20#if defined(TARGET_ARCH_IS_64_BIT)
22 using compiler::BlockBuilder;
24 CompilerState
S(thread,
true,
true);
26 FlowGraphBuilderHelper
H(1);
30 auto normal_entry =
H.flow_graph()->graph_entry()->normal_entry();
31 auto loop_header =
H.JoinEntry();
32 auto loop_body =
H.TargetEntry();
33 auto loop_exit =
H.TargetEntry();
40 BlockBuilder
builder(
H.flow_graph(), normal_entry);
41 v0 =
builder.AddParameter(0, kTagged);
42 builder.AddInstruction(
new GotoInstr(loop_header,
S.GetNextDeoptId()));
46 BlockBuilder
builder(
H.flow_graph(), loop_header);
47 loop_var =
H.Phi(loop_header, {{normal_entry, v0}, {loop_body, &add1}});
49 builder.AddBranch(
new RelationalOpInstr(
50 InstructionSource(), Token::kLT,
new Value(loop_var),
51 new Value(
H.IntConstant(50)), kMintCid,
53 loop_body, loop_exit);
57 BlockBuilder
builder(
H.flow_graph(), loop_body);
58 add1 =
builder.AddDefinition(
new BinaryInt64OpInstr(
59 Token::kADD,
new Value(loop_var),
new Value(
H.IntConstant(1)),
61 builder.AddInstruction(
new GotoInstr(loop_header,
S.GetNextDeoptId()));
65 BlockBuilder
builder(
H.flow_graph(), loop_exit);
71 FlowGraphTypePropagator::Propagate(
H.flow_graph());
72 H.flow_graph()->SelectRepresentations();
84 auto normal_entry =
H.flow_graph()->graph_entry()->normal_entry();
85 auto loop_header =
H.JoinEntry();
86 auto loop_body =
H.TargetEntry();
87 auto loop_exit =
H.TargetEntry();
89 ConstantInstr* sentinel =
H.flow_graph()->GetConstant(Object::sentinel());
97 builder.AddInstruction(
new GotoInstr(loop_header,
S.GetNextDeoptId()));
102 loop_var =
H.Phi(loop_header,
103 {{normal_entry,
H.IntConstant(0)}, {loop_body, &add1}});
104 builder.AddPhi(loop_var);
110 H.Phi(loop_header, {{normal_entry, sentinel}, {loop_body, &add1}});
111 builder.AddPhi(late_var);
114 new Value(
H.IntConstant(10)), kMintCid,
116 loop_body, loop_exit);
122 Token::kADD,
new Value(loop_var),
new Value(
H.IntConstant(1)),
124 builder.AddInstruction(
new GotoInstr(loop_header,
S.GetNextDeoptId()));
129 builder.AddReturn(
new Value(late_var));
134 FlowGraphTypePropagator::Propagate(
H.flow_graph());
135 H.flow_graph()->SelectRepresentations();
137#if defined(TARGET_ARCH_IS_64_BIT)
149 auto normal_entry =
H.flow_graph()->graph_entry()->normal_entry();
150 auto then_body =
H.TargetEntry();
151 auto else_body =
H.TargetEntry();
152 auto join_exit =
H.JoinEntry();
163 new Value(
H.IntConstant(1)),
164 false,
S.GetNextDeoptId()),
165 then_body, else_body);
171 new Value(
H.DoubleConstant(1)),
S.GetNextDeoptId(),
173 builder.AddInstruction(
new GotoInstr(join_exit,
S.GetNextDeoptId()));
179 new Value(
H.DoubleConstant(2)),
S.GetNextDeoptId(),
181 builder.AddInstruction(
new GotoInstr(join_exit,
S.GetNextDeoptId()));
191 builder.AddReturn(
new Value(phi));
195 FlowGraphTypePropagator::Propagate(
H.flow_graph());
196 H.flow_graph()->SelectRepresentations();
208 intptr_t num_locals = 2000;
209 printer.
Printf(
"import 'dart:typed_data';\n");
210 printer.
Printf(
"@pragma('vm:never-inline')\n");
211 printer.
Printf(
"%s one() { return %s; }\n",
type, one);
212 printer.
Printf(
"@pragma('vm:never-inline')\n");
213 printer.
Printf(
"%s largeFrame(int n) {\n",
type);
214 for (intptr_t i = 0; i < num_locals; i++) {
215 printer.
Printf(
" %s local%" Pd " = %s;\n",
type, i, zero);
217 printer.
Printf(
" for (int i = 0; i < n; i++) {\n");
218 for (intptr_t i = 0; i < num_locals; i++) {
219 printer.
Printf(
" local%" Pd " += one();\n", i);
222 printer.
Printf(
" %s sum = %s;\n",
type, zero);
223 for (intptr_t i = 0; i < num_locals; i++) {
224 printer.
Printf(
" sum += local%" Pd ";\n", i);
226 printer.
Printf(
" return sum;\n");
232 Invoke(root_library,
"main");
238 " for (var i = 0; i < 100; i++) {\n"
239 " var r = largeFrame(1);\n"
240 " if (r != 2000) throw r;\n"
249 " for (var i = 0; i < 100; i++) {\n"
250 " var r = largeFrame(1);\n"
251 " if (r != 2000.0) throw r;\n"
258 TestLargeFrame(
"Int32x4",
"Int32x4(0, 0, 0, 0)",
"Int32x4(1, 2, 3, 4)",
260 " for (var i = 0; i < 100; i++) {\n"
261 " var r = largeFrame(1);\n"
262 " if (r.x != 2000) throw r;\n"
263 " if (r.y != 4000) throw r;\n"
264 " if (r.z != 6000) throw r;\n"
265 " if (r.w != 8000) throw r;\n"
273 "Float32x4(1.0, 2.0, 3.0, 4.0)",
275 " for (var i = 0; i < 100; i++) {\n"
276 " var r = largeFrame(1);\n"
277 " if (r.x != 2000.0) throw r;\n"
278 " if (r.y != 4000.0) throw r;\n"
279 " if (r.z != 6000.0) throw r;\n"
280 " if (r.w != 8000.0) throw r;\n"
287 TestLargeFrame(
"Float64x2",
"Float64x2(0.0, 0.0)",
"Float64x2(1.0, 2.0)",
289 " for (var i = 0; i < 100; i++) {\n"
290 " var r = largeFrame(1);\n"
291 " if (r.x != 2000.0) throw r;\n"
292 " if (r.y != 4000.0) throw r;\n"
303 const char* kScript = R
"(
304 double foo(double sum, int n) {
305 if (sum == null) return 0.0;
306 for (int i = 0; i < n; i++) {
319 Invoke(root_library,
"main");
325 ILMatcher cursor(flow_graph, entry,
true,
329 kMatchAndMoveFunctionEntry,
333 kMatchAndMoveCheckSmi,
337 kMatchAndMoveJoinEntry,
338 kMatchAndMoveCheckStackOverflow,
339 kMatchAndMoveBranchTrue,
342 kMatchAndMoveTargetEntry,
343 kMatchAndMoveBinaryDoubleOp,
344 kMatchAndMoveBinarySmiOp,
348 kMatchAndMoveJoinEntry,
349 kMatchAndMoveCheckStackOverflow,
350 kMatchAndMoveBranchFalse,
353 kMatchAndMoveTargetEntry,
367 Invoke(root_library,
"main");
373 ILMatcher cursor(flow_graph, entry,
true,
377 kMatchAndMoveFunctionEntry,
381 kMatchAndMoveCheckSmi,
385 kMatchAndMoveJoinEntry,
386 kMatchAndMoveCheckStackOverflow,
387 kMatchAndMoveBranchTrue,
390 kMatchAndMoveTargetEntry,
392 kMatchAndMoveBinarySmiOp,
396 kMatchAndMoveJoinEntry,
397 kMatchAndMoveCheckStackOverflow,
398 kMatchAndMoveBranchFalse,
401 kMatchAndMoveTargetEntry,
408 const char* kScript = R
"(
409 import 'dart:typed_data';
410 Float32x4 foo(Float32x4 sum, int n) {
411 if (sum == null) return Float32x4(0.0, 0.0, 0.0, 0.0);
412 for (int i = 0; i < n; i++) {
413 sum += Float32x4(1.0, 2.0, 3.0, 4.0);
418 foo(Float32x4(0.0, 0.0, 0.0, 0.0), 10);
425 const char* kScript = R
"(
426 import 'dart:typed_data';
427 Float64x2 foo(Float64x2 sum, int n) {
428 if (sum == null) return Float64x2(0.0, 0.0);
429 for (int i = 0; i < n; i++) {
430 sum += Float64x2(1.0, 2.0);
435 foo(Float64x2(0.0, 0.0), 10);
442 const char* kScript = R
"(
443 import 'dart:typed_data';
444 Int32x4 foo(Int32x4 sum, int n) {
445 if (sum == null) return Int32x4(0, 0, 0, 0);
446 for (int i = 0; i < n; i++) {
447 sum += Int32x4(1, 2, 3, 4);
452 foo(Int32x4(0, 0, 0, 0), 10);
#define RELEASE_ASSERT(cond)
void AddString(const char *s)
intptr_t Printf(const char *format,...) PRINTF_ATTRIBUTE(2
static constexpr bool kCanBeSentinel
static constexpr bool kCannotBeNull
static CompileType FromAbstractType(const AbstractType &type, bool can_be_null, bool can_be_sentinel)
PRINT_OPERANDS_TO_SUPPORT PRINT_TO_SUPPORT bool UpdateType(CompileType new_type)
static bool SupportsUnboxedDoubles()
static bool SupportsUnboxedSimd128()
GraphEntryInstr * graph_entry() const
FunctionEntryInstr * normal_entry() const
bool TryMatch(std::initializer_list< MatchCode > match_codes, MatchOpCode insert_before=kInvalidMatchOpCode)
void SetInputAt(intptr_t i, Value *value)
static Object & ZoneHandle()
virtual Representation representation() const
FlowGraph * RunPasses(std::initializer_list< CompilerPass::Id > passes)
Dart_NativeFunction function
#define EXPECT_PROPERTY(entity, property)
LibraryPtr LoadTestScript(const char *script, Dart_NativeEntryResolver resolver, const char *lib_uri)
void TestLargeFrame(const char *type, const char *zero, const char *one, const char *main)
ObjectPtr Invoke(const Library &lib, const char *name)
FunctionPtr GetFunction(const Library &lib, const char *name)
static void TestPhiUnboxingHeuristicSimd(const char *script)
#define ISOLATE_UNIT_TEST_CASE(name)