138 bool use_same_buffer) {
139 OS::Print(
"==================================================\n");
140 OS::Print(
"RunMemoryCopyInstrTest src_start %" Pd " dest_start %" Pd
142 "%" Pd "%s elem_size %" Pd "\n",
143 src_start, dest_start,
length, unboxed_inputs ?
" (unboxed)" :
"",
145 OS::Print(
"==================================================\n");
149 uint8_t* ptr2 = use_same_buffer
154 OS::Print(
"&ptr %p &ptr2 %p\n", ptr, ptr2);
161 final pointer = Pointer<Uint8>.fromAddress(%s%p);
162 final pointer2 = Pointer<Uint8>.fromAddress(%s%p);
166 void callNonConstCopy() {
167 final pointer = Pointer<Uint8>.fromAddress(%s%p);
168 final pointer2 = Pointer<Uint8>.fromAddress(%s%p);
169 final src_start = %)" Pd R"(;
170 final dest_start = %)" Pd R"(;
171 final length = %)" Pd R"(;
173 pointer, pointer2, src_start, dest_start, length);
178 void copyNonConst(Pointer<Uint8> ptr1,
185 src_start, dest_start, length), std::free);
192 Invoke(root_library,
"copyConst");
196 const auto& const_copy =
201 CompilerPass::kComputeSSA,
212 {kMatchAndMoveStaticCall, &pointer},
213 {kMatchAndMoveStaticCall, &pointer2},
214 {kMatchAndMoveStaticCall, &another_function_call},
221 auto*
const src_start_constant_instr = flow_graph->GetConstant(
224 auto*
const dest_start_constant_instr = flow_graph->GetConstant(
227 auto*
const length_constant_instr = flow_graph->GetConstant(
232 cid,
new (zone)
Value(src_start_constant_instr),
233 new (zone)
Value(dest_start_constant_instr),
234 new (zone)
Value(length_constant_instr), unboxed_inputs,
236 flow_graph->InsertBefore(another_function_call, memory_copy_instr,
nullptr,
239 another_function_call->RemoveFromGraph();
243 ILMatcher cursor(flow_graph, flow_graph->graph_entry()->normal_entry());
246 kMatchAndMoveStaticCall,
247 kMatchAndMoveStaticCall,
248 kMatchAndMoveMemoryCopy,
253#if !defined(PRODUCT) && !defined(USING_THREAD_SANITIZER)
257 pipeline.RunForcedOptimizedAfterSSAPasses();
258 pipeline.CompileGraphAndAttachFunction();
263 ILMatcher cursor(flow_graph, flow_graph->graph_entry()->normal_entry());
267 {kMatchAndMoveMemoryCopy, &memory_copy},
269 EXPECT_EQ(kUntagged, memory_copy->src()->definition()->representation());
270 EXPECT_EQ(kUntagged, memory_copy->dest()->definition()->representation());
271 EXPECT(memory_copy->src_start()->BindsToConstant());
272 EXPECT(memory_copy->dest_start()->BindsToConstant());
273 EXPECT(memory_copy->length()->BindsToConstant());
277 Invoke(root_library,
"copyConst");
286 Invoke(root_library,
"callNonConstCopy");
290 const auto& copy_non_const =
291 Function::Handle(
GetFunction(root_library,
"copyNonConst"));
293 TestPipeline pipeline(copy_non_const, CompilerPass::kJIT);
294 FlowGraph* flow_graph = pipeline.RunPasses({
295 CompilerPass::kComputeSSA,
298 auto*
const entry_instr = flow_graph->graph_entry()->normal_entry();
299 auto*
const initial_defs = entry_instr->initial_definitions();
300 EXPECT(initial_defs !=
nullptr);
301 EXPECT_EQ(5, initial_defs->length());
303 auto*
const param_ptr = initial_defs->At(0)->AsParameter();
304 EXPECT(param_ptr !=
nullptr);
305 auto*
const param_ptr2 = initial_defs->At(1)->AsParameter();
306 EXPECT(param_ptr2 !=
nullptr);
307 auto*
const param_src_start = initial_defs->At(2)->AsParameter();
308 EXPECT(param_src_start !=
nullptr);
309 auto*
const param_dest_start = initial_defs->At(3)->AsParameter();
310 EXPECT(param_dest_start !=
nullptr);
311 auto*
const param_length = initial_defs->At(4)->AsParameter();
312 EXPECT(param_length !=
nullptr);
314 DartReturnInstr* return_instr;
316 ILMatcher cursor(flow_graph, entry_instr);
320 {kMatchDartReturn, &return_instr},
324 Zone*
const zone = Thread::Current()->zone();
326 Definition* src_start_def = param_src_start;
327 Definition* dest_start_def = param_dest_start;
328 Definition* length_def = param_length;
329 if (unboxed_inputs) {
333 UnboxInstr::Create(kUnboxedWord,
new (zone)
Value(param_length),
334 DeoptId::kNone, Instruction::kNotSpeculative);
335 flow_graph->InsertBefore(return_instr, length_def,
nullptr,
338 UnboxInstr::Create(kUnboxedWord,
new (zone)
Value(param_dest_start),
339 DeoptId::kNone, Instruction::kNotSpeculative);
340 flow_graph->InsertBefore(length_def, dest_start_def,
nullptr,
343 UnboxInstr::Create(kUnboxedWord,
new (zone)
Value(param_src_start),
344 DeoptId::kNone, Instruction::kNotSpeculative);
345 flow_graph->InsertBefore(dest_start_def, src_start_def,
nullptr,
349 auto*
const memory_copy_instr =
new (zone) MemoryCopyInstr(
352 new (zone)
Value(src_start_def),
new (zone)
Value(dest_start_def),
353 new (zone)
Value(length_def),
355 unboxed_inputs, use_same_buffer);
356 flow_graph->InsertBefore(return_instr, memory_copy_instr,
nullptr,
361 ILMatcher cursor(flow_graph, flow_graph->graph_entry()->normal_entry());
362 if (unboxed_inputs) {
368 kMatchAndMoveMemoryCopy,
374 kMatchAndMoveMemoryCopy,
381#if !defined(PRODUCT) && !defined(USING_THREAD_SANITIZER)
382 SetFlagScope<bool> sfs(&FLAG_disassemble_optimized,
true);
385 pipeline.RunForcedOptimizedAfterSSAPasses();
386 pipeline.CompileGraphAndAttachFunction();
391 ILMatcher cursor(flow_graph, flow_graph->graph_entry()->normal_entry());
392 MemoryCopyInstr* memory_copy;
395 {kMatchAndMoveMemoryCopy, &memory_copy},
397 EXPECT_EQ(kUntagged, memory_copy->src()->definition()->representation());
398 EXPECT_EQ(kUntagged, memory_copy->dest()->definition()->representation());
399 EXPECT(!memory_copy->src_start()->BindsToConstant());
400 EXPECT(!memory_copy->dest_start()->BindsToConstant());
401 EXPECT(!memory_copy->length()->BindsToConstant());
405 Invoke(root_library,
"callNonConstCopy");
410 if (!use_same_buffer) {