diff options
21 files changed, 1318 insertions, 2530 deletions
diff --git a/compiler/optimizing/bounds_check_elimination_test.cc b/compiler/optimizing/bounds_check_elimination_test.cc index 929a9e7fe7..5ddd25335b 100644 --- a/compiler/optimizing/bounds_check_elimination_test.cc +++ b/compiler/optimizing/bounds_check_elimination_test.cc @@ -57,6 +57,11 @@ class BoundsCheckEliminationTest : public OptimizingUnitTest { BoundsCheckElimination(graph_, side_effects, &induction).Run(); } + HInstruction* BuildSSAGraph1(int initial, int increment, IfCondition cond = kCondGE); + HInstruction* BuildSSAGraph2(int initial, int increment = -1, IfCondition cond = kCondLE); + HInstruction* BuildSSAGraph3(int initial, int increment, IfCondition cond); + HInstruction* BuildSSAGraph4(int initial, IfCondition cond = kCondGE); + HGraph* graph_; }; @@ -68,80 +73,52 @@ TEST_F(BoundsCheckEliminationTest, NarrowingRangeArrayBoundsElimination) { HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(entry); graph_->SetEntryBlock(entry); - HInstruction* parameter1 = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); // array - HInstruction* parameter2 = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kInt32); // i - entry->AddInstruction(parameter1); - entry->AddInstruction(parameter2); + HInstruction* parameter1 = MakeParam(DataType::Type::kReference); // array + HInstruction* parameter2 = MakeParam(DataType::Type::kInt32); // i HInstruction* constant_1 = graph_->GetIntConstant(1); HInstruction* constant_0 = graph_->GetIntConstant(0); HBasicBlock* block1 = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(block1); - HInstruction* cmp = new (GetAllocator()) HGreaterThanOrEqual(parameter2, constant_0); - HIf* if_inst = new (GetAllocator()) HIf(cmp); - block1->AddInstruction(cmp); - block1->AddInstruction(if_inst); + HInstruction* cmp = MakeCondition<HGreaterThanOrEqual>(block1, parameter2, constant_0); + MakeIf(block1, cmp); entry->AddSuccessor(block1); HBasicBlock* block2 = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(block2); - HNullCheck* null_check = new (GetAllocator()) HNullCheck(parameter1, 0); - HArrayLength* array_length = new (GetAllocator()) HArrayLength(null_check, 0); - HBoundsCheck* bounds_check2 = new (GetAllocator()) - HBoundsCheck(parameter2, array_length, 0); - HArraySet* array_set = new (GetAllocator()) HArraySet( - null_check, bounds_check2, constant_1, DataType::Type::kInt32, 0); - block2->AddInstruction(null_check); - block2->AddInstruction(array_length); - block2->AddInstruction(bounds_check2); - block2->AddInstruction(array_set); + HNullCheck* null_check = MakeNullCheck(block2, parameter1); + HArrayLength* array_length = MakeArrayLength(block2, null_check); + HBoundsCheck* bounds_check2 = MakeBoundsCheck(block2, parameter2, array_length); + MakeArraySet(block2, null_check, bounds_check2, constant_1, DataType::Type::kInt32); HBasicBlock* block3 = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(block3); - null_check = new (GetAllocator()) HNullCheck(parameter1, 0); - array_length = new (GetAllocator()) HArrayLength(null_check, 0); - cmp = new (GetAllocator()) HLessThan(parameter2, array_length); - if_inst = new (GetAllocator()) HIf(cmp); - block3->AddInstruction(null_check); - block3->AddInstruction(array_length); - block3->AddInstruction(cmp); - block3->AddInstruction(if_inst); + null_check = MakeNullCheck(block3, parameter1); + array_length = MakeArrayLength(block3, null_check); + cmp = MakeCondition<HLessThan>(block3, parameter2, array_length); + MakeIf(block3, cmp); HBasicBlock* block4 = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(block4); - null_check = new (GetAllocator()) HNullCheck(parameter1, 0); - array_length = new (GetAllocator()) HArrayLength(null_check, 0); - HBoundsCheck* bounds_check4 = new (GetAllocator()) - HBoundsCheck(parameter2, array_length, 0); - array_set = new (GetAllocator()) HArraySet( - null_check, bounds_check4, constant_1, DataType::Type::kInt32, 0); - block4->AddInstruction(null_check); - block4->AddInstruction(array_length); - block4->AddInstruction(bounds_check4); - block4->AddInstruction(array_set); + null_check = MakeNullCheck(block4, parameter1); + array_length = MakeArrayLength(block4, null_check); + HBoundsCheck* bounds_check4 = MakeBoundsCheck(block4, parameter2, array_length); + MakeArraySet(block4, null_check, bounds_check4, constant_1, DataType::Type::kInt32); HBasicBlock* block5 = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(block5); - null_check = new (GetAllocator()) HNullCheck(parameter1, 0); - array_length = new (GetAllocator()) HArrayLength(null_check, 0); - HBoundsCheck* bounds_check5 = new (GetAllocator()) - HBoundsCheck(parameter2, array_length, 0); - array_set = new (GetAllocator()) HArraySet( - null_check, bounds_check5, constant_1, DataType::Type::kInt32, 0); - block5->AddInstruction(null_check); - block5->AddInstruction(array_length); - block5->AddInstruction(bounds_check5); - block5->AddInstruction(array_set); + null_check = MakeNullCheck(block5, parameter1); + array_length = MakeArrayLength(block5, null_check); + HBoundsCheck* bounds_check5 = MakeBoundsCheck(block5, parameter2, array_length); + MakeArraySet(block5, null_check, bounds_check5, constant_1, DataType::Type::kInt32); HBasicBlock* exit = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(exit); block2->AddSuccessor(exit); block4->AddSuccessor(exit); block5->AddSuccessor(exit); - exit->AddInstruction(new (GetAllocator()) HExit()); + MakeExit(exit); block1->AddSuccessor(block3); // True successor block1->AddSuccessor(block2); // False successor @@ -165,12 +142,8 @@ TEST_F(BoundsCheckEliminationTest, OverflowArrayBoundsElimination) { HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(entry); graph_->SetEntryBlock(entry); - HInstruction* parameter1 = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); // array - HInstruction* parameter2 = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kInt32); // i - entry->AddInstruction(parameter1); - entry->AddInstruction(parameter2); + HInstruction* parameter1 = MakeParam(DataType::Type::kReference); // array + HInstruction* parameter2 = MakeParam(DataType::Type::kInt32); // i HInstruction* constant_1 = graph_->GetIntConstant(1); HInstruction* constant_0 = graph_->GetIntConstant(0); @@ -178,38 +151,26 @@ TEST_F(BoundsCheckEliminationTest, OverflowArrayBoundsElimination) { HBasicBlock* block1 = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(block1); - HInstruction* cmp = new (GetAllocator()) HLessThanOrEqual(parameter2, constant_0); - HIf* if_inst = new (GetAllocator()) HIf(cmp); - block1->AddInstruction(cmp); - block1->AddInstruction(if_inst); + HInstruction* cmp = MakeCondition<HLessThanOrEqual>(block1, parameter2, constant_0); + MakeIf(block1, cmp); entry->AddSuccessor(block1); HBasicBlock* block2 = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(block2); - HInstruction* add = - new (GetAllocator()) HAdd(DataType::Type::kInt32, parameter2, constant_max_int); - HNullCheck* null_check = new (GetAllocator()) HNullCheck(parameter1, 0); - HArrayLength* array_length = new (GetAllocator()) HArrayLength(null_check, 0); - HInstruction* cmp2 = new (GetAllocator()) HGreaterThanOrEqual(add, array_length); - if_inst = new (GetAllocator()) HIf(cmp2); - block2->AddInstruction(add); - block2->AddInstruction(null_check); - block2->AddInstruction(array_length); - block2->AddInstruction(cmp2); - block2->AddInstruction(if_inst); + HInstruction* add = MakeBinOp<HAdd>(block2, DataType::Type::kInt32, parameter2, constant_max_int); + HNullCheck* null_check = MakeNullCheck(block2, parameter1); + HArrayLength* array_length = MakeArrayLength(block2, null_check); + HInstruction* cmp2 = MakeCondition<HGreaterThanOrEqual>(block2, add, array_length); + MakeIf(block2, cmp2); HBasicBlock* block3 = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(block3); - HBoundsCheck* bounds_check = new (GetAllocator()) - HBoundsCheck(add, array_length, 0); - HArraySet* array_set = new (GetAllocator()) HArraySet( - null_check, bounds_check, constant_1, DataType::Type::kInt32, 0); - block3->AddInstruction(bounds_check); - block3->AddInstruction(array_set); + HBoundsCheck* bounds_check = MakeBoundsCheck(block3, add, array_length); + MakeArraySet(block3, null_check, bounds_check, constant_1, DataType::Type::kInt32); HBasicBlock* exit = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(exit); - exit->AddInstruction(new (GetAllocator()) HExit()); + MakeExit(exit); block1->AddSuccessor(exit); // true successor block1->AddSuccessor(block2); // false successor block2->AddSuccessor(exit); // true successor @@ -230,12 +191,8 @@ TEST_F(BoundsCheckEliminationTest, UnderflowArrayBoundsElimination) { HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(entry); graph_->SetEntryBlock(entry); - HInstruction* parameter1 = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); // array - HInstruction* parameter2 = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kInt32); // i - entry->AddInstruction(parameter1); - entry->AddInstruction(parameter2); + HInstruction* parameter1 = MakeParam(DataType::Type::kReference); // array + HInstruction* parameter2 = MakeParam(DataType::Type::kInt32); // i HInstruction* constant_1 = graph_->GetIntConstant(1); HInstruction* constant_0 = graph_->GetIntConstant(0); @@ -243,40 +200,28 @@ TEST_F(BoundsCheckEliminationTest, UnderflowArrayBoundsElimination) { HBasicBlock* block1 = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(block1); - HNullCheck* null_check = new (GetAllocator()) HNullCheck(parameter1, 0); - HArrayLength* array_length = new (GetAllocator()) HArrayLength(null_check, 0); - HInstruction* cmp = new (GetAllocator()) HGreaterThanOrEqual(parameter2, array_length); - HIf* if_inst = new (GetAllocator()) HIf(cmp); - block1->AddInstruction(null_check); - block1->AddInstruction(array_length); - block1->AddInstruction(cmp); - block1->AddInstruction(if_inst); + HNullCheck* null_check = MakeNullCheck(block1, parameter1); + HArrayLength* array_length = MakeArrayLength(block1, null_check); + HInstruction* cmp = MakeCondition<HGreaterThanOrEqual>(block1, parameter2, array_length); + MakeIf(block1, cmp); entry->AddSuccessor(block1); HBasicBlock* block2 = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(block2); HInstruction* sub1 = - new (GetAllocator()) HSub(DataType::Type::kInt32, parameter2, constant_max_int); - HInstruction* sub2 = new (GetAllocator()) HSub(DataType::Type::kInt32, sub1, constant_max_int); - HInstruction* cmp2 = new (GetAllocator()) HLessThanOrEqual(sub2, constant_0); - if_inst = new (GetAllocator()) HIf(cmp2); - block2->AddInstruction(sub1); - block2->AddInstruction(sub2); - block2->AddInstruction(cmp2); - block2->AddInstruction(if_inst); + MakeBinOp<HSub>(block2, DataType::Type::kInt32, parameter2, constant_max_int); + HInstruction* sub2 = MakeBinOp<HSub>(block2, DataType::Type::kInt32, sub1, constant_max_int); + HInstruction* cmp2 = MakeCondition<HLessThanOrEqual>(block2, sub2, constant_0); + MakeIf(block2, cmp2); HBasicBlock* block3 = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(block3); - HBoundsCheck* bounds_check = new (GetAllocator()) - HBoundsCheck(sub2, array_length, 0); - HArraySet* array_set = new (GetAllocator()) HArraySet( - null_check, bounds_check, constant_1, DataType::Type::kInt32, 0); - block3->AddInstruction(bounds_check); - block3->AddInstruction(array_set); + HBoundsCheck* bounds_check = MakeBoundsCheck(block3, sub2, array_length); + MakeArraySet(block3, null_check, bounds_check, constant_1, DataType::Type::kInt32); HBasicBlock* exit = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(exit); - exit->AddInstruction(new (GetAllocator()) HExit()); + MakeExit(exit); block1->AddSuccessor(exit); // true successor block1->AddSuccessor(block2); // false successor block2->AddSuccessor(exit); // true successor @@ -295,9 +240,7 @@ TEST_F(BoundsCheckEliminationTest, ConstantArrayBoundsElimination) { HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(entry); graph_->SetEntryBlock(entry); - HInstruction* parameter = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); - entry->AddInstruction(parameter); + HInstruction* parameter = MakeParam(DataType::Type::kReference); HInstruction* constant_5 = graph_->GetIntConstant(5); HInstruction* constant_4 = graph_->GetIntConstant(4); @@ -308,45 +251,27 @@ TEST_F(BoundsCheckEliminationTest, ConstantArrayBoundsElimination) { graph_->AddBlock(block); entry->AddSuccessor(block); - HNullCheck* null_check = new (GetAllocator()) HNullCheck(parameter, 0); - HArrayLength* array_length = new (GetAllocator()) HArrayLength(null_check, 0); - HBoundsCheck* bounds_check6 = new (GetAllocator()) - HBoundsCheck(constant_6, array_length, 0); - HInstruction* array_set = new (GetAllocator()) HArraySet( - null_check, bounds_check6, constant_1, DataType::Type::kInt32, 0); - block->AddInstruction(null_check); - block->AddInstruction(array_length); - block->AddInstruction(bounds_check6); - block->AddInstruction(array_set); - - null_check = new (GetAllocator()) HNullCheck(parameter, 0); - array_length = new (GetAllocator()) HArrayLength(null_check, 0); - HBoundsCheck* bounds_check5 = new (GetAllocator()) - HBoundsCheck(constant_5, array_length, 0); - array_set = new (GetAllocator()) HArraySet( - null_check, bounds_check5, constant_1, DataType::Type::kInt32, 0); - block->AddInstruction(null_check); - block->AddInstruction(array_length); - block->AddInstruction(bounds_check5); - block->AddInstruction(array_set); - - null_check = new (GetAllocator()) HNullCheck(parameter, 0); - array_length = new (GetAllocator()) HArrayLength(null_check, 0); - HBoundsCheck* bounds_check4 = new (GetAllocator()) - HBoundsCheck(constant_4, array_length, 0); - array_set = new (GetAllocator()) HArraySet( - null_check, bounds_check4, constant_1, DataType::Type::kInt32, 0); - block->AddInstruction(null_check); - block->AddInstruction(array_length); - block->AddInstruction(bounds_check4); - block->AddInstruction(array_set); - - block->AddInstruction(new (GetAllocator()) HGoto()); + HNullCheck* null_check = MakeNullCheck(block, parameter); + HArrayLength* array_length = MakeArrayLength(block, null_check); + HBoundsCheck* bounds_check6 = MakeBoundsCheck(block, constant_6, array_length); + MakeArraySet(block, null_check, bounds_check6, constant_1, DataType::Type::kInt32); + + null_check = MakeNullCheck(block, parameter); + array_length = MakeArrayLength(block, null_check); + HBoundsCheck* bounds_check5 = MakeBoundsCheck(block, constant_5, array_length); + MakeArraySet(block, null_check, bounds_check5, constant_1, DataType::Type::kInt32); + + null_check = MakeNullCheck(block, parameter); + array_length = MakeArrayLength(block, null_check); + HBoundsCheck* bounds_check4 = MakeBoundsCheck(block, constant_4, array_length); + MakeArraySet(block, null_check, bounds_check4, constant_1, DataType::Type::kInt32); + + MakeGoto(block); HBasicBlock* exit = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(exit); block->AddSuccessor(exit); - exit->AddInstruction(new (GetAllocator()) HExit()); + MakeExit(exit); RunBCE(); @@ -356,101 +281,85 @@ TEST_F(BoundsCheckEliminationTest, ConstantArrayBoundsElimination) { } // for (int i=initial; i<array.length; i+=increment) { array[i] = 10; } -static HInstruction* BuildSSAGraph1(HGraph* graph, - ArenaAllocator* allocator, - int initial, - int increment, - IfCondition cond = kCondGE) { - HBasicBlock* entry = new (allocator) HBasicBlock(graph); - graph->AddBlock(entry); - graph->SetEntryBlock(entry); - HInstruction* parameter = new (allocator) HParameterValue( - graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); - entry->AddInstruction(parameter); - - HInstruction* constant_initial = graph->GetIntConstant(initial); - HInstruction* constant_increment = graph->GetIntConstant(increment); - HInstruction* constant_10 = graph->GetIntConstant(10); - - HBasicBlock* block = new (allocator) HBasicBlock(graph); - graph->AddBlock(block); +HInstruction* BoundsCheckEliminationTest::BuildSSAGraph1(int initial, + int increment, + IfCondition cond) { + HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph_); + graph_->AddBlock(entry); + graph_->SetEntryBlock(entry); + HInstruction* parameter = MakeParam(DataType::Type::kReference); + + HInstruction* constant_initial = graph_->GetIntConstant(initial); + HInstruction* constant_increment = graph_->GetIntConstant(increment); + HInstruction* constant_10 = graph_->GetIntConstant(10); + + HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph_); + graph_->AddBlock(block); entry->AddSuccessor(block); - block->AddInstruction(new (allocator) HGoto()); + MakeGoto(block); - HBasicBlock* loop_header = new (allocator) HBasicBlock(graph); - HBasicBlock* loop_body = new (allocator) HBasicBlock(graph); - HBasicBlock* exit = new (allocator) HBasicBlock(graph); + HBasicBlock* loop_header = new (GetAllocator()) HBasicBlock(graph_); + HBasicBlock* loop_body = new (GetAllocator()) HBasicBlock(graph_); + HBasicBlock* exit = new (GetAllocator()) HBasicBlock(graph_); - graph->AddBlock(loop_header); - graph->AddBlock(loop_body); - graph->AddBlock(exit); + graph_->AddBlock(loop_header); + graph_->AddBlock(loop_body); + graph_->AddBlock(exit); block->AddSuccessor(loop_header); loop_header->AddSuccessor(exit); // true successor loop_header->AddSuccessor(loop_body); // false successor loop_body->AddSuccessor(loop_header); - HPhi* phi = new (allocator) HPhi(allocator, 0, 0, DataType::Type::kInt32); - HInstruction* null_check = new (allocator) HNullCheck(parameter, 0); - HInstruction* array_length = new (allocator) HArrayLength(null_check, 0); + HPhi* phi = MakePhi(loop_header, {constant_initial, /* placeholder */ constant_initial}); + HInstruction* null_check = MakeNullCheck(loop_header, parameter); + HInstruction* array_length = MakeArrayLength(loop_header, null_check); HInstruction* cmp = nullptr; if (cond == kCondGE) { - cmp = new (allocator) HGreaterThanOrEqual(phi, array_length); + cmp = MakeCondition<HGreaterThanOrEqual>(loop_header, phi, array_length); } else { DCHECK(cond == kCondGT); - cmp = new (allocator) HGreaterThan(phi, array_length); + cmp = MakeCondition<HGreaterThan>(loop_header, phi, array_length); } - HInstruction* if_inst = new (allocator) HIf(cmp); - loop_header->AddPhi(phi); - loop_header->AddInstruction(null_check); - loop_header->AddInstruction(array_length); - loop_header->AddInstruction(cmp); - loop_header->AddInstruction(if_inst); - phi->AddInput(constant_initial); - - null_check = new (allocator) HNullCheck(parameter, 0); - array_length = new (allocator) HArrayLength(null_check, 0); - HInstruction* bounds_check = new (allocator) HBoundsCheck(phi, array_length, 0); - HInstruction* array_set = new (allocator) HArraySet( - null_check, bounds_check, constant_10, DataType::Type::kInt32, 0); - - HInstruction* add = new (allocator) HAdd(DataType::Type::kInt32, phi, constant_increment); - loop_body->AddInstruction(null_check); - loop_body->AddInstruction(array_length); - loop_body->AddInstruction(bounds_check); - loop_body->AddInstruction(array_set); - loop_body->AddInstruction(add); - loop_body->AddInstruction(new (allocator) HGoto()); - phi->AddInput(add); - - exit->AddInstruction(new (allocator) HExit()); + MakeIf(loop_header, cmp); + + null_check = MakeNullCheck(loop_body, parameter); + array_length = MakeArrayLength(loop_body, null_check); + HInstruction* bounds_check = MakeBoundsCheck(loop_body, phi, array_length); + MakeArraySet(loop_body, null_check, bounds_check, constant_10, DataType::Type::kInt32); + HInstruction* add = MakeBinOp<HAdd>(loop_body, DataType::Type::kInt32, phi, constant_increment); + MakeGoto(loop_body); + + phi->ReplaceInput(add, 1u); // Update back-edge input. + + MakeExit(exit); return bounds_check; } TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination1a) { // for (int i=0; i<array.length; i++) { array[i] = 10; // Can eliminate with gvn. } - HInstruction* bounds_check = BuildSSAGraph1(graph_, GetAllocator(), 0, 1); + HInstruction* bounds_check = BuildSSAGraph1(0, 1); RunBCE(); ASSERT_TRUE(IsRemoved(bounds_check)); } TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination1b) { // for (int i=1; i<array.length; i++) { array[i] = 10; // Can eliminate. } - HInstruction* bounds_check = BuildSSAGraph1(graph_, GetAllocator(), 1, 1); + HInstruction* bounds_check = BuildSSAGraph1(1, 1); RunBCE(); ASSERT_TRUE(IsRemoved(bounds_check)); } TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination1c) { // for (int i=-1; i<array.length; i++) { array[i] = 10; // Can't eliminate. } - HInstruction* bounds_check = BuildSSAGraph1(graph_, GetAllocator(), -1, 1); + HInstruction* bounds_check = BuildSSAGraph1(-1, 1); RunBCE(); ASSERT_FALSE(IsRemoved(bounds_check)); } TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination1d) { // for (int i=0; i<=array.length; i++) { array[i] = 10; // Can't eliminate. } - HInstruction* bounds_check = BuildSSAGraph1(graph_, GetAllocator(), 0, 1, kCondGT); + HInstruction* bounds_check = BuildSSAGraph1(0, 1, kCondGT); RunBCE(); ASSERT_FALSE(IsRemoved(bounds_check)); } @@ -458,195 +367,163 @@ TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination1d) { TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination1e) { // for (int i=0; i<array.length; i += 2) { // array[i] = 10; // Can't eliminate due to overflow concern. } - HInstruction* bounds_check = BuildSSAGraph1(graph_, GetAllocator(), 0, 2); + HInstruction* bounds_check = BuildSSAGraph1(0, 2); RunBCE(); ASSERT_FALSE(IsRemoved(bounds_check)); } TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination1f) { // for (int i=1; i<array.length; i += 2) { array[i] = 10; // Can eliminate. } - HInstruction* bounds_check = BuildSSAGraph1(graph_, GetAllocator(), 1, 2); + HInstruction* bounds_check = BuildSSAGraph1(1, 2); RunBCE(); ASSERT_TRUE(IsRemoved(bounds_check)); } // for (int i=array.length; i>0; i+=increment) { array[i-1] = 10; } -static HInstruction* BuildSSAGraph2(HGraph *graph, - ArenaAllocator* allocator, - int initial, - int increment = -1, - IfCondition cond = kCondLE) { - HBasicBlock* entry = new (allocator) HBasicBlock(graph); - graph->AddBlock(entry); - graph->SetEntryBlock(entry); - HInstruction* parameter = new (allocator) HParameterValue( - graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); - entry->AddInstruction(parameter); - - HInstruction* constant_initial = graph->GetIntConstant(initial); - HInstruction* constant_increment = graph->GetIntConstant(increment); - HInstruction* constant_minus_1 = graph->GetIntConstant(-1); - HInstruction* constant_10 = graph->GetIntConstant(10); - - HBasicBlock* block = new (allocator) HBasicBlock(graph); - graph->AddBlock(block); +HInstruction* BoundsCheckEliminationTest::BuildSSAGraph2(int initial, + int increment, + IfCondition cond) { + HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph_); + graph_->AddBlock(entry); + graph_->SetEntryBlock(entry); + HInstruction* parameter = MakeParam(DataType::Type::kReference); + + HInstruction* constant_initial = graph_->GetIntConstant(initial); + HInstruction* constant_increment = graph_->GetIntConstant(increment); + HInstruction* constant_minus_1 = graph_->GetIntConstant(-1); + HInstruction* constant_10 = graph_->GetIntConstant(10); + + HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph_); + graph_->AddBlock(block); entry->AddSuccessor(block); - HInstruction* null_check = new (allocator) HNullCheck(parameter, 0); - HInstruction* array_length = new (allocator) HArrayLength(null_check, 0); - block->AddInstruction(null_check); - block->AddInstruction(array_length); - block->AddInstruction(new (allocator) HGoto()); - - HBasicBlock* loop_header = new (allocator) HBasicBlock(graph); - HBasicBlock* loop_body = new (allocator) HBasicBlock(graph); - HBasicBlock* exit = new (allocator) HBasicBlock(graph); - - graph->AddBlock(loop_header); - graph->AddBlock(loop_body); - graph->AddBlock(exit); + HInstruction* null_check = MakeNullCheck(block, parameter); + HInstruction* array_length = MakeArrayLength(block, null_check); + MakeGoto(block); + + HBasicBlock* loop_header = new (GetAllocator()) HBasicBlock(graph_); + HBasicBlock* loop_body = new (GetAllocator()) HBasicBlock(graph_); + HBasicBlock* exit = new (GetAllocator()) HBasicBlock(graph_); + + graph_->AddBlock(loop_header); + graph_->AddBlock(loop_body); + graph_->AddBlock(exit); block->AddSuccessor(loop_header); loop_header->AddSuccessor(exit); // true successor loop_header->AddSuccessor(loop_body); // false successor loop_body->AddSuccessor(loop_header); - HPhi* phi = new (allocator) HPhi(allocator, 0, 0, DataType::Type::kInt32); + HPhi* phi = MakePhi(loop_header, {array_length, /* placeholder */ array_length}); HInstruction* cmp = nullptr; if (cond == kCondLE) { - cmp = new (allocator) HLessThanOrEqual(phi, constant_initial); + cmp = MakeCondition<HLessThanOrEqual>(loop_header, phi, constant_initial); } else { DCHECK(cond == kCondLT); - cmp = new (allocator) HLessThan(phi, constant_initial); + cmp = MakeCondition<HLessThan>(loop_header, phi, constant_initial); } - HInstruction* if_inst = new (allocator) HIf(cmp); - loop_header->AddPhi(phi); - loop_header->AddInstruction(cmp); - loop_header->AddInstruction(if_inst); - phi->AddInput(array_length); - - HInstruction* add = new (allocator) HAdd(DataType::Type::kInt32, phi, constant_minus_1); - null_check = new (allocator) HNullCheck(parameter, 0); - array_length = new (allocator) HArrayLength(null_check, 0); - HInstruction* bounds_check = new (allocator) HBoundsCheck(add, array_length, 0); - HInstruction* array_set = new (allocator) HArraySet( - null_check, bounds_check, constant_10, DataType::Type::kInt32, 0); - HInstruction* add_phi = new (allocator) HAdd(DataType::Type::kInt32, phi, constant_increment); - loop_body->AddInstruction(add); - loop_body->AddInstruction(null_check); - loop_body->AddInstruction(array_length); - loop_body->AddInstruction(bounds_check); - loop_body->AddInstruction(array_set); - loop_body->AddInstruction(add_phi); - loop_body->AddInstruction(new (allocator) HGoto()); - phi->AddInput(add); - - exit->AddInstruction(new (allocator) HExit()); + MakeIf(loop_header, cmp); + + HInstruction* add = MakeBinOp<HAdd>(loop_body, DataType::Type::kInt32, phi, constant_minus_1); + null_check = MakeNullCheck(loop_body, parameter); + array_length = MakeArrayLength(loop_body, null_check); + HInstruction* bounds_check = MakeBoundsCheck(loop_body, add, array_length); + MakeArraySet(loop_body, null_check, bounds_check, constant_10, DataType::Type::kInt32); + MakeBinOp<HAdd>(loop_body, DataType::Type::kInt32, phi, constant_increment); + MakeGoto(loop_body); + + phi->ReplaceInput(add, 1u); // Update back-edge input. + + MakeExit(exit); return bounds_check; } TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination2a) { // for (int i=array.length; i>0; i--) { array[i-1] = 10; // Can eliminate with gvn. } - HInstruction* bounds_check = BuildSSAGraph2(graph_, GetAllocator(), 0); + HInstruction* bounds_check = BuildSSAGraph2(0); RunBCE(); ASSERT_TRUE(IsRemoved(bounds_check)); } TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination2b) { // for (int i=array.length; i>1; i--) { array[i-1] = 10; // Can eliminate. } - HInstruction* bounds_check = BuildSSAGraph2(graph_, GetAllocator(), 1); + HInstruction* bounds_check = BuildSSAGraph2(1); RunBCE(); ASSERT_TRUE(IsRemoved(bounds_check)); } TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination2c) { // for (int i=array.length; i>-1; i--) { array[i-1] = 10; // Can't eliminate. } - HInstruction* bounds_check = BuildSSAGraph2(graph_, GetAllocator(), -1); + HInstruction* bounds_check = BuildSSAGraph2(-1); RunBCE(); ASSERT_FALSE(IsRemoved(bounds_check)); } TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination2d) { // for (int i=array.length; i>=0; i--) { array[i-1] = 10; // Can't eliminate. } - HInstruction* bounds_check = BuildSSAGraph2(graph_, GetAllocator(), 0, -1, kCondLT); + HInstruction* bounds_check = BuildSSAGraph2(0, -1, kCondLT); RunBCE(); ASSERT_FALSE(IsRemoved(bounds_check)); } TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination2e) { // for (int i=array.length; i>0; i-=2) { array[i-1] = 10; // Can eliminate. } - HInstruction* bounds_check = BuildSSAGraph2(graph_, GetAllocator(), 0, -2); + HInstruction* bounds_check = BuildSSAGraph2(0, -2); RunBCE(); ASSERT_TRUE(IsRemoved(bounds_check)); } // int[] array = new int[10]; // for (int i=0; i<10; i+=increment) { array[i] = 10; } -static HInstruction* BuildSSAGraph3(HGraph* graph, - ArenaAllocator* allocator, - int initial, - int increment, - IfCondition cond) { - HBasicBlock* entry = new (allocator) HBasicBlock(graph); - graph->AddBlock(entry); - graph->SetEntryBlock(entry); - - HInstruction* constant_10 = graph->GetIntConstant(10); - HInstruction* constant_initial = graph->GetIntConstant(initial); - HInstruction* constant_increment = graph->GetIntConstant(increment); - - HBasicBlock* block = new (allocator) HBasicBlock(graph); - graph->AddBlock(block); +HInstruction* BoundsCheckEliminationTest::BuildSSAGraph3(int initial, + int increment, + IfCondition cond) { + HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph_); + graph_->AddBlock(entry); + graph_->SetEntryBlock(entry); + + HInstruction* constant_10 = graph_->GetIntConstant(10); + HInstruction* constant_initial = graph_->GetIntConstant(initial); + HInstruction* constant_increment = graph_->GetIntConstant(increment); + + HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph_); + graph_->AddBlock(block); entry->AddSuccessor(block); // We pass a bogus constant for the class to avoid mocking one. - HInstruction* new_array = new (allocator) HNewArray( - /* cls= */ constant_10, - /* length= */ constant_10, - /* dex_pc= */ 0, - /* component_size_shift= */ 0); - block->AddInstruction(new_array); - block->AddInstruction(new (allocator) HGoto()); - - HBasicBlock* loop_header = new (allocator) HBasicBlock(graph); - HBasicBlock* loop_body = new (allocator) HBasicBlock(graph); - HBasicBlock* exit = new (allocator) HBasicBlock(graph); - - graph->AddBlock(loop_header); - graph->AddBlock(loop_body); - graph->AddBlock(exit); + HInstruction* new_array = MakeNewArray(block, /* cls= */ constant_10, /* length= */ constant_10); + MakeGoto(block); + + HBasicBlock* loop_header = new (GetAllocator()) HBasicBlock(graph_); + HBasicBlock* loop_body = new (GetAllocator()) HBasicBlock(graph_); + HBasicBlock* exit = new (GetAllocator()) HBasicBlock(graph_); + + graph_->AddBlock(loop_header); + graph_->AddBlock(loop_body); + graph_->AddBlock(exit); block->AddSuccessor(loop_header); loop_header->AddSuccessor(exit); // true successor loop_header->AddSuccessor(loop_body); // false successor loop_body->AddSuccessor(loop_header); - HPhi* phi = new (allocator) HPhi(allocator, 0, 0, DataType::Type::kInt32); + HPhi* phi = MakePhi(loop_header, {constant_initial, /* placeholder */ constant_initial}); HInstruction* cmp = nullptr; if (cond == kCondGE) { - cmp = new (allocator) HGreaterThanOrEqual(phi, constant_10); + cmp = MakeCondition<HGreaterThanOrEqual>(loop_header, phi, constant_10); } else { DCHECK(cond == kCondGT); - cmp = new (allocator) HGreaterThan(phi, constant_10); + cmp = MakeCondition<HGreaterThan>(loop_header, phi, constant_10); } - HInstruction* if_inst = new (allocator) HIf(cmp); - loop_header->AddPhi(phi); - loop_header->AddInstruction(cmp); - loop_header->AddInstruction(if_inst); - phi->AddInput(constant_initial); - - HNullCheck* null_check = new (allocator) HNullCheck(new_array, 0); - HArrayLength* array_length = new (allocator) HArrayLength(null_check, 0); - HInstruction* bounds_check = new (allocator) HBoundsCheck(phi, array_length, 0); - HInstruction* array_set = new (allocator) HArraySet( - null_check, bounds_check, constant_10, DataType::Type::kInt32, 0); - HInstruction* add = new (allocator) HAdd(DataType::Type::kInt32, phi, constant_increment); - loop_body->AddInstruction(null_check); - loop_body->AddInstruction(array_length); - loop_body->AddInstruction(bounds_check); - loop_body->AddInstruction(array_set); - loop_body->AddInstruction(add); - loop_body->AddInstruction(new (allocator) HGoto()); - phi->AddInput(add); - - exit->AddInstruction(new (allocator) HExit()); + MakeIf(loop_header, cmp); + + HNullCheck* null_check = MakeNullCheck(loop_body, new_array); + HArrayLength* array_length = MakeArrayLength(loop_body, null_check); + HInstruction* bounds_check = MakeBoundsCheck(loop_body, phi, array_length); + MakeArraySet(loop_body, null_check, bounds_check, constant_10, DataType::Type::kInt32); + HInstruction* add = MakeBinOp<HAdd>(loop_body, DataType::Type::kInt32, phi, constant_increment); + MakeGoto(loop_body); + + phi->ReplaceInput(add, 1u); // Update back-edge input. + + MakeExit(exit); return bounds_check; } @@ -654,7 +531,7 @@ static HInstruction* BuildSSAGraph3(HGraph* graph, TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination3a) { // int[] array = new int[10]; // for (int i=0; i<10; i++) { array[i] = 10; // Can eliminate. } - HInstruction* bounds_check = BuildSSAGraph3(graph_, GetAllocator(), 0, 1, kCondGE); + HInstruction* bounds_check = BuildSSAGraph3(0, 1, kCondGE); RunBCE(); ASSERT_TRUE(IsRemoved(bounds_check)); } @@ -662,7 +539,7 @@ TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination3a) { TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination3b) { // int[] array = new int[10]; // for (int i=1; i<10; i++) { array[i] = 10; // Can eliminate. } - HInstruction* bounds_check = BuildSSAGraph3(graph_, GetAllocator(), 1, 1, kCondGE); + HInstruction* bounds_check = BuildSSAGraph3(1, 1, kCondGE); RunBCE(); ASSERT_TRUE(IsRemoved(bounds_check)); } @@ -670,7 +547,7 @@ TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination3b) { TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination3c) { // int[] array = new int[10]; // for (int i=0; i<=10; i++) { array[i] = 10; // Can't eliminate. } - HInstruction* bounds_check = BuildSSAGraph3(graph_, GetAllocator(), 0, 1, kCondGT); + HInstruction* bounds_check = BuildSSAGraph3(0, 1, kCondGT); RunBCE(); ASSERT_FALSE(IsRemoved(bounds_check)); } @@ -678,103 +555,86 @@ TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination3c) { TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination3d) { // int[] array = new int[10]; // for (int i=1; i<10; i+=8) { array[i] = 10; // Can eliminate. } - HInstruction* bounds_check = BuildSSAGraph3(graph_, GetAllocator(), 1, 8, kCondGE); + HInstruction* bounds_check = BuildSSAGraph3(1, 8, kCondGE); RunBCE(); ASSERT_TRUE(IsRemoved(bounds_check)); } // for (int i=initial; i<array.length; i++) { array[array.length-i-1] = 10; } -static HInstruction* BuildSSAGraph4(HGraph* graph, - ArenaAllocator* allocator, - int initial, - IfCondition cond = kCondGE) { - HBasicBlock* entry = new (allocator) HBasicBlock(graph); - graph->AddBlock(entry); - graph->SetEntryBlock(entry); - HInstruction* parameter = new (allocator) HParameterValue( - graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); - entry->AddInstruction(parameter); - - HInstruction* constant_initial = graph->GetIntConstant(initial); - HInstruction* constant_1 = graph->GetIntConstant(1); - HInstruction* constant_10 = graph->GetIntConstant(10); - HInstruction* constant_minus_1 = graph->GetIntConstant(-1); - - HBasicBlock* block = new (allocator) HBasicBlock(graph); - graph->AddBlock(block); +HInstruction* BoundsCheckEliminationTest::BuildSSAGraph4(int initial, IfCondition cond) { + HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph_); + graph_->AddBlock(entry); + graph_->SetEntryBlock(entry); + HInstruction* parameter = MakeParam(DataType::Type::kReference); + + HInstruction* constant_initial = graph_->GetIntConstant(initial); + HInstruction* constant_1 = graph_->GetIntConstant(1); + HInstruction* constant_10 = graph_->GetIntConstant(10); + HInstruction* constant_minus_1 = graph_->GetIntConstant(-1); + + HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph_); + graph_->AddBlock(block); entry->AddSuccessor(block); - block->AddInstruction(new (allocator) HGoto()); + MakeGoto(block); - HBasicBlock* loop_header = new (allocator) HBasicBlock(graph); - HBasicBlock* loop_body = new (allocator) HBasicBlock(graph); - HBasicBlock* exit = new (allocator) HBasicBlock(graph); + HBasicBlock* loop_header = new (GetAllocator()) HBasicBlock(graph_); + HBasicBlock* loop_body = new (GetAllocator()) HBasicBlock(graph_); + HBasicBlock* exit = new (GetAllocator()) HBasicBlock(graph_); - graph->AddBlock(loop_header); - graph->AddBlock(loop_body); - graph->AddBlock(exit); + graph_->AddBlock(loop_header); + graph_->AddBlock(loop_body); + graph_->AddBlock(exit); block->AddSuccessor(loop_header); loop_header->AddSuccessor(exit); // true successor loop_header->AddSuccessor(loop_body); // false successor loop_body->AddSuccessor(loop_header); - HPhi* phi = new (allocator) HPhi(allocator, 0, 0, DataType::Type::kInt32); - HInstruction* null_check = new (allocator) HNullCheck(parameter, 0); - HInstruction* array_length = new (allocator) HArrayLength(null_check, 0); + HPhi* phi = MakePhi(loop_header, {constant_initial, /* placeholder */ constant_initial}); + HInstruction* null_check = MakeNullCheck(loop_header, parameter); + HInstruction* array_length = MakeArrayLength(loop_header, null_check); HInstruction* cmp = nullptr; if (cond == kCondGE) { - cmp = new (allocator) HGreaterThanOrEqual(phi, array_length); - } else if (cond == kCondGT) { - cmp = new (allocator) HGreaterThan(phi, array_length); + cmp = MakeCondition<HGreaterThanOrEqual>(loop_header, phi, array_length); + } else { + DCHECK(cond == kCondGT); + cmp = MakeCondition<HGreaterThan>(loop_header, phi, array_length); } - HInstruction* if_inst = new (allocator) HIf(cmp); - loop_header->AddPhi(phi); - loop_header->AddInstruction(null_check); - loop_header->AddInstruction(array_length); - loop_header->AddInstruction(cmp); - loop_header->AddInstruction(if_inst); - phi->AddInput(constant_initial); - - null_check = new (allocator) HNullCheck(parameter, 0); - array_length = new (allocator) HArrayLength(null_check, 0); - HInstruction* sub = new (allocator) HSub(DataType::Type::kInt32, array_length, phi); - HInstruction* add_minus_1 = new (allocator) - HAdd(DataType::Type::kInt32, sub, constant_minus_1); - HInstruction* bounds_check = new (allocator) HBoundsCheck(add_minus_1, array_length, 0); - HInstruction* array_set = new (allocator) HArraySet( - null_check, bounds_check, constant_10, DataType::Type::kInt32, 0); - HInstruction* add = new (allocator) HAdd(DataType::Type::kInt32, phi, constant_1); - loop_body->AddInstruction(null_check); - loop_body->AddInstruction(array_length); - loop_body->AddInstruction(sub); - loop_body->AddInstruction(add_minus_1); - loop_body->AddInstruction(bounds_check); - loop_body->AddInstruction(array_set); - loop_body->AddInstruction(add); - loop_body->AddInstruction(new (allocator) HGoto()); - phi->AddInput(add); - - exit->AddInstruction(new (allocator) HExit()); + MakeIf(loop_header, cmp); + + null_check = MakeNullCheck(loop_body, parameter); + array_length = MakeArrayLength(loop_body, null_check); + HInstruction* sub = MakeBinOp<HSub>(loop_body, DataType::Type::kInt32, array_length, phi); + HInstruction* add_minus_1 = + MakeBinOp<HAdd>(loop_body, DataType::Type::kInt32, sub, constant_minus_1); + HInstruction* bounds_check = MakeBoundsCheck(loop_body, add_minus_1, array_length); + MakeArraySet(loop_body, null_check, bounds_check, constant_10, DataType::Type::kInt32); + HInstruction* add = MakeBinOp<HAdd>(loop_body, DataType::Type::kInt32, phi, constant_1); + MakeGoto(loop_body); + + phi->ReplaceInput(add, 1u); // Update back-edge input. + + MakeExit(exit); return bounds_check; } TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination4a) { // for (int i=0; i<array.length; i++) { array[array.length-i-1] = 10; // Can eliminate with gvn. } - HInstruction* bounds_check = BuildSSAGraph4(graph_, GetAllocator(), 0); + HInstruction* bounds_check = BuildSSAGraph4(0); RunBCE(); ASSERT_TRUE(IsRemoved(bounds_check)); } TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination4b) { // for (int i=1; i<array.length; i++) { array[array.length-i-1] = 10; // Can eliminate. } - HInstruction* bounds_check = BuildSSAGraph4(graph_, GetAllocator(), 1); + HInstruction* bounds_check = BuildSSAGraph4(1); RunBCE(); ASSERT_TRUE(IsRemoved(bounds_check)); } TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination4c) { // for (int i=0; i<=array.length; i++) { array[array.length-i] = 10; // Can't eliminate. } - HInstruction* bounds_check = BuildSSAGraph4(graph_, GetAllocator(), 0, kCondGT); + HInstruction* bounds_check = BuildSSAGraph4(0, kCondGT); RunBCE(); ASSERT_FALSE(IsRemoved(bounds_check)); } @@ -794,9 +654,7 @@ TEST_F(BoundsCheckEliminationTest, BubbleSortArrayBoundsElimination) { HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(entry); graph_->SetEntryBlock(entry); - HInstruction* parameter = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); - entry->AddInstruction(parameter); + HInstruction* parameter = MakeParam(DataType::Type::kReference); HInstruction* constant_0 = graph_->GetIntConstant(0); HInstruction* constant_minus_1 = graph_->GetIntConstant(-1); @@ -805,131 +663,87 @@ TEST_F(BoundsCheckEliminationTest, BubbleSortArrayBoundsElimination) { HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(block); entry->AddSuccessor(block); - block->AddInstruction(new (GetAllocator()) HGoto()); + MakeGoto(block); HBasicBlock* exit = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(exit); - exit->AddInstruction(new (GetAllocator()) HExit()); + MakeExit(exit); HBasicBlock* outer_header = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(outer_header); - HPhi* phi_i = new (GetAllocator()) HPhi(GetAllocator(), 0, 0, DataType::Type::kInt32); - HNullCheck* null_check = new (GetAllocator()) HNullCheck(parameter, 0); - HArrayLength* array_length = new (GetAllocator()) HArrayLength(null_check, 0); - HAdd* add = new (GetAllocator()) HAdd(DataType::Type::kInt32, array_length, constant_minus_1); - HInstruction* cmp = new (GetAllocator()) HGreaterThanOrEqual(phi_i, add); - HIf* if_inst = new (GetAllocator()) HIf(cmp); - outer_header->AddPhi(phi_i); - outer_header->AddInstruction(null_check); - outer_header->AddInstruction(array_length); - outer_header->AddInstruction(add); - outer_header->AddInstruction(cmp); - outer_header->AddInstruction(if_inst); - phi_i->AddInput(constant_0); + HPhi* phi_i = MakePhi(outer_header, {constant_0, /* placeholder */ constant_0}); + HNullCheck* null_check = MakeNullCheck(outer_header, parameter); + HArrayLength* array_length = MakeArrayLength(outer_header, null_check); + HAdd* add = MakeBinOp<HAdd>(outer_header, DataType::Type::kInt32, array_length, constant_minus_1); + HInstruction* cmp = MakeCondition<HGreaterThanOrEqual>(outer_header, phi_i, add); + MakeIf(outer_header, cmp); HBasicBlock* inner_header = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(inner_header); - HPhi* phi_j = new (GetAllocator()) HPhi(GetAllocator(), 0, 0, DataType::Type::kInt32); - null_check = new (GetAllocator()) HNullCheck(parameter, 0); - array_length = new (GetAllocator()) HArrayLength(null_check, 0); - HSub* sub = new (GetAllocator()) HSub(DataType::Type::kInt32, array_length, phi_i); - add = new (GetAllocator()) HAdd(DataType::Type::kInt32, sub, constant_minus_1); - cmp = new (GetAllocator()) HGreaterThanOrEqual(phi_j, add); - if_inst = new (GetAllocator()) HIf(cmp); - inner_header->AddPhi(phi_j); - inner_header->AddInstruction(null_check); - inner_header->AddInstruction(array_length); - inner_header->AddInstruction(sub); - inner_header->AddInstruction(add); - inner_header->AddInstruction(cmp); - inner_header->AddInstruction(if_inst); - phi_j->AddInput(constant_0); + HPhi* phi_j = MakePhi(inner_header, {constant_0, /* placeholder */ constant_0}); + null_check = MakeNullCheck(inner_header, parameter); + array_length = MakeArrayLength(inner_header, null_check); + HSub* sub = MakeBinOp<HSub>(inner_header, DataType::Type::kInt32, array_length, phi_i); + add = MakeBinOp<HAdd>(inner_header, DataType::Type::kInt32, sub, constant_minus_1); + cmp = MakeCondition<HGreaterThanOrEqual>(inner_header, phi_j, add); + MakeIf(inner_header, cmp); HBasicBlock* inner_body_compare = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(inner_body_compare); - null_check = new (GetAllocator()) HNullCheck(parameter, 0); - array_length = new (GetAllocator()) HArrayLength(null_check, 0); - HBoundsCheck* bounds_check1 = new (GetAllocator()) HBoundsCheck(phi_j, array_length, 0); - HArrayGet* array_get_j = new (GetAllocator()) - HArrayGet(null_check, bounds_check1, DataType::Type::kInt32, 0); - inner_body_compare->AddInstruction(null_check); - inner_body_compare->AddInstruction(array_length); - inner_body_compare->AddInstruction(bounds_check1); - inner_body_compare->AddInstruction(array_get_j); - HInstruction* j_plus_1 = new (GetAllocator()) HAdd(DataType::Type::kInt32, phi_j, constant_1); - null_check = new (GetAllocator()) HNullCheck(parameter, 0); - array_length = new (GetAllocator()) HArrayLength(null_check, 0); - HBoundsCheck* bounds_check2 = new (GetAllocator()) HBoundsCheck(j_plus_1, array_length, 0); - HArrayGet* array_get_j_plus_1 = new (GetAllocator()) - HArrayGet(null_check, bounds_check2, DataType::Type::kInt32, 0); - cmp = new (GetAllocator()) HGreaterThanOrEqual(array_get_j, array_get_j_plus_1); - if_inst = new (GetAllocator()) HIf(cmp); - inner_body_compare->AddInstruction(j_plus_1); - inner_body_compare->AddInstruction(null_check); - inner_body_compare->AddInstruction(array_length); - inner_body_compare->AddInstruction(bounds_check2); - inner_body_compare->AddInstruction(array_get_j_plus_1); - inner_body_compare->AddInstruction(cmp); - inner_body_compare->AddInstruction(if_inst); + null_check = MakeNullCheck(inner_body_compare, parameter); + array_length = MakeArrayLength(inner_body_compare, null_check); + HBoundsCheck* bounds_check1 = MakeBoundsCheck(inner_body_compare, phi_j, array_length); + HArrayGet* array_get_j = + MakeArrayGet(inner_body_compare, null_check, bounds_check1, DataType::Type::kInt32); + HInstruction* j_plus_1 = + MakeBinOp<HAdd>(inner_body_compare, DataType::Type::kInt32, phi_j, constant_1); + null_check = MakeNullCheck(inner_body_compare, parameter); + array_length = MakeArrayLength(inner_body_compare, null_check); + HBoundsCheck* bounds_check2 = MakeBoundsCheck(inner_body_compare, j_plus_1, array_length); + HArrayGet* array_get_j_plus_1 = + MakeArrayGet(inner_body_compare, null_check, bounds_check2, DataType::Type::kInt32); + cmp = MakeCondition<HGreaterThanOrEqual>(inner_body_compare, array_get_j, array_get_j_plus_1); + MakeIf(inner_body_compare, cmp); HBasicBlock* inner_body_swap = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(inner_body_swap); - j_plus_1 = new (GetAllocator()) HAdd(DataType::Type::kInt32, phi_j, constant_1); + j_plus_1 = MakeBinOp<HAdd>(inner_body_swap, DataType::Type::kInt32, phi_j, constant_1); // temp = array[j+1] - null_check = new (GetAllocator()) HNullCheck(parameter, 0); - array_length = new (GetAllocator()) HArrayLength(null_check, 0); - HInstruction* bounds_check3 = new (GetAllocator()) HBoundsCheck(j_plus_1, array_length, 0); - array_get_j_plus_1 = new (GetAllocator()) - HArrayGet(null_check, bounds_check3, DataType::Type::kInt32, 0); - inner_body_swap->AddInstruction(j_plus_1); - inner_body_swap->AddInstruction(null_check); - inner_body_swap->AddInstruction(array_length); - inner_body_swap->AddInstruction(bounds_check3); - inner_body_swap->AddInstruction(array_get_j_plus_1); + null_check = MakeNullCheck(inner_body_swap, parameter); + array_length = MakeArrayLength(inner_body_swap, null_check); + HInstruction* bounds_check3 = MakeBoundsCheck(inner_body_swap, j_plus_1, array_length); + array_get_j_plus_1 = + MakeArrayGet(inner_body_swap, null_check, bounds_check3, DataType::Type::kInt32); // array[j+1] = array[j] - null_check = new (GetAllocator()) HNullCheck(parameter, 0); - array_length = new (GetAllocator()) HArrayLength(null_check, 0); - HInstruction* bounds_check4 = new (GetAllocator()) HBoundsCheck(phi_j, array_length, 0); - array_get_j = new (GetAllocator()) - HArrayGet(null_check, bounds_check4, DataType::Type::kInt32, 0); - inner_body_swap->AddInstruction(null_check); - inner_body_swap->AddInstruction(array_length); - inner_body_swap->AddInstruction(bounds_check4); - inner_body_swap->AddInstruction(array_get_j); - null_check = new (GetAllocator()) HNullCheck(parameter, 0); - array_length = new (GetAllocator()) HArrayLength(null_check, 0); - HInstruction* bounds_check5 = new (GetAllocator()) HBoundsCheck(j_plus_1, array_length, 0); - HArraySet* array_set_j_plus_1 = new (GetAllocator()) - HArraySet(null_check, bounds_check5, array_get_j, DataType::Type::kInt32, 0); - inner_body_swap->AddInstruction(null_check); - inner_body_swap->AddInstruction(array_length); - inner_body_swap->AddInstruction(bounds_check5); - inner_body_swap->AddInstruction(array_set_j_plus_1); + null_check = MakeNullCheck(inner_body_swap, parameter); + array_length = MakeArrayLength(inner_body_swap, null_check); + HInstruction* bounds_check4 = MakeBoundsCheck(inner_body_swap, phi_j, array_length); + array_get_j = MakeArrayGet(inner_body_swap, null_check, bounds_check4, DataType::Type::kInt32); + null_check = MakeNullCheck(inner_body_swap, parameter); + array_length = MakeArrayLength(inner_body_swap, null_check); + HInstruction* bounds_check5 = MakeBoundsCheck(inner_body_swap, j_plus_1, array_length); + MakeArraySet(inner_body_swap, null_check, bounds_check5, array_get_j, DataType::Type::kInt32); // array[j] = temp - null_check = new (GetAllocator()) HNullCheck(parameter, 0); - array_length = new (GetAllocator()) HArrayLength(null_check, 0); - HInstruction* bounds_check6 = new (GetAllocator()) HBoundsCheck(phi_j, array_length, 0); - HArraySet* array_set_j = new (GetAllocator()) - HArraySet(null_check, bounds_check6, array_get_j_plus_1, DataType::Type::kInt32, 0); - inner_body_swap->AddInstruction(null_check); - inner_body_swap->AddInstruction(array_length); - inner_body_swap->AddInstruction(bounds_check6); - inner_body_swap->AddInstruction(array_set_j); - inner_body_swap->AddInstruction(new (GetAllocator()) HGoto()); + null_check = MakeNullCheck(inner_body_swap, parameter); + array_length = MakeArrayLength(inner_body_swap, null_check); + HInstruction* bounds_check6 = MakeBoundsCheck(inner_body_swap, phi_j, array_length); + MakeArraySet( + inner_body_swap, null_check, bounds_check6, array_get_j_plus_1, DataType::Type::kInt32); + MakeGoto(inner_body_swap); HBasicBlock* inner_body_add = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(inner_body_add); - add = new (GetAllocator()) HAdd(DataType::Type::kInt32, phi_j, constant_1); - inner_body_add->AddInstruction(add); - inner_body_add->AddInstruction(new (GetAllocator()) HGoto()); - phi_j->AddInput(add); + add = MakeBinOp<HAdd>(inner_body_add, DataType::Type::kInt32, phi_j, constant_1); + MakeGoto(inner_body_add); + + phi_j->ReplaceInput(add, 1u); // Update back-edge input. HBasicBlock* outer_body_add = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(outer_body_add); - add = new (GetAllocator()) HAdd(DataType::Type::kInt32, phi_i, constant_1); - outer_body_add->AddInstruction(add); - outer_body_add->AddInstruction(new (GetAllocator()) HGoto()); - phi_i->AddInput(add); + add = MakeBinOp<HAdd>(outer_body_add, DataType::Type::kInt32, phi_i, constant_1); + MakeGoto(outer_body_add); + + phi_i->ReplaceInput(add, 1u); // Update back-edge input. block->AddSuccessor(outer_header); outer_header->AddSuccessor(exit); @@ -965,9 +779,7 @@ TEST_F(BoundsCheckEliminationTest, ModArrayBoundsElimination) { HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(entry); graph_->SetEntryBlock(entry); - HInstruction* param_i = new (GetAllocator()) - HParameterValue(graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kInt32); - entry->AddInstruction(param_i); + HInstruction* param_i = MakeParam(DataType::Type::kInt32); HInstruction* constant_0 = graph_->GetIntConstant(0); HInstruction* constant_1 = graph_->GetIntConstant(1); @@ -979,13 +791,8 @@ TEST_F(BoundsCheckEliminationTest, ModArrayBoundsElimination) { graph_->AddBlock(block); entry->AddSuccessor(block); // We pass a bogus constant for the class to avoid mocking one. - HInstruction* new_array = new (GetAllocator()) HNewArray( - /* cls= */ constant_10, - /* length= */ constant_10, - /* dex_pc= */ 0, - /* component_size_shift= */ 0); - block->AddInstruction(new_array); - block->AddInstruction(new (GetAllocator()) HGoto()); + HInstruction* new_array = MakeNewArray(block, /* cls= */ constant_10, /* length= */ constant_10); + MakeGoto(block); HBasicBlock* loop_header = new (GetAllocator()) HBasicBlock(graph_); HBasicBlock* loop_body = new (GetAllocator()) HBasicBlock(graph_); @@ -999,103 +806,72 @@ TEST_F(BoundsCheckEliminationTest, ModArrayBoundsElimination) { loop_header->AddSuccessor(loop_body); // false successor loop_body->AddSuccessor(loop_header); - HPhi* phi = new (GetAllocator()) HPhi(GetAllocator(), 0, 0, DataType::Type::kInt32); - HInstruction* cmp = new (GetAllocator()) HGreaterThanOrEqual(phi, constant_200); - HInstruction* if_inst = new (GetAllocator()) HIf(cmp); - loop_header->AddPhi(phi); - loop_header->AddInstruction(cmp); - loop_header->AddInstruction(if_inst); - phi->AddInput(constant_0); + HPhi* phi = MakePhi(loop_header, {constant_0, /* placeholder */ constant_0}); + HInstruction* cmp = MakeCondition<HGreaterThanOrEqual>(loop_header, phi, constant_200); + MakeIf(loop_header, cmp); ////////////////////////////////////////////////////////////////////////////////// // LOOP BODY: // array[i % 10] = 10; - HRem* i_mod_10 = new (GetAllocator()) HRem(DataType::Type::kInt32, phi, constant_10, 0); - HBoundsCheck* bounds_check_i_mod_10 = new (GetAllocator()) HBoundsCheck(i_mod_10, constant_10, 0); - HInstruction* array_set = new (GetAllocator()) HArraySet( - new_array, bounds_check_i_mod_10, constant_10, DataType::Type::kInt32, 0); - loop_body->AddInstruction(i_mod_10); - loop_body->AddInstruction(bounds_check_i_mod_10); - loop_body->AddInstruction(array_set); + HRem* i_mod_10 = MakeBinOp<HRem>(loop_body, DataType::Type::kInt32, phi, constant_10); + HBoundsCheck* bounds_check_i_mod_10 = MakeBoundsCheck(loop_body, i_mod_10, constant_10); + MakeArraySet(loop_body, new_array, bounds_check_i_mod_10, constant_10, DataType::Type::kInt32); // array[i % 1] = 10; - HRem* i_mod_1 = new (GetAllocator()) HRem(DataType::Type::kInt32, phi, constant_1, 0); - HBoundsCheck* bounds_check_i_mod_1 = new (GetAllocator()) HBoundsCheck(i_mod_1, constant_10, 0); - array_set = new (GetAllocator()) HArraySet( - new_array, bounds_check_i_mod_1, constant_10, DataType::Type::kInt32, 0); - loop_body->AddInstruction(i_mod_1); - loop_body->AddInstruction(bounds_check_i_mod_1); - loop_body->AddInstruction(array_set); + HRem* i_mod_1 = MakeBinOp<HRem>(loop_body, DataType::Type::kInt32, phi, constant_1); + HBoundsCheck* bounds_check_i_mod_1 = MakeBoundsCheck(loop_body, i_mod_1, constant_10); + MakeArraySet(loop_body, new_array, bounds_check_i_mod_1, constant_10, DataType::Type::kInt32); // array[i % 200] = 10; - HRem* i_mod_200 = new (GetAllocator()) HRem(DataType::Type::kInt32, phi, constant_1, 0); - HBoundsCheck* bounds_check_i_mod_200 = new (GetAllocator()) HBoundsCheck( - i_mod_200, constant_10, 0); - array_set = new (GetAllocator()) HArraySet( - new_array, bounds_check_i_mod_200, constant_10, DataType::Type::kInt32, 0); - loop_body->AddInstruction(i_mod_200); - loop_body->AddInstruction(bounds_check_i_mod_200); - loop_body->AddInstruction(array_set); + HRem* i_mod_200 = MakeBinOp<HRem>(loop_body, DataType::Type::kInt32, phi, constant_1); + HBoundsCheck* bounds_check_i_mod_200 = MakeBoundsCheck(loop_body, i_mod_200, constant_10); + MakeArraySet(loop_body, new_array, bounds_check_i_mod_200, constant_10, DataType::Type::kInt32); // array[i % -10] = 10; - HRem* i_mod_minus_10 = new (GetAllocator()) HRem( - DataType::Type::kInt32, phi, constant_minus_10, 0); - HBoundsCheck* bounds_check_i_mod_minus_10 = new (GetAllocator()) HBoundsCheck( - i_mod_minus_10, constant_10, 0); - array_set = new (GetAllocator()) HArraySet( - new_array, bounds_check_i_mod_minus_10, constant_10, DataType::Type::kInt32, 0); - loop_body->AddInstruction(i_mod_minus_10); - loop_body->AddInstruction(bounds_check_i_mod_minus_10); - loop_body->AddInstruction(array_set); + HRem* i_mod_minus_10 = MakeBinOp<HRem>(loop_body, DataType::Type::kInt32, phi, constant_minus_10); + HBoundsCheck* bounds_check_i_mod_minus_10 = + MakeBoundsCheck(loop_body, i_mod_minus_10, constant_10); + MakeArraySet( + loop_body, new_array, bounds_check_i_mod_minus_10, constant_10, DataType::Type::kInt32); // array[i%array.length] = 10; - HNullCheck* null_check = new (GetAllocator()) HNullCheck(new_array, 0); - HArrayLength* array_length = new (GetAllocator()) HArrayLength(null_check, 0); - HRem* i_mod_array_length = new (GetAllocator()) HRem( - DataType::Type::kInt32, phi, array_length, 0); - HBoundsCheck* bounds_check_i_mod_array_len = new (GetAllocator()) HBoundsCheck( - i_mod_array_length, array_length, 0); - array_set = new (GetAllocator()) HArraySet( - null_check, bounds_check_i_mod_array_len, constant_10, DataType::Type::kInt32, 0); - loop_body->AddInstruction(null_check); - loop_body->AddInstruction(array_length); - loop_body->AddInstruction(i_mod_array_length); - loop_body->AddInstruction(bounds_check_i_mod_array_len); - loop_body->AddInstruction(array_set); + HNullCheck* null_check = MakeNullCheck(loop_body, new_array); + HArrayLength* array_length = MakeArrayLength(loop_body, null_check); + HRem* i_mod_array_length = MakeBinOp<HRem>(loop_body, DataType::Type::kInt32, phi, array_length); + HBoundsCheck* bounds_check_i_mod_array_len = + MakeBoundsCheck(loop_body, i_mod_array_length, array_length); + MakeArraySet( + loop_body, null_check, bounds_check_i_mod_array_len, constant_10, DataType::Type::kInt32); // array[param_i % 10] = 10; - HRem* param_i_mod_10 = new (GetAllocator()) HRem(DataType::Type::kInt32, param_i, constant_10, 0); - HBoundsCheck* bounds_check_param_i_mod_10 = new (GetAllocator()) HBoundsCheck( - param_i_mod_10, constant_10, 0); - array_set = new (GetAllocator()) HArraySet( - new_array, bounds_check_param_i_mod_10, constant_10, DataType::Type::kInt32, 0); - loop_body->AddInstruction(param_i_mod_10); - loop_body->AddInstruction(bounds_check_param_i_mod_10); - loop_body->AddInstruction(array_set); + HRem* param_i_mod_10 = MakeBinOp<HRem>(loop_body, DataType::Type::kInt32, param_i, constant_10); + HBoundsCheck* bounds_check_param_i_mod_10 = + MakeBoundsCheck(loop_body, param_i_mod_10, constant_10); + MakeArraySet( + loop_body, new_array, bounds_check_param_i_mod_10, constant_10, DataType::Type::kInt32); // array[param_i%array.length] = 10; - null_check = new (GetAllocator()) HNullCheck(new_array, 0); - array_length = new (GetAllocator()) HArrayLength(null_check, 0); - HRem* param_i_mod_array_length = new (GetAllocator()) HRem( - DataType::Type::kInt32, param_i, array_length, 0); - HBoundsCheck* bounds_check_param_i_mod_array_len = new (GetAllocator()) HBoundsCheck( - param_i_mod_array_length, array_length, 0); - array_set = new (GetAllocator()) HArraySet( - null_check, bounds_check_param_i_mod_array_len, constant_10, DataType::Type::kInt32, 0); - loop_body->AddInstruction(null_check); - loop_body->AddInstruction(array_length); - loop_body->AddInstruction(param_i_mod_array_length); - loop_body->AddInstruction(bounds_check_param_i_mod_array_len); - loop_body->AddInstruction(array_set); + null_check = MakeNullCheck(loop_body, new_array); + array_length = MakeArrayLength(loop_body, null_check); + HRem* param_i_mod_array_length = + MakeBinOp<HRem>(loop_body, DataType::Type::kInt32, param_i, array_length); + HBoundsCheck* bounds_check_param_i_mod_array_len = + MakeBoundsCheck(loop_body, param_i_mod_array_length, array_length); + MakeArraySet(loop_body, + null_check, + bounds_check_param_i_mod_array_len, + constant_10, + DataType::Type::kInt32); // i++; - HInstruction* add = new (GetAllocator()) HAdd(DataType::Type::kInt32, phi, constant_1); - loop_body->AddInstruction(add); - loop_body->AddInstruction(new (GetAllocator()) HGoto()); - phi->AddInput(add); + HInstruction* add = MakeBinOp<HAdd>(loop_body, DataType::Type::kInt32, phi, constant_1); + MakeGoto(loop_body); + + phi->ReplaceInput(add, 1u); // Update back-edge input. + ////////////////////////////////////////////////////////////////////////////////// - exit->AddInstruction(new (GetAllocator()) HExit()); + MakeExit(exit); RunBCE(); diff --git a/compiler/optimizing/codegen_test.cc b/compiler/optimizing/codegen_test.cc index c72d3ea24a..e3366760ca 100644 --- a/compiler/optimizing/codegen_test.cc +++ b/compiler/optimizing/codegen_test.cc @@ -417,16 +417,15 @@ TEST_F(CodegenTest, NonMaterializedCondition) { HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(entry); graph->SetEntryBlock(entry); - entry->AddInstruction(new (GetAllocator()) HGoto()); + MakeGoto(entry); HBasicBlock* first_block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(first_block); entry->AddSuccessor(first_block); HIntConstant* constant0 = graph->GetIntConstant(0); HIntConstant* constant1 = graph->GetIntConstant(1); - HEqual* equal = new (GetAllocator()) HEqual(constant0, constant0); - first_block->AddInstruction(equal); - first_block->AddInstruction(new (GetAllocator()) HIf(equal)); + HEqual* equal = MakeCondition<HEqual>(first_block, constant0, constant0); + MakeIf(first_block, equal); HBasicBlock* then_block = new (GetAllocator()) HBasicBlock(graph); HBasicBlock* else_block = new (GetAllocator()) HBasicBlock(graph); @@ -441,9 +440,9 @@ TEST_F(CodegenTest, NonMaterializedCondition) { then_block->AddSuccessor(exit_block); else_block->AddSuccessor(exit_block); - exit_block->AddInstruction(new (GetAllocator()) HExit()); - then_block->AddInstruction(new (GetAllocator()) HReturn(constant0)); - else_block->AddInstruction(new (GetAllocator()) HReturn(constant1)); + MakeExit(exit_block); + MakeReturn(then_block, constant0); + MakeReturn(else_block, constant1); ASSERT_FALSE(equal->IsEmittedAtUseSite()); graph->BuildDominatorTree(); @@ -479,12 +478,12 @@ TEST_F(CodegenTest, MaterializedCondition1) { HBasicBlock* entry_block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(entry_block); graph->SetEntryBlock(entry_block); - entry_block->AddInstruction(new (GetAllocator()) HGoto()); + MakeGoto(entry_block); HBasicBlock* code_block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(code_block); HBasicBlock* exit_block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(exit_block); - exit_block->AddInstruction(new (GetAllocator()) HExit()); + MakeExit(exit_block); entry_block->AddSuccessor(code_block); code_block->AddSuccessor(exit_block); @@ -492,10 +491,8 @@ TEST_F(CodegenTest, MaterializedCondition1) { HIntConstant* cst_lhs = graph->GetIntConstant(lhs[i]); HIntConstant* cst_rhs = graph->GetIntConstant(rhs[i]); - HLessThan cmp_lt(cst_lhs, cst_rhs); - code_block->AddInstruction(&cmp_lt); - HReturn ret(&cmp_lt); - code_block->AddInstruction(&ret); + HInstruction* cmp_lt = MakeCondition<HLessThan>(code_block, cst_lhs, cst_rhs); + MakeReturn(code_block, cmp_lt); graph->BuildDominatorTree(); auto hook_before_codegen = [](HGraph* graph_in) { @@ -528,7 +525,7 @@ TEST_F(CodegenTest, MaterializedCondition2) { HBasicBlock* entry_block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(entry_block); graph->SetEntryBlock(entry_block); - entry_block->AddInstruction(new (GetAllocator()) HGoto()); + MakeGoto(entry_block); HBasicBlock* if_block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(if_block); @@ -538,7 +535,7 @@ TEST_F(CodegenTest, MaterializedCondition2) { graph->AddBlock(if_false_block); HBasicBlock* exit_block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(exit_block); - exit_block->AddInstruction(new (GetAllocator()) HExit()); + MakeExit(exit_block); graph->SetEntryBlock(entry_block); entry_block->AddSuccessor(if_block); @@ -550,21 +547,18 @@ TEST_F(CodegenTest, MaterializedCondition2) { HIntConstant* cst_lhs = graph->GetIntConstant(lhs[i]); HIntConstant* cst_rhs = graph->GetIntConstant(rhs[i]); - HLessThan cmp_lt(cst_lhs, cst_rhs); - if_block->AddInstruction(&cmp_lt); + HInstruction* cmp_lt = MakeCondition<HLessThan>(if_block, cst_lhs, cst_rhs); // We insert a fake instruction to separate the HIf from the HLessThan // and force the materialization of the condition. - HMemoryBarrier force_materialization(MemBarrierKind::kAnyAny, 0); - if_block->AddInstruction(&force_materialization); - HIf if_lt(&cmp_lt); - if_block->AddInstruction(&if_lt); + HInstruction* force_materialization = + new (GetAllocator()) HMemoryBarrier(MemBarrierKind::kAnyAny, 0); + if_block->AddInstruction(force_materialization); + MakeIf(if_block, cmp_lt); HIntConstant* cst_lt = graph->GetIntConstant(1); - HReturn ret_lt(cst_lt); - if_true_block->AddInstruction(&ret_lt); + MakeReturn(if_true_block, cst_lt); HIntConstant* cst_ge = graph->GetIntConstant(0); - HReturn ret_ge(cst_ge); - if_false_block->AddInstruction(&ret_ge); + MakeReturn(if_false_block, cst_ge); graph->BuildDominatorTree(); auto hook_before_codegen = [](HGraph* graph_in) { @@ -610,7 +604,7 @@ void CodegenTest::TestComparison(IfCondition condition, HBasicBlock* entry_block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(entry_block); graph->SetEntryBlock(entry_block); - entry_block->AddInstruction(new (GetAllocator()) HGoto()); + MakeGoto(entry_block); HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(block); @@ -618,7 +612,7 @@ void CodegenTest::TestComparison(IfCondition condition, HBasicBlock* exit_block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(exit_block); graph->SetExitBlock(exit_block); - exit_block->AddInstruction(new (GetAllocator()) HExit()); + MakeExit(exit_block); entry_block->AddSuccessor(block); block->AddSuccessor(exit_block); @@ -640,48 +634,47 @@ void CodegenTest::TestComparison(IfCondition condition, const uint64_t y = j; switch (condition) { case kCondEQ: - comparison = new (GetAllocator()) HEqual(op1, op2); + comparison = MakeCondition<HEqual>(block, op1, op2); expected_result = (i == j); break; case kCondNE: - comparison = new (GetAllocator()) HNotEqual(op1, op2); + comparison = MakeCondition<HNotEqual>(block, op1, op2); expected_result = (i != j); break; case kCondLT: - comparison = new (GetAllocator()) HLessThan(op1, op2); + comparison = MakeCondition<HLessThan>(block, op1, op2); expected_result = (i < j); break; case kCondLE: - comparison = new (GetAllocator()) HLessThanOrEqual(op1, op2); + comparison = MakeCondition<HLessThanOrEqual>(block, op1, op2); expected_result = (i <= j); break; case kCondGT: - comparison = new (GetAllocator()) HGreaterThan(op1, op2); + comparison = MakeCondition<HGreaterThan>(block, op1, op2); expected_result = (i > j); break; case kCondGE: - comparison = new (GetAllocator()) HGreaterThanOrEqual(op1, op2); + comparison = MakeCondition<HGreaterThanOrEqual>(block, op1, op2); expected_result = (i >= j); break; case kCondB: - comparison = new (GetAllocator()) HBelow(op1, op2); + comparison = MakeCondition<HBelow>(block, op1, op2); expected_result = (x < y); break; case kCondBE: - comparison = new (GetAllocator()) HBelowOrEqual(op1, op2); + comparison = MakeCondition<HBelowOrEqual>(block, op1, op2); expected_result = (x <= y); break; case kCondA: - comparison = new (GetAllocator()) HAbove(op1, op2); + comparison = MakeCondition<HAbove>(block, op1, op2); expected_result = (x > y); break; case kCondAE: - comparison = new (GetAllocator()) HAboveOrEqual(op1, op2); + comparison = MakeCondition<HAboveOrEqual>(block, op1, op2); expected_result = (x >= y); break; } - block->AddInstruction(comparison); - block->AddInstruction(new (GetAllocator()) HReturn(comparison)); + MakeReturn(block, comparison); graph->BuildDominatorTree(); std::unique_ptr<CompilerOptions> compiler_options = diff --git a/compiler/optimizing/constant_folding_test.cc b/compiler/optimizing/constant_folding_test.cc index 689d77111c..7ff8649fa9 100644 --- a/compiler/optimizing/constant_folding_test.cc +++ b/compiler/optimizing/constant_folding_test.cc @@ -748,10 +748,8 @@ TEST_F(ConstantFoldingTest, UnsignedComparisonsWithZero) { block->AddSuccessor(exit_block); // Make various unsigned comparisons with zero against a parameter. - HInstruction* parameter = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kInt32, true); - entry_block->AddInstruction(parameter); - entry_block->AddInstruction(new (GetAllocator()) HGoto()); + HInstruction* parameter = MakeParam(DataType::Type::kInt32); + MakeGoto(entry_block); HInstruction* zero = graph_->GetIntConstant(0); @@ -772,9 +770,9 @@ TEST_F(ConstantFoldingTest, UnsignedComparisonsWithZero) { block->AddInstruction(new (GetAllocator()) HSelect(last, parameter, parameter, 0)); block->AddInstruction(last = new (GetAllocator()) HBelowOrEqual(parameter, zero)); block->AddInstruction(new (GetAllocator()) HSelect(last, parameter, parameter, 0)); - block->AddInstruction(new (GetAllocator()) HReturn(zero)); + MakeReturn(block, zero); - exit_block->AddInstruction(new (GetAllocator()) HExit()); + MakeExit(exit_block); graph_->BuildDominatorTree(); diff --git a/compiler/optimizing/graph_checker_test.cc b/compiler/optimizing/graph_checker_test.cc index b256fbb46d..cea34b9e2c 100644 --- a/compiler/optimizing/graph_checker_test.cc +++ b/compiler/optimizing/graph_checker_test.cc @@ -37,11 +37,11 @@ class GraphCheckerTest : public CommonCompilerTest, public OptimizingUnitTestHel HGraph* GraphCheckerTest::CreateSimpleCFG() { HGraph* graph = CreateGraph(); HBasicBlock* entry_block = new (GetAllocator()) HBasicBlock(graph); - entry_block->AddInstruction(new (GetAllocator()) HReturnVoid()); + MakeReturnVoid(entry_block); graph->AddBlock(entry_block); graph->SetEntryBlock(entry_block); HBasicBlock* exit_block = new (GetAllocator()) HBasicBlock(graph); - exit_block->AddInstruction(new (GetAllocator()) HExit()); + MakeExit(exit_block); graph->AddBlock(exit_block); graph->SetExitBlock(exit_block); entry_block->AddSuccessor(exit_block); diff --git a/compiler/optimizing/graph_test.cc b/compiler/optimizing/graph_test.cc index b5d712736f..46c93aff84 100644 --- a/compiler/optimizing/graph_test.cc +++ b/compiler/optimizing/graph_test.cc @@ -38,18 +38,15 @@ HBasicBlock* GraphTest::CreateIfBlock(HGraph* graph) { HBasicBlock* if_block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(if_block); HInstruction* instr = graph->GetIntConstant(4); - HInstruction* equal = new (GetAllocator()) HEqual(instr, instr); - if_block->AddInstruction(equal); - instr = new (GetAllocator()) HIf(equal); - if_block->AddInstruction(instr); + HInstruction* equal = MakeCondition<HEqual>(if_block, instr, instr); + MakeIf(if_block, equal); return if_block; } HBasicBlock* GraphTest::CreateGotoBlock(HGraph* graph) { HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(block); - HInstruction* got = new (GetAllocator()) HGoto(); - block->AddInstruction(got); + MakeGoto(block); return block; } @@ -70,8 +67,7 @@ HBasicBlock* GraphTest::CreateReturnBlock(HGraph* graph) { HBasicBlock* GraphTest::CreateExitBlock(HGraph* graph) { HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(block); - HInstruction* exit_instr = new (GetAllocator()) HExit(); - block->AddInstruction(exit_instr); + MakeExit(block); return block; } diff --git a/compiler/optimizing/gvn_test.cc b/compiler/optimizing/gvn_test.cc index 1eb6307cb1..27121fc55a 100644 --- a/compiler/optimizing/gvn_test.cc +++ b/compiler/optimizing/gvn_test.cc @@ -32,67 +32,22 @@ TEST_F(GVNTest, LocalFieldElimination) { HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(entry); graph->SetEntryBlock(entry); - HInstruction* parameter = new (GetAllocator()) HParameterValue(graph->GetDexFile(), - dex::TypeIndex(0), - 0, - DataType::Type::kReference); - entry->AddInstruction(parameter); + HInstruction* parameter = MakeParam(DataType::Type::kReference); HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(block); entry->AddSuccessor(block); - block->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, - nullptr, - DataType::Type::kReference, - MemberOffset(42), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0)); - block->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, - nullptr, - DataType::Type::kReference, - MemberOffset(42), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0)); - HInstruction* to_remove = block->GetLastInstruction(); - block->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, - nullptr, - DataType::Type::kReference, - MemberOffset(43), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0)); - HInstruction* different_offset = block->GetLastInstruction(); + MakeIFieldGet(block, parameter, DataType::Type::kReference, MemberOffset(42)); + HInstruction* to_remove = + MakeIFieldGet(block, parameter, DataType::Type::kReference, MemberOffset(42)); + HInstruction* different_offset = + MakeIFieldGet(block, parameter, DataType::Type::kReference, MemberOffset(43)); // Kill the value. - block->AddInstruction(new (GetAllocator()) HInstanceFieldSet(parameter, - parameter, - nullptr, - DataType::Type::kReference, - MemberOffset(42), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0)); - block->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, - nullptr, - DataType::Type::kReference, - MemberOffset(42), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0)); - HInstruction* use_after_kill = block->GetLastInstruction(); - block->AddInstruction(new (GetAllocator()) HExit()); + MakeIFieldSet(block, parameter, parameter, MemberOffset(42)); + HInstruction* use_after_kill = + MakeIFieldGet(block, parameter, DataType::Type::kReference, MemberOffset(42)); + MakeExit(block); ASSERT_EQ(to_remove->GetBlock(), block); ASSERT_EQ(different_offset->GetBlock(), block); @@ -113,26 +68,16 @@ TEST_F(GVNTest, GlobalFieldElimination) { HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(entry); graph->SetEntryBlock(entry); - HInstruction* parameter = new (GetAllocator()) HParameterValue(graph->GetDexFile(), - dex::TypeIndex(0), - 0, - DataType::Type::kReference); - entry->AddInstruction(parameter); + HInstruction* parameter = MakeParam(DataType::Type::kReference); HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(block); entry->AddSuccessor(block); - block->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, - nullptr, - DataType::Type::kBool, - MemberOffset(42), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0)); - - block->AddInstruction(new (GetAllocator()) HIf(block->GetLastInstruction())); + + HInstruction* field_get = + MakeIFieldGet(block, parameter, DataType::Type::kBool, MemberOffset(42)); + MakeIf(block, field_get); + HBasicBlock* then = new (GetAllocator()) HBasicBlock(graph); HBasicBlock* else_ = new (GetAllocator()) HBasicBlock(graph); HBasicBlock* join = new (GetAllocator()) HBasicBlock(graph); @@ -145,36 +90,14 @@ TEST_F(GVNTest, GlobalFieldElimination) { then->AddSuccessor(join); else_->AddSuccessor(join); - then->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, - nullptr, - DataType::Type::kBool, - MemberOffset(42), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0)); - then->AddInstruction(new (GetAllocator()) HGoto()); - else_->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, - nullptr, - DataType::Type::kBool, - MemberOffset(42), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0)); - else_->AddInstruction(new (GetAllocator()) HGoto()); - join->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, - nullptr, - DataType::Type::kBool, - MemberOffset(42), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0)); - join->AddInstruction(new (GetAllocator()) HExit()); + MakeIFieldGet(then, parameter, DataType::Type::kBool, MemberOffset(42)); + MakeGoto(then); + + MakeIFieldGet(else_, parameter, DataType::Type::kBool, MemberOffset(42)); + MakeGoto(else_); + + MakeIFieldGet(join, parameter, DataType::Type::kBool, MemberOffset(42)); + MakeExit(join); graph->BuildDominatorTree(); SideEffectsAnalysis side_effects(graph); @@ -193,25 +116,13 @@ TEST_F(GVNTest, LoopFieldElimination) { graph->AddBlock(entry); graph->SetEntryBlock(entry); - HInstruction* parameter = new (GetAllocator()) HParameterValue(graph->GetDexFile(), - dex::TypeIndex(0), - 0, - DataType::Type::kReference); - entry->AddInstruction(parameter); + HInstruction* parameter = MakeParam(DataType::Type::kReference); HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(block); entry->AddSuccessor(block); - block->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, - nullptr, - DataType::Type::kBool, - MemberOffset(42), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0)); - block->AddInstruction(new (GetAllocator()) HGoto()); + MakeIFieldGet(block, parameter, DataType::Type::kBool, MemberOffset(42)); + MakeGoto(block); HBasicBlock* loop_header = new (GetAllocator()) HBasicBlock(graph); HBasicBlock* loop_body = new (GetAllocator()) HBasicBlock(graph); @@ -225,54 +136,21 @@ TEST_F(GVNTest, LoopFieldElimination) { loop_header->AddSuccessor(exit); loop_body->AddSuccessor(loop_header); - loop_header->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, - nullptr, - DataType::Type::kBool, - MemberOffset(42), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0)); - HInstruction* field_get_in_loop_header = loop_header->GetLastInstruction(); - loop_header->AddInstruction(new (GetAllocator()) HIf(block->GetLastInstruction())); + HInstruction* field_get_in_loop_header = + MakeIFieldGet(loop_header, parameter, DataType::Type::kBool, MemberOffset(42)); + MakeIf(loop_header, field_get_in_loop_header); // Kill inside the loop body to prevent field gets inside the loop header // and the body to be GVN'ed. - loop_body->AddInstruction(new (GetAllocator()) HInstanceFieldSet(parameter, - parameter, - nullptr, - DataType::Type::kBool, - MemberOffset(42), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0)); - HInstruction* field_set = loop_body->GetLastInstruction(); - loop_body->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, - nullptr, - DataType::Type::kBool, - MemberOffset(42), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0)); - HInstruction* field_get_in_loop_body = loop_body->GetLastInstruction(); - loop_body->AddInstruction(new (GetAllocator()) HGoto()); - - exit->AddInstruction(new (GetAllocator()) HInstanceFieldGet(parameter, - nullptr, - DataType::Type::kBool, - MemberOffset(42), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0)); - HInstruction* field_get_in_exit = exit->GetLastInstruction(); - exit->AddInstruction(new (GetAllocator()) HExit()); + HInstruction* field_set = + MakeIFieldSet(loop_body, parameter, parameter, DataType::Type::kBool, MemberOffset(42)); + HInstruction* field_get_in_loop_body = + MakeIFieldGet(loop_body, parameter, DataType::Type::kBool, MemberOffset(42)); + MakeGoto(loop_body); + + HInstruction* field_get_in_exit = + MakeIFieldGet(exit, parameter, DataType::Type::kBool, MemberOffset(42)); + MakeExit(exit); ASSERT_EQ(field_get_in_loop_header->GetBlock(), loop_header); ASSERT_EQ(field_get_in_loop_body->GetBlock(), loop_body); @@ -337,20 +215,16 @@ TEST_F(GVNTest, LoopSideEffects) { inner_loop_body->AddSuccessor(inner_loop_header); inner_loop_exit->AddSuccessor(outer_loop_header); - HInstruction* parameter = new (GetAllocator()) HParameterValue(graph->GetDexFile(), - dex::TypeIndex(0), - 0, - DataType::Type::kBool); - entry->AddInstruction(parameter); - entry->AddInstruction(new (GetAllocator()) HGoto()); - outer_loop_header->AddInstruction(new (GetAllocator()) HSuspendCheck()); - outer_loop_header->AddInstruction(new (GetAllocator()) HIf(parameter)); - outer_loop_body->AddInstruction(new (GetAllocator()) HGoto()); - inner_loop_header->AddInstruction(new (GetAllocator()) HSuspendCheck()); - inner_loop_header->AddInstruction(new (GetAllocator()) HIf(parameter)); - inner_loop_body->AddInstruction(new (GetAllocator()) HGoto()); - inner_loop_exit->AddInstruction(new (GetAllocator()) HGoto()); - outer_loop_exit->AddInstruction(new (GetAllocator()) HExit()); + HInstruction* parameter = MakeParam(DataType::Type::kBool); + MakeGoto(entry); + MakeSuspendCheck(outer_loop_header); + MakeIf(outer_loop_header, parameter); + MakeGoto(outer_loop_body); + MakeSuspendCheck(inner_loop_header); + MakeIf(inner_loop_header, parameter); + MakeGoto(inner_loop_body); + MakeGoto(inner_loop_exit); + MakeExit(outer_loop_exit); graph->BuildDominatorTree(); @@ -360,16 +234,7 @@ TEST_F(GVNTest, LoopSideEffects) { // Check that the only side effect of loops is to potentially trigger GC. { // Make one block with a side effect. - entry->AddInstruction(new (GetAllocator()) HInstanceFieldSet(parameter, - parameter, - nullptr, - DataType::Type::kReference, - MemberOffset(42), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0)); + MakeIFieldSet(entry, parameter, parameter, DataType::Type::kReference, MemberOffset(42)); SideEffectsAnalysis side_effects(graph); side_effects.Run(); @@ -384,18 +249,8 @@ TEST_F(GVNTest, LoopSideEffects) { // Check that the side effects of the outer loop does not affect the inner loop. { - outer_loop_body->InsertInstructionBefore( - new (GetAllocator()) HInstanceFieldSet(parameter, - parameter, - nullptr, - DataType::Type::kReference, - MemberOffset(42), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0), - outer_loop_body->GetLastInstruction()); + MakeIFieldSet( + outer_loop_body, parameter, parameter, DataType::Type::kReference, MemberOffset(42)); SideEffectsAnalysis side_effects(graph); side_effects.Run(); @@ -410,18 +265,8 @@ TEST_F(GVNTest, LoopSideEffects) { // Check that the side effects of the inner loop affects the outer loop. { outer_loop_body->RemoveInstruction(outer_loop_body->GetFirstInstruction()); - inner_loop_body->InsertInstructionBefore( - new (GetAllocator()) HInstanceFieldSet(parameter, - parameter, - nullptr, - DataType::Type::kReference, - MemberOffset(42), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0), - inner_loop_body->GetLastInstruction()); + MakeIFieldSet( + inner_loop_body, parameter, parameter, DataType::Type::kReference, MemberOffset(42)); SideEffectsAnalysis side_effects(graph); side_effects.Run(); diff --git a/compiler/optimizing/induction_var_analysis_test.cc b/compiler/optimizing/induction_var_analysis_test.cc index 80c15371dc..2adf74ad64 100644 --- a/compiler/optimizing/induction_var_analysis_test.cc +++ b/compiler/optimizing/induction_var_analysis_test.cc @@ -92,9 +92,7 @@ class InductionVarAnalysisTest : public OptimizingUnitTest { graph_->SetExitBlock(exit_); // Provide entry and exit instructions. - parameter_ = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference, true); - entry_->AddInstruction(parameter_); + parameter_ = MakeParam(DataType::Type::kReference); constant0_ = graph_->GetIntConstant(0); constant1_ = graph_->GetIntConstant(1); constant2_ = graph_->GetIntConstant(2); @@ -102,23 +100,21 @@ class InductionVarAnalysisTest : public OptimizingUnitTest { constant100_ = graph_->GetIntConstant(100); constantm1_ = graph_->GetIntConstant(-1); float_constant0_ = graph_->GetFloatConstant(0.0f); - return_->AddInstruction(new (GetAllocator()) HReturnVoid()); - exit_->AddInstruction(new (GetAllocator()) HExit()); + MakeReturnVoid(return_); + MakeExit(exit_); // Provide loop instructions. for (int d = 0; d < n; d++) { - basic_[d] = new (GetAllocator()) HPhi(GetAllocator(), d, 0, DataType::Type::kInt32); - loop_preheader_[d]->AddInstruction(new (GetAllocator()) HGoto()); - loop_header_[d]->AddPhi(basic_[d]); - HInstruction* compare = new (GetAllocator()) HLessThan(basic_[d], constant100_); - loop_header_[d]->AddInstruction(compare); - loop_header_[d]->AddInstruction(new (GetAllocator()) HIf(compare)); - increment_[d] = new (GetAllocator()) HAdd(DataType::Type::kInt32, basic_[d], constant1_); - loop_body_[d]->AddInstruction(increment_[d]); - loop_body_[d]->AddInstruction(new (GetAllocator()) HGoto()); - - basic_[d]->AddInput(constant0_); - basic_[d]->AddInput(increment_[d]); + MakeGoto(loop_preheader_[d]); + + basic_[d] = MakePhi(loop_header_[d], {constant0_, /* placeholder */ constant0_}); + HInstruction* compare = MakeCondition<HLessThan>(loop_header_[d], basic_[d], constant100_); + MakeIf(loop_header_[d], compare); + + increment_[d] = MakeBinOp<HAdd>(loop_body_[d], DataType::Type::kInt32, basic_[d], constant1_); + MakeGoto(loop_body_[d]); + + basic_[d]->ReplaceInput(increment_[d], 1u); // Update back-edge input. } } @@ -136,7 +132,7 @@ class InductionVarAnalysisTest : public OptimizingUnitTest { cond->AddSuccessor(ifFalse); ifTrue->AddSuccessor(loop_body_[d]); ifFalse->AddSuccessor(loop_body_[d]); - cond->AddInstruction(new (GetAllocator()) HIf(parameter_)); + MakeIf(cond, parameter_); *ifT = ifTrue; *ifF = ifFalse; @@ -348,12 +344,10 @@ TEST_F(InductionVarAnalysisTest, FindTwoWayBasicInduction) { HPhi* k_body = BuildIf(0, &ifTrue, &ifFalse); // True-branch. - HInstruction* inc1 = new (GetAllocator()) HAdd(DataType::Type::kInt32, k_header, constant1_); - ifTrue->AddInstruction(inc1); + HInstruction* inc1 = MakeBinOp<HAdd>(ifTrue, DataType::Type::kInt32, k_header, constant1_); k_body->AddInput(inc1); // False-branch. - HInstruction* inc2 = new (GetAllocator()) HAdd(DataType::Type::kInt32, k_header, constant1_); - ifFalse->AddInstruction(inc2); + HInstruction* inc2 = MakeBinOp<HAdd>(ifFalse, DataType::Type::kInt32, k_header, constant1_); k_body->AddInput(inc2); // Merge over a phi. HInstruction* store = InsertArrayStore(k_body, 0); @@ -381,12 +375,10 @@ TEST_F(InductionVarAnalysisTest, FindTwoWayDerivedInduction) { HPhi* k = BuildIf(0, &ifTrue, &ifFalse); // True-branch. - HInstruction* inc1 = new (GetAllocator()) HAdd(DataType::Type::kInt32, basic_[0], constant1_); - ifTrue->AddInstruction(inc1); + HInstruction* inc1 = MakeBinOp<HAdd>(ifTrue, DataType::Type::kInt32, basic_[0], constant1_); k->AddInput(inc1); // False-branch. - HInstruction* inc2 = new (GetAllocator()) HAdd(DataType::Type::kInt32, basic_[0], constant1_); - ifFalse->AddInstruction(inc2); + HInstruction* inc2 = MakeBinOp<HAdd>(ifFalse, DataType::Type::kInt32, basic_[0], constant1_); k->AddInput(inc2); // Merge over a phi. HInstruction* store = InsertArrayStore(k, 0); diff --git a/compiler/optimizing/induction_var_range_test.cc b/compiler/optimizing/induction_var_range_test.cc index 40fb0d6092..bc970296ef 100644 --- a/compiler/optimizing/induction_var_range_test.cc +++ b/compiler/optimizing/induction_var_range_test.cc @@ -67,16 +67,8 @@ class InductionVarRangeTest : public OptimizingUnitTest { graph_->SetEntryBlock(entry_block_); graph_->SetExitBlock(exit_block_); // Two parameters. - x_ = new (GetAllocator()) HParameterValue(graph_->GetDexFile(), - dex::TypeIndex(0), - 0, - DataType::Type::kInt32); - entry_block_->AddInstruction(x_); - y_ = new (GetAllocator()) HParameterValue(graph_->GetDexFile(), - dex::TypeIndex(0), - 0, - DataType::Type::kInt32); - entry_block_->AddInstruction(y_); + x_ = MakeParam(DataType::Type::kInt32); + y_ = MakeParam(DataType::Type::kInt32); // Set arbitrary range analysis hint while testing private methods. SetHint(x_); } @@ -99,24 +91,21 @@ class InductionVarRangeTest : public OptimizingUnitTest { loop_body_->AddSuccessor(loop_header_); return_block->AddSuccessor(exit_block_); // Instructions. - loop_preheader_->AddInstruction(new (GetAllocator()) HGoto()); - HPhi* phi = new (GetAllocator()) HPhi(GetAllocator(), 0, 0, DataType::Type::kInt32); - loop_header_->AddPhi(phi); - phi->AddInput(graph_->GetIntConstant(lower)); // i = l + MakeGoto(loop_preheader_); + HInstruction* lower_const = graph_->GetIntConstant(lower); + HPhi* phi = MakePhi(loop_header_, {lower_const, /* placeholder */ lower_const}); // i = l if (stride > 0) { - condition_ = new (GetAllocator()) HLessThan(phi, upper); // i < u + condition_ = MakeCondition<HLessThan>(loop_header_, phi, upper); // i < u } else { - condition_ = new (GetAllocator()) HGreaterThan(phi, upper); // i > u + condition_ = MakeCondition<HGreaterThan>(loop_header_, phi, upper); // i > u } - loop_header_->AddInstruction(condition_); - loop_header_->AddInstruction(new (GetAllocator()) HIf(condition_)); - increment_ = - new (GetAllocator()) HAdd(DataType::Type::kInt32, phi, graph_->GetIntConstant(stride)); - loop_body_->AddInstruction(increment_); // i += s - phi->AddInput(increment_); - loop_body_->AddInstruction(new (GetAllocator()) HGoto()); - return_block->AddInstruction(new (GetAllocator()) HReturnVoid()); - exit_block_->AddInstruction(new (GetAllocator()) HExit()); + MakeIf(loop_header_, condition_); + increment_ = MakeBinOp<HAdd>( + loop_body_, DataType::Type::kInt32, phi, graph_->GetIntConstant(stride)); // i += s + phi->ReplaceInput(increment_, 1u); // Update back-edge input. + MakeGoto(loop_body_); + MakeReturnVoid(return_block); + MakeExit(exit_block_); } /** Constructs SSA and performs induction variable analysis. */ @@ -922,14 +911,8 @@ TEST_F(InductionVarRangeTest, MaxValue) { TEST_F(InductionVarRangeTest, ArrayLengthAndHints) { // We pass a bogus constant for the class to avoid mocking one. - HInstruction* new_array = new (GetAllocator()) HNewArray( - /* cls= */ x_, - /* length= */ x_, - /* dex_pc= */ 0, - /* component_size_shift= */ 0); - entry_block_->AddInstruction(new_array); - HInstruction* array_length = new (GetAllocator()) HArrayLength(new_array, 0); - entry_block_->AddInstruction(array_length); + HInstruction* new_array = MakeNewArray(entry_block_, /* cls= */ x_, /* length= */ x_); + HInstruction* array_length = MakeArrayLength(entry_block_, new_array); // With null hint: yields extreme constants. const int32_t max_value = std::numeric_limits<int32_t>::max(); SetHint(nullptr); @@ -946,18 +929,12 @@ TEST_F(InductionVarRangeTest, ArrayLengthAndHints) { } TEST_F(InductionVarRangeTest, AddOrSubAndConstant) { - HInstruction* add = new (GetAllocator()) - HAdd(DataType::Type::kInt32, x_, graph_->GetIntConstant(-1)); - HInstruction* alt = new (GetAllocator()) - HAdd(DataType::Type::kInt32, graph_->GetIntConstant(-1), x_); - HInstruction* sub = new (GetAllocator()) - HSub(DataType::Type::kInt32, x_, graph_->GetIntConstant(1)); - HInstruction* rev = new (GetAllocator()) - HSub(DataType::Type::kInt32, graph_->GetIntConstant(1), x_); - entry_block_->AddInstruction(add); - entry_block_->AddInstruction(alt); - entry_block_->AddInstruction(sub); - entry_block_->AddInstruction(rev); + HInstruction* plus1 = graph_->GetIntConstant(1); + HInstruction* minus1 = graph_->GetIntConstant(-1); + HInstruction* add = MakeBinOp<HAdd>(entry_block_, DataType::Type::kInt32, x_, minus1); + HInstruction* alt = MakeBinOp<HAdd>(entry_block_, DataType::Type::kInt32, minus1, x_); + HInstruction* sub = MakeBinOp<HSub>(entry_block_, DataType::Type::kInt32, x_, plus1); + HInstruction* rev = MakeBinOp<HSub>(entry_block_, DataType::Type::kInt32, plus1, x_); ExpectEqual(Value(x_, 1, -1), GetMin(CreateFetch(add), nullptr)); ExpectEqual(Value(x_, 1, -1), GetMax(CreateFetch(add), nullptr)); ExpectEqual(Value(x_, 1, -1), GetMin(CreateFetch(alt), nullptr)); diff --git a/compiler/optimizing/instruction_simplifier_test.cc b/compiler/optimizing/instruction_simplifier_test.cc index 9f47995cf5..3f49492938 100644 --- a/compiler/optimizing/instruction_simplifier_test.cc +++ b/compiler/optimizing/instruction_simplifier_test.cc @@ -103,18 +103,21 @@ class InstanceOfInstructionSimplifierTestGroup } } - std::pair<HLoadClass*, HLoadClass*> GetLoadClasses(VariableSizedHandleScope* vshs) { + std::pair<HLoadClass*, HLoadClass*> GetLoadClasses(HBasicBlock* block, + VariableSizedHandleScope* vshs) { InstanceOfKind kind = GetParam(); ScopedObjectAccess soa(Thread::Current()); // New inst always needs to have a valid rti since we dcheck that. - HLoadClass* new_inst = MakeClassLoad( - /* ti= */ std::nullopt, vshs->NewHandle<mirror::Class>(GetClassRoot<mirror::ClassExt>())); + HLoadClass* new_inst = MakeLoadClass( + block, + /* ti= */ std::nullopt, + vshs->NewHandle<mirror::Class>(GetClassRoot<mirror::ClassExt>())); new_inst->SetValidLoadedClassRTI(); if (kind == InstanceOfKind::kSelf) { return {new_inst, new_inst}; } if (kind == InstanceOfKind::kUnrelatedUnloaded) { - HLoadClass* target_class = MakeClassLoad(); + HLoadClass* target_class = MakeLoadClass(block); EXPECT_FALSE(target_class->GetLoadedClassRTI().IsValid()); return {new_inst, target_class}; } @@ -122,7 +125,8 @@ class InstanceOfInstructionSimplifierTestGroup // For simplicity we use class-roots as the types. The new-inst will always // be a ClassExt, unrelated-loaded will always be Throwable and super will // always be Object - HLoadClass* target_class = MakeClassLoad( + HLoadClass* target_class = MakeLoadClass( + block, /* ti= */ std::nullopt, vshs->NewHandle<mirror::Class>(kind == InstanceOfKind::kSupertype ? GetClassRoot<mirror::Object>() : @@ -165,8 +169,8 @@ TEST_P(InstanceOfInstructionSimplifierTestGroup, ExactClassInstanceOfOther) { EnsurePredecessorOrder(breturn, {left, right}); HInstruction* test_res = graph_->GetIntConstant(GetConstantResult() ? 1 : 0); - auto [new_inst_klass, target_klass] = GetLoadClasses(&vshs); - HInstruction* new_inst = MakeNewInstance(new_inst_klass); + auto [new_inst_klass, target_klass] = GetLoadClasses(entry, &vshs); + HInstruction* new_inst = MakeNewInstance(entry, new_inst_klass); new_inst->SetReferenceTypeInfo( ReferenceTypeInfo::Create(new_inst_klass->GetClass(), /*is_exact=*/true)); HInstanceOf* instance_of = new (GetAllocator()) HInstanceOf(new_inst, @@ -180,32 +184,23 @@ TEST_P(InstanceOfInstructionSimplifierTestGroup, ExactClassInstanceOfOther) { if (target_klass->GetLoadedClassRTI().IsValid()) { instance_of->SetValidTargetClassRTI(); } - HInstruction* if_inst = new (GetAllocator()) HIf(instance_of); - entry->AddInstruction(new_inst_klass); - if (new_inst_klass != target_klass) { - entry->AddInstruction(target_klass); - } - entry->AddInstruction(new_inst); entry->AddInstruction(instance_of); - entry->AddInstruction(if_inst); + HIf* if_inst = MakeIf(entry, instance_of); ManuallyBuildEnvFor(new_inst_klass, {}); if (new_inst_klass != target_klass) { target_klass->CopyEnvironmentFrom(new_inst_klass->GetEnvironment()); } new_inst->CopyEnvironmentFrom(new_inst_klass->GetEnvironment()); - HInstruction* goto_left = new (GetAllocator()) HGoto(); - left->AddInstruction(goto_left); + MakeGoto(left); - HInstruction* goto_right = new (GetAllocator()) HGoto(); - right->AddInstruction(goto_right); + MakeGoto(right); - HInstruction* read_bottom = MakeIFieldGet(new_inst, DataType::Type::kInt32, MemberOffset(32)); - HInstruction* return_exit = new (GetAllocator()) HReturn(read_bottom); - breturn->AddInstruction(read_bottom); - breturn->AddInstruction(return_exit); + HInstruction* read_bottom = + MakeIFieldGet(breturn, new_inst, DataType::Type::kInt32, MemberOffset(32)); + MakeReturn(breturn, read_bottom); - SetupExit(exit); + MakeExit(exit); PerformSimplification(blks); @@ -235,8 +230,8 @@ TEST_P(InstanceOfInstructionSimplifierTestGroup, ExactClassCheckCastOther) { GET_BLOCK(exit); #undef GET_BLOCK - auto [new_inst_klass, target_klass] = GetLoadClasses(&vshs); - HInstruction* new_inst = MakeNewInstance(new_inst_klass); + auto [new_inst_klass, target_klass] = GetLoadClasses(entry, &vshs); + HInstruction* new_inst = MakeNewInstance(entry, new_inst_klass); new_inst->SetReferenceTypeInfo( ReferenceTypeInfo::Create(new_inst_klass->GetClass(), /*is_exact=*/true)); HCheckCast* check_cast = new (GetAllocator()) HCheckCast(new_inst, @@ -250,21 +245,15 @@ TEST_P(InstanceOfInstructionSimplifierTestGroup, ExactClassCheckCastOther) { if (target_klass->GetLoadedClassRTI().IsValid()) { check_cast->SetValidTargetClassRTI(); } - HInstruction* entry_return = new (GetAllocator()) HReturn(new_inst); - entry->AddInstruction(new_inst_klass); - if (new_inst_klass != target_klass) { - entry->AddInstruction(target_klass); - } - entry->AddInstruction(new_inst); entry->AddInstruction(check_cast); - entry->AddInstruction(entry_return); + MakeReturn(entry, new_inst); ManuallyBuildEnvFor(new_inst_klass, {}); if (new_inst_klass != target_klass) { target_klass->CopyEnvironmentFrom(new_inst_klass->GetEnvironment()); } new_inst->CopyEnvironmentFrom(new_inst_klass->GetEnvironment()); - SetupExit(exit); + MakeExit(exit); PerformSimplification(blks); diff --git a/compiler/optimizing/licm_test.cc b/compiler/optimizing/licm_test.cc index f8481099f4..58d90c3168 100644 --- a/compiler/optimizing/licm_test.cc +++ b/compiler/optimizing/licm_test.cc @@ -74,18 +74,14 @@ class LICMTest : public OptimizingUnitTest { return_->AddSuccessor(exit_); // Provide boiler-plate instructions. - parameter_ = new (GetAllocator()) HParameterValue(graph_->GetDexFile(), - dex::TypeIndex(0), - 0, - DataType::Type::kReference); - entry_->AddInstruction(parameter_); + parameter_ = MakeParam(DataType::Type::kReference); int_constant_ = graph_->GetIntConstant(42); float_constant_ = graph_->GetFloatConstant(42.0f); - loop_preheader_->AddInstruction(new (GetAllocator()) HGoto()); - loop_header_->AddInstruction(new (GetAllocator()) HIf(parameter_)); - loop_body_->AddInstruction(new (GetAllocator()) HGoto()); - return_->AddInstruction(new (GetAllocator()) HReturnVoid()); - exit_->AddInstruction(new (GetAllocator()) HExit()); + MakeGoto(loop_preheader_); + MakeIf(loop_header_, parameter_); + MakeGoto(loop_body_); + MakeReturnVoid(return_); + MakeExit(exit_); } // Performs LICM optimizations (after proper set up). @@ -120,20 +116,10 @@ TEST_F(LICMTest, FieldHoisting) { BuildLoop(); // Populate the loop with instructions: set/get field with different types. - HInstruction* get_field = new (GetAllocator()) HInstanceFieldGet(parameter_, - nullptr, - DataType::Type::kInt64, - MemberOffset(10), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph_->GetDexFile(), - 0); - loop_body_->InsertInstructionBefore(get_field, loop_body_->GetLastInstruction()); - HInstruction* set_field = new (GetAllocator()) HInstanceFieldSet( - parameter_, int_constant_, nullptr, DataType::Type::kInt32, MemberOffset(20), - false, kUnknownFieldIndex, kUnknownClassDefIndex, graph_->GetDexFile(), 0); - loop_body_->InsertInstructionBefore(set_field, loop_body_->GetLastInstruction()); + HInstruction* get_field = + MakeIFieldGet(loop_body_, parameter_, DataType::Type::kInt64, MemberOffset(10)); + HInstruction* set_field = + MakeIFieldSet(loop_body_, parameter_, int_constant_, DataType::Type::kInt32, MemberOffset(20)); EXPECT_EQ(get_field->GetBlock(), loop_body_); EXPECT_EQ(set_field->GetBlock(), loop_body_); @@ -147,27 +133,9 @@ TEST_F(LICMTest, NoFieldHoisting) { // Populate the loop with instructions: set/get field with same types. ScopedNullHandle<mirror::DexCache> dex_cache; - HInstruction* get_field = new (GetAllocator()) HInstanceFieldGet(parameter_, - nullptr, - DataType::Type::kInt64, - MemberOffset(10), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph_->GetDexFile(), - 0); - loop_body_->InsertInstructionBefore(get_field, loop_body_->GetLastInstruction()); - HInstruction* set_field = new (GetAllocator()) HInstanceFieldSet(parameter_, - get_field, - nullptr, - DataType::Type::kInt64, - MemberOffset(10), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph_->GetDexFile(), - 0); - loop_body_->InsertInstructionBefore(set_field, loop_body_->GetLastInstruction()); + HInstruction* get_field = + MakeIFieldGet(loop_body_, parameter_, DataType::Type::kInt64, MemberOffset(10)); + HInstruction* set_field = MakeIFieldSet(loop_body_, parameter_, get_field, MemberOffset(10)); EXPECT_EQ(get_field->GetBlock(), loop_body_); EXPECT_EQ(set_field->GetBlock(), loop_body_); @@ -180,12 +148,10 @@ TEST_F(LICMTest, ArrayHoisting) { BuildLoop(); // Populate the loop with instructions: set/get array with different types. - HInstruction* get_array = new (GetAllocator()) HArrayGet( - parameter_, int_constant_, DataType::Type::kInt32, 0); - loop_body_->InsertInstructionBefore(get_array, loop_body_->GetLastInstruction()); - HInstruction* set_array = new (GetAllocator()) HArraySet( - parameter_, int_constant_, float_constant_, DataType::Type::kFloat32, 0); - loop_body_->InsertInstructionBefore(set_array, loop_body_->GetLastInstruction()); + HInstruction* get_array = + MakeArrayGet(loop_body_, parameter_, int_constant_, DataType::Type::kInt32); + HInstruction* set_array = MakeArraySet( + loop_body_, parameter_, int_constant_, float_constant_, DataType::Type::kFloat32); EXPECT_EQ(get_array->GetBlock(), loop_body_); EXPECT_EQ(set_array->GetBlock(), loop_body_); diff --git a/compiler/optimizing/load_store_analysis_test.cc b/compiler/optimizing/load_store_analysis_test.cc index 90185579e3..09a336323c 100644 --- a/compiler/optimizing/load_store_analysis_test.cc +++ b/compiler/optimizing/load_store_analysis_test.cc @@ -67,25 +67,15 @@ TEST_F(LoadStoreAnalysisTest, ArrayHeapLocations) { // array_get2 ArrayGet [array, c2] // array_set1 ArraySet [array, c1, c3] // array_set2 ArraySet [array, index, c3] - HInstruction* array = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); - HInstruction* index = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(1), 1, DataType::Type::kInt32); + HInstruction* array = MakeParam(DataType::Type::kReference); + HInstruction* index = MakeParam(DataType::Type::kInt32); HInstruction* c1 = graph_->GetIntConstant(1); HInstruction* c2 = graph_->GetIntConstant(2); HInstruction* c3 = graph_->GetIntConstant(3); - HInstruction* array_get1 = new (GetAllocator()) HArrayGet(array, c1, DataType::Type::kInt32, 0); - HInstruction* array_get2 = new (GetAllocator()) HArrayGet(array, c2, DataType::Type::kInt32, 0); - HInstruction* array_set1 = - new (GetAllocator()) HArraySet(array, c1, c3, DataType::Type::kInt32, 0); - HInstruction* array_set2 = - new (GetAllocator()) HArraySet(array, index, c3, DataType::Type::kInt32, 0); - entry->AddInstruction(array); - entry->AddInstruction(index); - entry->AddInstruction(array_get1); - entry->AddInstruction(array_get2); - entry->AddInstruction(array_set1); - entry->AddInstruction(array_set2); + HInstruction* array_get1 = MakeArrayGet(entry, array, c1, DataType::Type::kInt32); + HInstruction* array_get2 = MakeArrayGet(entry, array, c2, DataType::Type::kInt32); + HInstruction* array_set1 = MakeArraySet(entry, array, c1, c3, DataType::Type::kInt32); + HInstruction* array_set2 = MakeArraySet(entry, array, index, c3, DataType::Type::kInt32); // Test HeapLocationCollector initialization. // Should be no heap locations, no operations on the heap. @@ -149,42 +139,12 @@ TEST_F(LoadStoreAnalysisTest, FieldHeapLocations) { // get_field20 InstanceFieldGet [object, 20] HInstruction* c1 = graph_->GetIntConstant(1); - HInstruction* object = new (GetAllocator()) HParameterValue(graph_->GetDexFile(), - dex::TypeIndex(0), - 0, - DataType::Type::kReference); - HInstanceFieldSet* set_field10 = new (GetAllocator()) HInstanceFieldSet(object, - c1, - nullptr, - DataType::Type::kInt32, - MemberOffset(32), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph_->GetDexFile(), - 0); - HInstanceFieldGet* get_field10 = new (GetAllocator()) HInstanceFieldGet(object, - nullptr, - DataType::Type::kInt32, - MemberOffset(32), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph_->GetDexFile(), - 0); - HInstanceFieldGet* get_field20 = new (GetAllocator()) HInstanceFieldGet(object, - nullptr, - DataType::Type::kInt32, - MemberOffset(20), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph_->GetDexFile(), - 0); - entry->AddInstruction(object); - entry->AddInstruction(set_field10); - entry->AddInstruction(get_field10); - entry->AddInstruction(get_field20); + HInstruction* object = MakeParam(DataType::Type::kReference); + HInstanceFieldSet* set_field10 = MakeIFieldSet(entry, object, c1, MemberOffset(10)); + HInstanceFieldGet* get_field10 = + MakeIFieldGet(entry, object, DataType::Type::kInt32, MemberOffset(10)); + HInstanceFieldGet* get_field20 = + MakeIFieldGet(entry, object, DataType::Type::kInt32, MemberOffset(20)); // Test HeapLocationCollector initialization. // Should be no heap locations, no operations on the heap. @@ -222,53 +182,35 @@ TEST_F(LoadStoreAnalysisTest, ArrayIndexAliasingTest) { SetupFromAdjacencyList("entry", "exit", {{"entry", "body"}, {"body", "exit"}})); HBasicBlock* body = blks.Get("body"); - HInstruction* array = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); - HInstruction* index = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(1), 1, DataType::Type::kInt32); + HInstruction* array = MakeParam(DataType::Type::kReference); + HInstruction* index = MakeParam(DataType::Type::kInt32); HInstruction* c0 = graph_->GetIntConstant(0); HInstruction* c1 = graph_->GetIntConstant(1); HInstruction* c_neg1 = graph_->GetIntConstant(-1); - HInstruction* add0 = new (GetAllocator()) HAdd(DataType::Type::kInt32, index, c0); - HInstruction* add1 = new (GetAllocator()) HAdd(DataType::Type::kInt32, index, c1); - HInstruction* sub0 = new (GetAllocator()) HSub(DataType::Type::kInt32, index, c0); - HInstruction* sub1 = new (GetAllocator()) HSub(DataType::Type::kInt32, index, c1); - HInstruction* sub_neg1 = new (GetAllocator()) HSub(DataType::Type::kInt32, index, c_neg1); - HInstruction* rev_sub1 = new (GetAllocator()) HSub(DataType::Type::kInt32, c1, index); - HInstruction* arr_set1 = new (GetAllocator()) HArraySet(array, c0, c0, DataType::Type::kInt32, 0); - HInstruction* arr_set2 = new (GetAllocator()) HArraySet(array, c1, c0, DataType::Type::kInt32, 0); - HInstruction* arr_set3 = - new (GetAllocator()) HArraySet(array, add0, c0, DataType::Type::kInt32, 0); - HInstruction* arr_set4 = - new (GetAllocator()) HArraySet(array, add1, c0, DataType::Type::kInt32, 0); - HInstruction* arr_set5 = - new (GetAllocator()) HArraySet(array, sub0, c0, DataType::Type::kInt32, 0); - HInstruction* arr_set6 = - new (GetAllocator()) HArraySet(array, sub1, c0, DataType::Type::kInt32, 0); - HInstruction* arr_set7 = - new (GetAllocator()) HArraySet(array, rev_sub1, c0, DataType::Type::kInt32, 0); - HInstruction* arr_set8 = - new (GetAllocator()) HArraySet(array, sub_neg1, c0, DataType::Type::kInt32, 0); - - body->AddInstruction(array); - body->AddInstruction(index); - body->AddInstruction(add0); - body->AddInstruction(add1); - body->AddInstruction(sub0); - body->AddInstruction(sub1); - body->AddInstruction(sub_neg1); - body->AddInstruction(rev_sub1); - - body->AddInstruction(arr_set1); // array[0] = c0 - body->AddInstruction(arr_set2); // array[1] = c0 - body->AddInstruction(arr_set3); // array[i+0] = c0 - body->AddInstruction(arr_set4); // array[i+1] = c0 - body->AddInstruction(arr_set5); // array[i-0] = c0 - body->AddInstruction(arr_set6); // array[i-1] = c0 - body->AddInstruction(arr_set7); // array[1-i] = c0 - body->AddInstruction(arr_set8); // array[i-(-1)] = c0 - - body->AddInstruction(new (GetAllocator()) HReturnVoid()); + HInstruction* add0 = MakeBinOp<HAdd>(body, DataType::Type::kInt32, index, c0); + HInstruction* add1 = MakeBinOp<HAdd>(body, DataType::Type::kInt32, index, c1); + HInstruction* sub0 = MakeBinOp<HSub>(body, DataType::Type::kInt32, index, c0); + HInstruction* sub1 = MakeBinOp<HSub>(body, DataType::Type::kInt32, index, c1); + HInstruction* sub_neg1 = MakeBinOp<HSub>(body, DataType::Type::kInt32, index, c_neg1); + HInstruction* rev_sub1 = MakeBinOp<HSub>(body, DataType::Type::kInt32, c1, index); + // array[0] = c0 + HInstruction* arr_set1 = MakeArraySet(body, array, c0, c0, DataType::Type::kInt32); + // array[1] = c0 + HInstruction* arr_set2 = MakeArraySet(body, array, c1, c0, DataType::Type::kInt32); + // array[i+0] = c0 + HInstruction* arr_set3 = MakeArraySet(body, array, add0, c0, DataType::Type::kInt32); + // array[i+1] = c0 + HInstruction* arr_set4 = MakeArraySet(body, array, add1, c0, DataType::Type::kInt32); + // array[i-0] = c0 + HInstruction* arr_set5 = MakeArraySet(body, array, sub0, c0, DataType::Type::kInt32); + // array[i-1] = c0 + HInstruction* arr_set6 = MakeArraySet(body, array, sub1, c0, DataType::Type::kInt32); + // array[1-i] = c0 + HInstruction* arr_set7 = MakeArraySet(body, array, rev_sub1, c0, DataType::Type::kInt32); + // array[i-(-1)] = c0 + HInstruction* arr_set8 = MakeArraySet(body, array, sub_neg1, c0, DataType::Type::kInt32); + + MakeReturnVoid(body); ScopedArenaAllocator allocator(graph_->GetArenaStack()); LoadStoreAnalysis lsa(graph_, nullptr, &allocator); @@ -318,125 +260,40 @@ TEST_F(LoadStoreAnalysisTest, ArrayAliasingTest) { graph_->SetEntryBlock(entry); graph_->BuildDominatorTree(); - HInstruction* array = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); - HInstruction* index = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(1), 1, DataType::Type::kInt32); + HInstruction* array = MakeParam(DataType::Type::kReference); + HInstruction* index = MakeParam(DataType::Type::kInt32); HInstruction* c0 = graph_->GetIntConstant(0); HInstruction* c1 = graph_->GetIntConstant(1); HInstruction* c6 = graph_->GetIntConstant(6); HInstruction* c8 = graph_->GetIntConstant(8); - HInstruction* arr_set_0 = new (GetAllocator()) HArraySet(array, - c0, - c0, - DataType::Type::kInt32, - 0); - HInstruction* arr_set_1 = new (GetAllocator()) HArraySet(array, - c1, - c0, - DataType::Type::kInt32, - 0); - HInstruction* arr_set_i = new (GetAllocator()) HArraySet(array, - index, - c0, - DataType::Type::kInt32, - 0); + HInstruction* arr_set_0 = MakeArraySet(entry, array, c0, c0, DataType::Type::kInt32); + HInstruction* arr_set_1 = MakeArraySet(entry, array, c1, c0, DataType::Type::kInt32); + HInstruction* arr_set_i = MakeArraySet(entry, array, index, c0, DataType::Type::kInt32); HVecOperation* v1 = new (GetAllocator()) HVecReplicateScalar(GetAllocator(), c1, DataType::Type::kInt32, 4, kNoDexPc); + entry->AddInstruction(v1); HVecOperation* v2 = new (GetAllocator()) HVecReplicateScalar(GetAllocator(), c1, DataType::Type::kInt32, 2, kNoDexPc); - HInstruction* i_add6 = new (GetAllocator()) HAdd(DataType::Type::kInt32, index, c6); - HInstruction* i_add8 = new (GetAllocator()) HAdd(DataType::Type::kInt32, index, c8); - - HInstruction* vstore_0 = new (GetAllocator()) HVecStore( - GetAllocator(), - array, - c0, - v1, - DataType::Type::kInt32, - SideEffects::ArrayWriteOfType(DataType::Type::kInt32), - 4, - kNoDexPc); - HInstruction* vstore_1 = new (GetAllocator()) HVecStore( - GetAllocator(), - array, - c1, - v1, - DataType::Type::kInt32, - SideEffects::ArrayWriteOfType(DataType::Type::kInt32), - 4, - kNoDexPc); - HInstruction* vstore_8 = new (GetAllocator()) HVecStore( - GetAllocator(), - array, - c8, - v1, - DataType::Type::kInt32, - SideEffects::ArrayWriteOfType(DataType::Type::kInt32), - 4, - kNoDexPc); - HInstruction* vstore_i = new (GetAllocator()) HVecStore( - GetAllocator(), - array, - index, - v1, - DataType::Type::kInt32, - SideEffects::ArrayWriteOfType(DataType::Type::kInt32), - 4, - kNoDexPc); - HInstruction* vstore_i_add6 = new (GetAllocator()) HVecStore( - GetAllocator(), - array, - i_add6, - v1, - DataType::Type::kInt32, - SideEffects::ArrayWriteOfType(DataType::Type::kInt32), - 4, - kNoDexPc); - HInstruction* vstore_i_add8 = new (GetAllocator()) HVecStore( - GetAllocator(), - array, - i_add8, - v1, - DataType::Type::kInt32, - SideEffects::ArrayWriteOfType(DataType::Type::kInt32), - 4, - kNoDexPc); - HInstruction* vstore_i_add6_vlen2 = new (GetAllocator()) HVecStore( - GetAllocator(), - array, - i_add6, - v2, - DataType::Type::kInt32, - SideEffects::ArrayWriteOfType(DataType::Type::kInt32), - 2, - kNoDexPc); - - entry->AddInstruction(array); - entry->AddInstruction(index); - - entry->AddInstruction(arr_set_0); - entry->AddInstruction(arr_set_1); - entry->AddInstruction(arr_set_i); - entry->AddInstruction(v1); entry->AddInstruction(v2); - entry->AddInstruction(i_add6); - entry->AddInstruction(i_add8); - entry->AddInstruction(vstore_0); - entry->AddInstruction(vstore_1); - entry->AddInstruction(vstore_8); - entry->AddInstruction(vstore_i); - entry->AddInstruction(vstore_i_add6); - entry->AddInstruction(vstore_i_add8); - entry->AddInstruction(vstore_i_add6_vlen2); + HInstruction* i_add6 = MakeBinOp<HAdd>(entry, DataType::Type::kInt32, index, c6); + HInstruction* i_add8 = MakeBinOp<HAdd>(entry, DataType::Type::kInt32, index, c8); + + HInstruction* vstore_0 = MakeVecStore(entry, array, c0, v1, DataType::Type::kInt32); + HInstruction* vstore_1 = MakeVecStore(entry, array, c1, v1, DataType::Type::kInt32); + HInstruction* vstore_8 = MakeVecStore(entry, array, c8, v1, DataType::Type::kInt32); + HInstruction* vstore_i = MakeVecStore(entry, array, index, v1, DataType::Type::kInt32); + HInstruction* vstore_i_add6 = MakeVecStore(entry, array, i_add6, v1, DataType::Type::kInt32); + HInstruction* vstore_i_add8 = MakeVecStore(entry, array, i_add8, v1, DataType::Type::kInt32); + HInstruction* vstore_i_add6_vlen2 = + MakeVecStore(entry, array, i_add6, v2, DataType::Type::kInt32, /*vector_lengt=*/ 2); ScopedArenaAllocator allocator(graph_->GetArenaStack()); LoadStoreAnalysis lsa(graph_, nullptr, &allocator); @@ -530,10 +387,8 @@ TEST_F(LoadStoreAnalysisTest, ArrayIndexCalculationOverflowTest) { graph_->SetEntryBlock(entry); graph_->BuildDominatorTree(); - HInstruction* array = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); - HInstruction* index = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(1), 1, DataType::Type::kInt32); + HInstruction* array = MakeParam(DataType::Type::kReference); + HInstruction* index = MakeParam(DataType::Type::kInt32); HInstruction* c0 = graph_->GetIntConstant(0); HInstruction* c_0x80000000 = graph_->GetIntConstant(0x80000000); @@ -543,60 +398,33 @@ TEST_F(LoadStoreAnalysisTest, ArrayIndexCalculationOverflowTest) { HInstruction* c_0x80000001 = graph_->GetIntConstant(0x80000001); // `index+0x80000000` and `index-0x80000000` array indices MAY alias. - HInstruction* add_0x80000000 = new (GetAllocator()) HAdd( - DataType::Type::kInt32, index, c_0x80000000); - HInstruction* sub_0x80000000 = new (GetAllocator()) HSub( - DataType::Type::kInt32, index, c_0x80000000); - HInstruction* arr_set_1 = new (GetAllocator()) HArraySet( - array, add_0x80000000, c0, DataType::Type::kInt32, 0); - HInstruction* arr_set_2 = new (GetAllocator()) HArraySet( - array, sub_0x80000000, c0, DataType::Type::kInt32, 0); + HInstruction* add_0x80000000 = + MakeBinOp<HAdd>(entry, DataType::Type::kInt32, index, c_0x80000000); + HInstruction* sub_0x80000000 = + MakeBinOp<HSub>(entry, DataType::Type::kInt32, index, c_0x80000000); + HInstruction* arr_set_1 = MakeArraySet(entry, array, add_0x80000000, c0, DataType::Type::kInt32); + HInstruction* arr_set_2 = MakeArraySet(entry, array, sub_0x80000000, c0, DataType::Type::kInt32); // `index+0x10` and `index-0xFFFFFFF0` array indices MAY alias. - HInstruction* add_0x10 = new (GetAllocator()) HAdd(DataType::Type::kInt32, index, c_0x10); - HInstruction* sub_0xFFFFFFF0 = new (GetAllocator()) HSub( - DataType::Type::kInt32, index, c_0xFFFFFFF0); - HInstruction* arr_set_3 = new (GetAllocator()) HArraySet( - array, add_0x10, c0, DataType::Type::kInt32, 0); - HInstruction* arr_set_4 = new (GetAllocator()) HArraySet( - array, sub_0xFFFFFFF0, c0, DataType::Type::kInt32, 0); + HInstruction* add_0x10 = MakeBinOp<HAdd>(entry, DataType::Type::kInt32, index, c_0x10); + HInstruction* sub_0xFFFFFFF0 = + MakeBinOp<HSub>(entry, DataType::Type::kInt32, index, c_0xFFFFFFF0); + HInstruction* arr_set_3 = MakeArraySet(entry, array, add_0x10, c0, DataType::Type::kInt32); + HInstruction* arr_set_4 = MakeArraySet(entry, array, sub_0xFFFFFFF0, c0, DataType::Type::kInt32); // `index+0x7FFFFFFF` and `index-0x80000001` array indices MAY alias. - HInstruction* add_0x7FFFFFFF = new (GetAllocator()) HAdd( - DataType::Type::kInt32, index, c_0x7FFFFFFF); - HInstruction* sub_0x80000001 = new (GetAllocator()) HSub( - DataType::Type::kInt32, index, c_0x80000001); - HInstruction* arr_set_5 = new (GetAllocator()) HArraySet( - array, add_0x7FFFFFFF, c0, DataType::Type::kInt32, 0); - HInstruction* arr_set_6 = new (GetAllocator()) HArraySet( - array, sub_0x80000001, c0, DataType::Type::kInt32, 0); + HInstruction* add_0x7FFFFFFF = + MakeBinOp<HAdd>(entry, DataType::Type::kInt32, index, c_0x7FFFFFFF); + HInstruction* sub_0x80000001 = + MakeBinOp<HSub>(entry, DataType::Type::kInt32, index, c_0x80000001); + HInstruction* arr_set_5 = MakeArraySet(entry, array, add_0x7FFFFFFF, c0, DataType::Type::kInt32); + HInstruction* arr_set_6 = MakeArraySet(entry, array, sub_0x80000001, c0, DataType::Type::kInt32); // `index+0` and `index-0` array indices MAY alias. - HInstruction* add_0 = new (GetAllocator()) HAdd(DataType::Type::kInt32, index, c0); - HInstruction* sub_0 = new (GetAllocator()) HSub(DataType::Type::kInt32, index, c0); - HInstruction* arr_set_7 = new (GetAllocator()) HArraySet( - array, add_0, c0, DataType::Type::kInt32, 0); - HInstruction* arr_set_8 = new (GetAllocator()) HArraySet( - array, sub_0, c0, DataType::Type::kInt32, 0); - - entry->AddInstruction(array); - entry->AddInstruction(index); - entry->AddInstruction(add_0x80000000); - entry->AddInstruction(sub_0x80000000); - entry->AddInstruction(add_0x10); - entry->AddInstruction(sub_0xFFFFFFF0); - entry->AddInstruction(add_0x7FFFFFFF); - entry->AddInstruction(sub_0x80000001); - entry->AddInstruction(add_0); - entry->AddInstruction(sub_0); - entry->AddInstruction(arr_set_1); - entry->AddInstruction(arr_set_2); - entry->AddInstruction(arr_set_3); - entry->AddInstruction(arr_set_4); - entry->AddInstruction(arr_set_5); - entry->AddInstruction(arr_set_6); - entry->AddInstruction(arr_set_7); - entry->AddInstruction(arr_set_8); + HInstruction* add_0 = MakeBinOp<HAdd>(entry, DataType::Type::kInt32, index, c0); + HInstruction* sub_0 = MakeBinOp<HSub>(entry, DataType::Type::kInt32, index, c0); + HInstruction* arr_set_7 = MakeArraySet(entry, array, add_0, c0, DataType::Type::kInt32); + HInstruction* arr_set_8 = MakeArraySet(entry, array, sub_0, c0, DataType::Type::kInt32); ScopedArenaAllocator allocator(graph_->GetArenaStack()); LoadStoreAnalysis lsa(graph_, nullptr, &allocator); @@ -654,40 +482,19 @@ TEST_F(LoadStoreAnalysisTest, TestHuntOriginalRef) { // ParameterValue --> BoundType --> NullCheck --> ArrayGet // ParameterValue --> BoundType --> NullCheck --> IntermediateAddress --> ArrayGet HInstruction* c1 = graph_->GetIntConstant(1); - HInstruction* array = new (GetAllocator()) HParameterValue(graph_->GetDexFile(), - dex::TypeIndex(0), - 0, - DataType::Type::kReference); - HInstruction* array_get1 = new (GetAllocator()) HArrayGet(array, - c1, - DataType::Type::kInt32, - 0); + HInstruction* array = MakeParam(DataType::Type::kReference); + HInstruction* array_get1 = MakeArrayGet(entry, array, c1, DataType::Type::kInt32); HInstruction* bound_type = new (GetAllocator()) HBoundType(array); - HInstruction* array_get2 = new (GetAllocator()) HArrayGet(bound_type, - c1, - DataType::Type::kInt32, - 0); + entry->AddInstruction(bound_type); + HInstruction* array_get2 = MakeArrayGet(entry, bound_type, c1, DataType::Type::kInt32); - HInstruction* null_check = new (GetAllocator()) HNullCheck(bound_type, 0); - HInstruction* array_get3 = new (GetAllocator()) HArrayGet(null_check, - c1, - DataType::Type::kInt32, - 0); + HInstruction* null_check = MakeNullCheck(entry, bound_type); + HInstruction* array_get3 = MakeArrayGet(entry, null_check, c1, DataType::Type::kInt32); HInstruction* inter_addr = new (GetAllocator()) HIntermediateAddress(null_check, c1, 0); - HInstruction* array_get4 = new (GetAllocator()) HArrayGet(inter_addr, - c1, - DataType::Type::kInt32, - 0); - entry->AddInstruction(array); - entry->AddInstruction(array_get1); - entry->AddInstruction(bound_type); - entry->AddInstruction(array_get2); - entry->AddInstruction(null_check); - entry->AddInstruction(array_get3); entry->AddInstruction(inter_addr); - entry->AddInstruction(array_get4); + HInstruction* array_get4 = MakeArrayGet(entry, inter_addr, c1, DataType::Type::kInt32); ScopedArenaAllocator allocator(graph_->GetArenaStack()); HeapLocationCollector heap_location_collector(graph_, &allocator); @@ -731,84 +538,21 @@ TEST_F(LoadStoreAnalysisTest, TotalEscape) { HBasicBlock* right = blks.Get("right"); HBasicBlock* exit = blks.Get("exit"); - HInstruction* bool_value = new (GetAllocator()) - HParameterValue(graph_->GetDexFile(), dex::TypeIndex(1), 1, DataType::Type::kBool); + HInstruction* bool_value = MakeParam(DataType::Type::kBool); HInstruction* c0 = graph_->GetIntConstant(0); - HInstruction* cls = new (GetAllocator()) HLoadClass(graph_->GetCurrentMethod(), - dex::TypeIndex(10), - graph_->GetDexFile(), - ScopedNullHandle<mirror::Class>(), - false, - 0, - false); - HInstruction* new_inst = - new (GetAllocator()) HNewInstance(cls, - 0, - dex::TypeIndex(10), - graph_->GetDexFile(), - false, - QuickEntrypointEnum::kQuickAllocObjectInitialized); - HInstruction* if_inst = new (GetAllocator()) HIf(bool_value); - entry->AddInstruction(bool_value); - entry->AddInstruction(cls); - entry->AddInstruction(new_inst); - entry->AddInstruction(if_inst); - - HInstruction* call_left = new (GetAllocator()) - HInvokeStaticOrDirect(GetAllocator(), - 1, - DataType::Type::kVoid, - 0, - { nullptr, 0 }, - nullptr, - {}, - InvokeType::kStatic, - { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, - !graph_->IsDebuggable()); - HInstruction* goto_left = new (GetAllocator()) HGoto(); - call_left->SetRawInputAt(0, new_inst); - left->AddInstruction(call_left); - left->AddInstruction(goto_left); - - HInstruction* call_right = new (GetAllocator()) - HInvokeStaticOrDirect(GetAllocator(), - 1, - DataType::Type::kVoid, - 0, - { nullptr, 0 }, - nullptr, - {}, - InvokeType::kStatic, - { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, - !graph_->IsDebuggable()); - HInstruction* write_right = new (GetAllocator()) HInstanceFieldSet(new_inst, - c0, - nullptr, - DataType::Type::kInt32, - MemberOffset(32), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* goto_right = new (GetAllocator()) HGoto(); - call_right->SetRawInputAt(0, new_inst); - right->AddInstruction(write_right); - right->AddInstruction(call_right); - right->AddInstruction(goto_right); - - HInstruction* read_final = new (GetAllocator()) HInstanceFieldGet(new_inst, - nullptr, - DataType::Type::kInt32, - MemberOffset(32), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - exit->AddInstruction(read_final); + HInstruction* cls = MakeLoadClass(entry); + HInstruction* new_inst = MakeNewInstance(entry, cls); + MakeIf(entry, bool_value); + + HInstruction* call_left = MakeInvokeStatic(left, DataType::Type::kVoid, {new_inst}); + MakeGoto(left); + + HInstruction* call_right = MakeInvokeStatic(right, DataType::Type::kVoid, {new_inst}); + HInstruction* write_right = MakeIFieldSet(right, new_inst, c0, MemberOffset(32)); + MakeGoto(right); + + HInstruction* read_final = + MakeIFieldGet(exit, new_inst, DataType::Type::kInt32, MemberOffset(32)); ScopedArenaAllocator allocator(graph_->GetArenaStack()); LoadStoreAnalysis lsa(graph_, nullptr, &allocator); @@ -831,39 +575,12 @@ TEST_F(LoadStoreAnalysisTest, TotalEscape2) { HBasicBlock* exit = blks.Get("exit"); HInstruction* c0 = graph_->GetIntConstant(0); - HInstruction* cls = new (GetAllocator()) HLoadClass(graph_->GetCurrentMethod(), - dex::TypeIndex(10), - graph_->GetDexFile(), - ScopedNullHandle<mirror::Class>(), - false, - 0, - false); - HInstruction* new_inst = - new (GetAllocator()) HNewInstance(cls, - 0, - dex::TypeIndex(10), - graph_->GetDexFile(), - false, - QuickEntrypointEnum::kQuickAllocObjectInitialized); - - HInstruction* write_start = new (GetAllocator()) HInstanceFieldSet(new_inst, - c0, - nullptr, - DataType::Type::kInt32, - MemberOffset(32), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* goto_inst = new (GetAllocator()) HGoto(); - entry->AddInstruction(cls); - entry->AddInstruction(new_inst); - entry->AddInstruction(write_start); - entry->AddInstruction(goto_inst); - - HInstruction* return_final = new (GetAllocator()) HReturn(new_inst); - exit->AddInstruction(return_final); + HInstruction* cls = MakeLoadClass(entry); + HInstruction* new_inst = MakeNewInstance(entry, cls); + HInstruction* write_start = MakeIFieldSet(entry, new_inst, c0, MemberOffset(32)); + MakeGoto(entry); + + MakeReturn(exit, new_inst); ScopedArenaAllocator allocator(graph_->GetArenaStack()); LoadStoreAnalysis lsa(graph_, nullptr, &allocator); @@ -914,131 +631,33 @@ TEST_F(LoadStoreAnalysisTest, DoubleDiamondEscape) { HBasicBlock* low_right = blks.Get("low_right"); HBasicBlock* exit = blks.Get("exit"); - HInstruction* bool_value1 = new (GetAllocator()) - HParameterValue(graph_->GetDexFile(), dex::TypeIndex(1), 1, DataType::Type::kBool); - HInstruction* bool_value2 = new (GetAllocator()) - HParameterValue(graph_->GetDexFile(), dex::TypeIndex(1), 2, DataType::Type::kBool); + HInstruction* bool_value1 = MakeParam(DataType::Type::kBool); + HInstruction* bool_value2 = MakeParam(DataType::Type::kBool); HInstruction* c0 = graph_->GetIntConstant(0); HInstruction* c2 = graph_->GetIntConstant(2); - HInstruction* cls = new (GetAllocator()) HLoadClass(graph_->GetCurrentMethod(), - dex::TypeIndex(10), - graph_->GetDexFile(), - ScopedNullHandle<mirror::Class>(), - false, - 0, - false); - HInstruction* new_inst = - new (GetAllocator()) HNewInstance(cls, - 0, - dex::TypeIndex(10), - graph_->GetDexFile(), - false, - QuickEntrypointEnum::kQuickAllocObjectInitialized); - HInstruction* if_inst = new (GetAllocator()) HIf(bool_value1); - entry->AddInstruction(bool_value1); - entry->AddInstruction(bool_value2); - entry->AddInstruction(cls); - entry->AddInstruction(new_inst); - entry->AddInstruction(if_inst); - - HInstruction* call_left = new (GetAllocator()) - HInvokeStaticOrDirect(GetAllocator(), - 1, - DataType::Type::kVoid, - 0, - { nullptr, 0 }, - nullptr, - {}, - InvokeType::kStatic, - { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, - !graph_->IsDebuggable()); - HInstruction* goto_left = new (GetAllocator()) HGoto(); - call_left->SetRawInputAt(0, new_inst); - high_left->AddInstruction(call_left); - high_left->AddInstruction(goto_left); - - HInstruction* write_right = new (GetAllocator()) HInstanceFieldSet(new_inst, - c0, - nullptr, - DataType::Type::kInt32, - MemberOffset(32), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* goto_right = new (GetAllocator()) HGoto(); - high_right->AddInstruction(write_right); - high_right->AddInstruction(goto_right); - - HInstruction* read_mid = new (GetAllocator()) HInstanceFieldGet(new_inst, - nullptr, - DataType::Type::kInt32, - MemberOffset(32), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* mul_mid = new (GetAllocator()) HMul(DataType::Type::kInt32, read_mid, c2); - HInstruction* write_mid = new (GetAllocator()) HInstanceFieldSet(new_inst, - mul_mid, - nullptr, - DataType::Type::kInt32, - MemberOffset(32), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* if_mid = new (GetAllocator()) HIf(bool_value2); - mid->AddInstruction(read_mid); - mid->AddInstruction(mul_mid); - mid->AddInstruction(write_mid); - mid->AddInstruction(if_mid); - - HInstruction* call_low_left = new (GetAllocator()) - HInvokeStaticOrDirect(GetAllocator(), - 1, - DataType::Type::kVoid, - 0, - { nullptr, 0 }, - nullptr, - {}, - InvokeType::kStatic, - { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, - !graph_->IsDebuggable()); - HInstruction* goto_low_left = new (GetAllocator()) HGoto(); - call_low_left->SetRawInputAt(0, new_inst); - low_left->AddInstruction(call_low_left); - low_left->AddInstruction(goto_low_left); - - HInstruction* write_low_right = new (GetAllocator()) HInstanceFieldSet(new_inst, - c0, - nullptr, - DataType::Type::kInt32, - MemberOffset(32), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* goto_low_right = new (GetAllocator()) HGoto(); - low_right->AddInstruction(write_low_right); - low_right->AddInstruction(goto_low_right); - - HInstruction* read_final = new (GetAllocator()) HInstanceFieldGet(new_inst, - nullptr, - DataType::Type::kInt32, - MemberOffset(32), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - exit->AddInstruction(read_final); + HInstruction* cls = MakeLoadClass(entry); + HInstruction* new_inst = MakeNewInstance(entry, cls); + MakeIf(entry, bool_value1); + + HInstruction* call_left = MakeInvokeStatic(high_left, DataType::Type::kVoid, {new_inst}); + MakeGoto(high_left); + + HInstruction* write_right = MakeIFieldSet(high_right, new_inst, c0, MemberOffset(32)); + MakeGoto(high_right); + + HInstruction* read_mid = MakeIFieldGet(mid, new_inst, DataType::Type::kInt32, MemberOffset(32)); + HInstruction* mul_mid = MakeBinOp<HMul>(mid, DataType::Type::kInt32, read_mid, c2); + HInstruction* write_mid = MakeIFieldSet(mid, new_inst, mul_mid, MemberOffset(32)); + MakeIf(mid, bool_value2); + + HInstruction* call_low_left = MakeInvokeStatic(low_left, DataType::Type::kVoid, {new_inst}); + MakeGoto(low_left); + + HInstruction* write_low_right = MakeIFieldSet(low_right, new_inst, c0, MemberOffset(32)); + MakeGoto(low_right); + + HInstruction* read_final = + MakeIFieldGet(exit, new_inst, DataType::Type::kInt32, MemberOffset(32)); ScopedArenaAllocator allocator(graph_->GetArenaStack()); LoadStoreAnalysis lsa(graph_, nullptr, &allocator); @@ -1102,105 +721,38 @@ TEST_F(LoadStoreAnalysisTest, PartialPhiPropagation1) { #undef GET_BLOCK EnsurePredecessorOrder(breturn, {left_merge, right}); EnsurePredecessorOrder(left_merge, {left_left, left_right}); - HInstruction* param1 = new (GetAllocator()) - HParameterValue(graph_->GetDexFile(), dex::TypeIndex(1), 1, DataType::Type::kBool); - HInstruction* param2 = new (GetAllocator()) - HParameterValue(graph_->GetDexFile(), dex::TypeIndex(1), 2, DataType::Type::kBool); - HInstruction* obj_param = new (GetAllocator()) - HParameterValue(graph_->GetDexFile(), dex::TypeIndex(10), 3, DataType::Type::kReference); + HInstruction* param1 = MakeParam(DataType::Type::kBool); + HInstruction* param2 = MakeParam(DataType::Type::kBool); + HInstruction* obj_param = MakeParam(DataType::Type::kReference); HInstruction* c12 = graph_->GetIntConstant(12); - HInstruction* cls = new (GetAllocator()) HLoadClass(graph_->GetCurrentMethod(), - dex::TypeIndex(10), - graph_->GetDexFile(), - ScopedNullHandle<mirror::Class>(), - false, - 0, - false); - HInstruction* new_inst = - new (GetAllocator()) HNewInstance(cls, - 0, - dex::TypeIndex(10), - graph_->GetDexFile(), - false, - QuickEntrypointEnum::kQuickAllocObjectInitialized); - HInstruction* store = new (GetAllocator()) HInstanceFieldSet(new_inst, - c12, - nullptr, - DataType::Type::kInt32, - MemberOffset(32), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* if_param1 = new (GetAllocator()) HIf(param1); - entry->AddInstruction(param1); - entry->AddInstruction(param2); - entry->AddInstruction(obj_param); - entry->AddInstruction(cls); - entry->AddInstruction(new_inst); - entry->AddInstruction(store); - entry->AddInstruction(if_param1); + HInstruction* cls = MakeLoadClass(entry); + HInstruction* new_inst = MakeNewInstance(entry, cls); + HInstruction* store = MakeIFieldSet(entry, new_inst, c12, MemberOffset(32)); + MakeIf(entry, param1); ArenaVector<HInstruction*> current_locals({}, GetAllocator()->Adapter(kArenaAllocInstruction)); ManuallyBuildEnvFor(cls, ¤t_locals); new_inst->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* if_left = new (GetAllocator()) HIf(param2); - left->AddInstruction(if_left); - - HInstruction* goto_left_left = new (GetAllocator()) HGoto(); - left_left->AddInstruction(goto_left_left); - - HInstruction* goto_left_right = new (GetAllocator()) HGoto(); - left_right->AddInstruction(goto_left_right); - - HPhi* left_phi = - new (GetAllocator()) HPhi(GetAllocator(), kNoRegNumber, 2, DataType::Type::kReference); - HInstruction* call_left = new (GetAllocator()) - HInvokeStaticOrDirect(GetAllocator(), - 1, - DataType::Type::kVoid, - 0, - {nullptr, 0}, - nullptr, - {}, - InvokeType::kStatic, - {nullptr, 0}, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, - !graph_->IsDebuggable()); - HInstruction* goto_left_merge = new (GetAllocator()) HGoto(); - left_phi->SetRawInputAt(0, obj_param); - left_phi->SetRawInputAt(1, new_inst); - call_left->SetRawInputAt(0, left_phi); - left_merge->AddPhi(left_phi); - left_merge->AddInstruction(call_left); - left_merge->AddInstruction(goto_left_merge); + MakeIf(left, param2); + + MakeGoto(left_left); + + MakeGoto(left_right); + + HPhi* left_phi = MakePhi(left_merge, {obj_param, new_inst}); + HInstruction* call_left = MakeInvokeStatic(left_merge, DataType::Type::kVoid, {left_phi}); + MakeGoto(left_merge); left_phi->SetCanBeNull(true); call_left->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* goto_right = new (GetAllocator()) HGoto(); - right->AddInstruction(goto_right); - - HPhi* return_phi = - new (GetAllocator()) HPhi(GetAllocator(), kNoRegNumber, 2, DataType::Type::kReference); - HInstruction* read_exit = new (GetAllocator()) HInstanceFieldGet(return_phi, - nullptr, - DataType::Type::kReference, - MemberOffset(32), - false, - 0, - 0, - graph_->GetDexFile(), - 0); - HInstruction* return_exit = new (GetAllocator()) HReturn(read_exit); - return_phi->SetRawInputAt(0, left_phi); - return_phi->SetRawInputAt(1, obj_param); - breturn->AddPhi(return_phi); - breturn->AddInstruction(read_exit); - breturn->AddInstruction(return_exit); - - HInstruction* exit_instruction = new (GetAllocator()) HExit(); - exit->AddInstruction(exit_instruction); + MakeGoto(right); + + HPhi* return_phi = MakePhi(breturn, {left_phi, obj_param}); + HInstruction* read_exit = + MakeIFieldGet(breturn, return_phi, DataType::Type::kReference, MemberOffset(32)); + MakeReturn(breturn, read_exit); + + MakeExit(exit); graph_->ClearDominanceInformation(); graph_->BuildDominatorTree(); diff --git a/compiler/optimizing/load_store_elimination_test.cc b/compiler/optimizing/load_store_elimination_test.cc index 0775051eb4..1ac6f1f965 100644 --- a/compiler/optimizing/load_store_elimination_test.cc +++ b/compiler/optimizing/load_store_elimination_test.cc @@ -93,11 +93,9 @@ class LoadStoreEliminationTestBase : public SuperTest, public OptimizingUnitTest void CreateEntryBlockInstructions() { HInstruction* c1 = graph_->GetIntConstant(1); HInstruction* c4 = graph_->GetIntConstant(4); - i_add1_ = new (GetAllocator()) HAdd(DataType::Type::kInt32, i_, c1); - i_add4_ = new (GetAllocator()) HAdd(DataType::Type::kInt32, i_, c4); - entry_block_->AddInstruction(i_add1_); - entry_block_->AddInstruction(i_add4_); - entry_block_->AddInstruction(new (GetAllocator()) HGoto()); + i_add1_ = MakeBinOp<HAdd>(entry_block_, DataType::Type::kInt32, i_, c1); + i_add4_ = MakeBinOp<HAdd>(entry_block_, DataType::Type::kInt32, i_, c4); + MakeGoto(entry_block_); } // Create the major CFG used by tests: @@ -128,24 +126,18 @@ class LoadStoreEliminationTestBase : public SuperTest, public OptimizingUnitTest // pre_header block // phi = 0; - phi_ = new (GetAllocator()) HPhi(GetAllocator(), 0, 0, DataType::Type::kInt32); - loop_->AddPhi(phi_); - pre_header_->AddInstruction(new (GetAllocator()) HGoto()); - phi_->AddInput(c0); + phi_ = MakePhi(loop_, {c0, /* placeholder */ c0}); + MakeGoto(pre_header_); // loop block: // suspend_check // phi++; // if (phi >= 128) - suspend_check_ = new (GetAllocator()) HSuspendCheck(); - HInstruction* inc_phi = new (GetAllocator()) HAdd(DataType::Type::kInt32, phi_, c1); - HInstruction* cmp = new (GetAllocator()) HGreaterThanOrEqual(phi_, c128); - HInstruction* hif = new (GetAllocator()) HIf(cmp); - loop_->AddInstruction(suspend_check_); - loop_->AddInstruction(inc_phi); - loop_->AddInstruction(cmp); - loop_->AddInstruction(hif); - phi_->AddInput(inc_phi); + suspend_check_ = MakeSuspendCheck(loop_); + HInstruction* inc_phi = MakeBinOp<HAdd>(loop_, DataType::Type::kInt32, phi_, c1); + HInstruction* cmp = MakeCondition<HGreaterThanOrEqual>(loop_, phi_, c128); + MakeIf(loop_, cmp); + phi_->ReplaceInput(inc_phi, 1u); // Update back-edge input. CreateEnvForSuspendCheck(); } @@ -176,13 +168,11 @@ class LoadStoreEliminationTestBase : public SuperTest, public OptimizingUnitTest left->AddSuccessor(return_block_); right->AddSuccessor(return_block_); - HInstruction* cmp = new (GetAllocator()) HGreaterThanOrEqual(i_, j_); - HInstruction* hif = new (GetAllocator()) HIf(cmp); - upper->AddInstruction(cmp); - upper->AddInstruction(hif); + HInstruction* cmp = MakeCondition<HGreaterThanOrEqual>(upper, i_, j_); + MakeIf(upper, cmp); - left->AddInstruction(new (GetAllocator()) HGoto()); - right->AddInstruction(new (GetAllocator()) HGoto()); + MakeGoto(left); + MakeGoto(right); return std::make_tuple(upper, left, right, return_block_); } @@ -271,15 +261,9 @@ class LoadStoreEliminationTestBase : public SuperTest, public OptimizingUnitTest void InitGraphAndParameters() { InitGraph(); - AddParameter(new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kInt32)); - array_ = parameters_.back(); - AddParameter(new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(1), 1, DataType::Type::kInt32)); - i_ = parameters_.back(); - AddParameter(new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(1), 2, DataType::Type::kInt32)); - j_ = parameters_.back(); + array_ = MakeParam(DataType::Type::kInt32); + i_ = MakeParam(DataType::Type::kInt32); + j_ = MakeParam(DataType::Type::kInt32); } HBasicBlock* pre_header_; @@ -726,9 +710,7 @@ TEST_F(LoadStoreEliminationTest, StoreAfterLoopWithSideEffects2) { // Add another array parameter that may alias with `array_`. // Note: We're not adding it to the suspend check environment. - AddParameter(new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(0), 3, DataType::Type::kInt32)); - HInstruction* array2 = parameters_.back(); + HInstruction* array2 = MakeParam(DataType::Type::kInt32); HInstruction* c0 = graph_->GetIntConstant(0); HInstruction* c2 = graph_->GetIntConstant(2); @@ -995,28 +977,23 @@ TEST_F(LoadStoreEliminationTest, DefaultShadowClass) { GET_BLOCK(exit); #undef GET_BLOCK - HInstruction* suspend_check = new (GetAllocator()) HSuspendCheck(); - entry->AddInstruction(suspend_check); - entry->AddInstruction(new (GetAllocator()) HGoto()); + HInstruction* suspend_check = MakeSuspendCheck(entry); + MakeGoto(entry); ManuallyBuildEnvFor(suspend_check, {}); - HInstruction* cls = MakeClassLoad(); - HInstruction* new_inst = MakeNewInstance(cls); + HInstruction* cls = MakeLoadClass(main); + HInstruction* new_inst = MakeNewInstance(main, cls); HInstruction* const_fence = new (GetAllocator()) HConstructorFence(new_inst, 0, GetAllocator()); - HInstruction* set_field = MakeIFieldSet(new_inst, graph_->GetIntConstant(33), MemberOffset(32)); - HInstruction* get_field = - MakeIFieldGet(new_inst, DataType::Type::kReference, mirror::Object::ClassOffset()); - HInstruction* return_val = new (GetAllocator()) HReturn(get_field); - main->AddInstruction(cls); - main->AddInstruction(new_inst); main->AddInstruction(const_fence); - main->AddInstruction(set_field); - main->AddInstruction(get_field); - main->AddInstruction(return_val); + HInstruction* set_field = + MakeIFieldSet(main, new_inst, graph_->GetIntConstant(33), MemberOffset(32)); + HInstruction* get_field = + MakeIFieldGet(main, new_inst, DataType::Type::kReference, mirror::Object::ClassOffset()); + HReturn* return_val = MakeReturn(main, get_field); cls->CopyEnvironmentFrom(suspend_check->GetEnvironment()); new_inst->CopyEnvironmentFrom(suspend_check->GetEnvironment()); - SetupExit(exit); + MakeExit(exit); graph_->ClearDominanceInformation(); PerformLSE(); @@ -1046,28 +1023,23 @@ TEST_F(LoadStoreEliminationTest, DefaultShadowMonitor) { GET_BLOCK(exit); #undef GET_BLOCK - HInstruction* suspend_check = new (GetAllocator()) HSuspendCheck(); - entry->AddInstruction(suspend_check); - entry->AddInstruction(new (GetAllocator()) HGoto()); + HInstruction* suspend_check = MakeSuspendCheck(entry); + MakeGoto(entry); ManuallyBuildEnvFor(suspend_check, {}); - HInstruction* cls = MakeClassLoad(); - HInstruction* new_inst = MakeNewInstance(cls); + HInstruction* cls = MakeLoadClass(main); + HInstruction* new_inst = MakeNewInstance(main, cls); HInstruction* const_fence = new (GetAllocator()) HConstructorFence(new_inst, 0, GetAllocator()); - HInstruction* set_field = MakeIFieldSet(new_inst, graph_->GetIntConstant(33), MemberOffset(32)); - HInstruction* get_field = - MakeIFieldGet(new_inst, DataType::Type::kInt32, mirror::Object::MonitorOffset()); - HInstruction* return_val = new (GetAllocator()) HReturn(get_field); - main->AddInstruction(cls); - main->AddInstruction(new_inst); main->AddInstruction(const_fence); - main->AddInstruction(set_field); - main->AddInstruction(get_field); - main->AddInstruction(return_val); + HInstruction* set_field = + MakeIFieldSet(main, new_inst, graph_->GetIntConstant(33), MemberOffset(32)); + HInstruction* get_field = + MakeIFieldGet(main, new_inst, DataType::Type::kInt32, mirror::Object::MonitorOffset()); + HReturn* return_val = MakeReturn(main, get_field); cls->CopyEnvironmentFrom(suspend_check->GetEnvironment()); new_inst->CopyEnvironmentFrom(suspend_check->GetEnvironment()); - SetupExit(exit); + MakeExit(exit); graph_->ClearDominanceInformation(); PerformLSE(); @@ -1117,27 +1089,19 @@ TEST_F(LoadStoreEliminationTest, ArrayLoopOverlap) { HInstruction* zero_const = graph_->GetConstant(DataType::Type::kInt32, 0); HInstruction* one_const = graph_->GetConstant(DataType::Type::kInt32, 1); HInstruction* eighty_const = graph_->GetConstant(DataType::Type::kInt32, 80); - HInstruction* entry_goto = new (GetAllocator()) HGoto(); - entry->AddInstruction(entry_goto); + MakeGoto(entry); - HInstruction* alloc_w = new (GetAllocator()) HNewArray(zero_const, eighty_const, 0, 0); - HInstruction* pre_header_goto = new (GetAllocator()) HGoto(); - loop_pre_header->AddInstruction(alloc_w); - loop_pre_header->AddInstruction(pre_header_goto); + HInstruction* alloc_w = MakeNewArray(loop_pre_header, zero_const, eighty_const); + MakeGoto(loop_pre_header); // environment ManuallyBuildEnvFor(alloc_w, {}); // loop-start - HPhi* i_phi = new (GetAllocator()) HPhi(GetAllocator(), 0, 0, DataType::Type::kInt32); - HPhi* t_phi = new (GetAllocator()) HPhi(GetAllocator(), 1, 0, DataType::Type::kInt32); - HInstruction* suspend = new (GetAllocator()) HSuspendCheck(); - HInstruction* i_cmp_top = new (GetAllocator()) HGreaterThanOrEqual(i_phi, eighty_const); - HInstruction* loop_start_branch = new (GetAllocator()) HIf(i_cmp_top); - loop_entry->AddPhi(i_phi); - loop_entry->AddPhi(t_phi); - loop_entry->AddInstruction(suspend); - loop_entry->AddInstruction(i_cmp_top); - loop_entry->AddInstruction(loop_start_branch); + HPhi* i_phi = MakePhi(loop_entry, {one_const, /* placeholder */ one_const}); + HPhi* t_phi = MakePhi(loop_entry, {zero_const, /* placeholder */ zero_const}); + HInstruction* suspend = MakeSuspendCheck(loop_entry); + HInstruction* i_cmp_top = MakeCondition<HGreaterThanOrEqual>(loop_entry, i_phi, eighty_const); + MakeIf(loop_entry, i_cmp_top); CHECK_EQ(loop_entry->GetSuccessors().size(), 2u); if (loop_entry->GetNormalSuccessors()[1] != loop_body) { loop_entry->SwapSuccessors(); @@ -1146,44 +1110,32 @@ TEST_F(LoadStoreEliminationTest, ArrayLoopOverlap) { if (loop_entry->GetPredecessors()[0] != loop_pre_header) { loop_entry->SwapPredecessors(); } - i_phi->AddInput(one_const); - t_phi->AddInput(zero_const); // environment ManuallyBuildEnvFor(suspend, { alloc_w, i_phi, t_phi }); // BODY - HInstruction* last_i = new (GetAllocator()) HSub(DataType::Type::kInt32, i_phi, one_const); - HInstruction* last_get = - new (GetAllocator()) HArrayGet(alloc_w, last_i, DataType::Type::kInt32, 0); - HInvoke* body_value = MakeInvoke(DataType::Type::kInt32, { last_get, one_const }); + HInstruction* last_i = MakeBinOp<HSub>(loop_body, DataType::Type::kInt32, i_phi, one_const); + HInstruction* last_get = MakeArrayGet(loop_body, alloc_w, last_i, DataType::Type::kInt32); + HInvoke* body_value = + MakeInvokeStatic(loop_body, DataType::Type::kInt32, { last_get, one_const }); HInstruction* body_set = - new (GetAllocator()) HArraySet(alloc_w, i_phi, body_value, DataType::Type::kInt32, 0); - HInstruction* body_get = - new (GetAllocator()) HArrayGet(alloc_w, i_phi, DataType::Type::kInt32, 0); - HInvoke* t_next = MakeInvoke(DataType::Type::kInt32, { body_get, t_phi }); - HInstruction* i_next = new (GetAllocator()) HAdd(DataType::Type::kInt32, i_phi, one_const); - HInstruction* body_goto = new (GetAllocator()) HGoto(); - loop_body->AddInstruction(last_i); - loop_body->AddInstruction(last_get); - loop_body->AddInstruction(body_value); - loop_body->AddInstruction(body_set); - loop_body->AddInstruction(body_get); - loop_body->AddInstruction(t_next); - loop_body->AddInstruction(i_next); - loop_body->AddInstruction(body_goto); + MakeArraySet(loop_body, alloc_w, i_phi, body_value, DataType::Type::kInt32); + HInstruction* body_get = MakeArrayGet(loop_body, alloc_w, i_phi, DataType::Type::kInt32); + HInvoke* t_next = MakeInvokeStatic(loop_body, DataType::Type::kInt32, { body_get, t_phi }); + HInstruction* i_next = MakeBinOp<HAdd>(loop_body, DataType::Type::kInt32, i_phi, one_const); + MakeGoto(loop_body); body_value->CopyEnvironmentFrom(suspend->GetEnvironment()); - i_phi->AddInput(i_next); - t_phi->AddInput(t_next); + i_phi->ReplaceInput(i_next, 1u); // Update back-edge input. + t_phi->ReplaceInput(t_next, 1u); // Update back-edge input. t_next->CopyEnvironmentFrom(suspend->GetEnvironment()); // loop-post - HInstruction* return_inst = new (GetAllocator()) HReturn(t_phi); - loop_post->AddInstruction(return_inst); + MakeReturn(loop_post, t_phi); // exit - SetupExit(exit); + MakeExit(exit); graph_->ClearDominanceInformation(); graph_->ClearLoopInformation(); @@ -1246,27 +1198,19 @@ TEST_F(LoadStoreEliminationTest, ArrayLoopOverlap2) { HInstruction* zero_const = graph_->GetConstant(DataType::Type::kInt32, 0); HInstruction* one_const = graph_->GetConstant(DataType::Type::kInt32, 1); HInstruction* eighty_const = graph_->GetConstant(DataType::Type::kInt32, 80); - HInstruction* entry_goto = new (GetAllocator()) HGoto(); - entry->AddInstruction(entry_goto); + MakeGoto(entry); - HInstruction* alloc_w = new (GetAllocator()) HNewArray(zero_const, eighty_const, 0, 0); - HInstruction* pre_header_goto = new (GetAllocator()) HGoto(); - loop_pre_header->AddInstruction(alloc_w); - loop_pre_header->AddInstruction(pre_header_goto); + HInstruction* alloc_w = MakeNewArray(loop_pre_header, zero_const, eighty_const); + MakeGoto(loop_pre_header); // environment ManuallyBuildEnvFor(alloc_w, {}); // loop-start - HPhi* i_phi = new (GetAllocator()) HPhi(GetAllocator(), 0, 0, DataType::Type::kInt32); - HPhi* t_phi = new (GetAllocator()) HPhi(GetAllocator(), 1, 0, DataType::Type::kInt32); - HInstruction* suspend = new (GetAllocator()) HSuspendCheck(); - HInstruction* i_cmp_top = new (GetAllocator()) HGreaterThanOrEqual(i_phi, eighty_const); - HInstruction* loop_start_branch = new (GetAllocator()) HIf(i_cmp_top); - loop_entry->AddPhi(i_phi); - loop_entry->AddPhi(t_phi); - loop_entry->AddInstruction(suspend); - loop_entry->AddInstruction(i_cmp_top); - loop_entry->AddInstruction(loop_start_branch); + HPhi* i_phi = MakePhi(loop_entry, {one_const, /* placeholder */ one_const}); + HPhi* t_phi = MakePhi(loop_entry, {zero_const, /* placeholder */ zero_const}); + HInstruction* suspend = MakeSuspendCheck(loop_entry); + HInstruction* i_cmp_top = MakeCondition<HGreaterThanOrEqual>(loop_entry, i_phi, eighty_const); + MakeIf(loop_entry, i_cmp_top); CHECK_EQ(loop_entry->GetSuccessors().size(), 2u); if (loop_entry->GetNormalSuccessors()[1] != loop_body) { loop_entry->SwapSuccessors(); @@ -1275,61 +1219,43 @@ TEST_F(LoadStoreEliminationTest, ArrayLoopOverlap2) { if (loop_entry->GetPredecessors()[0] != loop_pre_header) { loop_entry->SwapPredecessors(); } - i_phi->AddInput(one_const); - t_phi->AddInput(zero_const); // environment ManuallyBuildEnvFor(suspend, { alloc_w, i_phi, t_phi }); // BODY - HInstruction* last_i = new (GetAllocator()) HSub(DataType::Type::kInt32, i_phi, one_const); - HInstruction *last_get_1, *last_get_2, *last_get_3; - HInstruction *body_value_1, *body_value_2, *body_value_3; - HInstruction *body_set_1, *body_set_2, *body_set_3; - HInstruction *body_get_1, *body_get_2, *body_get_3; - HInstruction *t_next_1, *t_next_2, *t_next_3; + HInstruction* last_i = MakeBinOp<HSub>(loop_body, DataType::Type::kInt32, i_phi, one_const); auto make_instructions = [&](HInstruction* last_t_value) { - HInstruction* last_get = - new (GetAllocator()) HArrayGet(alloc_w, last_i, DataType::Type::kInt32, 0); - HInvoke* body_value = MakeInvoke(DataType::Type::kInt32, { last_get, one_const }); + HInstruction* last_get = MakeArrayGet(loop_body, alloc_w, last_i, DataType::Type::kInt32); + HInvoke* body_value = + MakeInvokeStatic(loop_body, DataType::Type::kInt32, { last_get, one_const }); HInstruction* body_set = - new (GetAllocator()) HArraySet(alloc_w, i_phi, body_value, DataType::Type::kInt32, 0); - HInstruction* body_get = - new (GetAllocator()) HArrayGet(alloc_w, i_phi, DataType::Type::kInt32, 0); - HInvoke* t_next = MakeInvoke(DataType::Type::kInt32, { body_get, last_t_value }); - loop_body->AddInstruction(last_get); - loop_body->AddInstruction(body_value); - loop_body->AddInstruction(body_set); - loop_body->AddInstruction(body_get); - loop_body->AddInstruction(t_next); + MakeArraySet(loop_body, alloc_w, i_phi, body_value, DataType::Type::kInt32); + HInstruction* body_get = MakeArrayGet(loop_body, alloc_w, i_phi, DataType::Type::kInt32); + HInvoke* t_next = + MakeInvokeStatic(loop_body, DataType::Type::kInt32, { body_get, last_t_value }); return std::make_tuple(last_get, body_value, body_set, body_get, t_next); }; - std::tie(last_get_1, body_value_1, body_set_1, body_get_1, t_next_1) = make_instructions(t_phi); - std::tie(last_get_2, body_value_2, body_set_2, body_get_2, t_next_2) = - make_instructions(t_next_1); - std::tie(last_get_3, body_value_3, body_set_3, body_get_3, t_next_3) = - make_instructions(t_next_2); - HInstruction* i_next = new (GetAllocator()) HAdd(DataType::Type::kInt32, i_phi, one_const); - HInstruction* body_goto = new (GetAllocator()) HGoto(); - loop_body->InsertInstructionBefore(last_i, last_get_1); - loop_body->AddInstruction(i_next); - loop_body->AddInstruction(body_goto); + auto [last_get_1, body_value_1, body_set_1, body_get_1, t_next_1] = make_instructions(t_phi); + auto [last_get_2, body_value_2, body_set_2, body_get_2, t_next_2] = make_instructions(t_next_1); + auto [last_get_3, body_value_3, body_set_3, body_get_3, t_next_3] = make_instructions(t_next_2); + HInstruction* i_next = MakeBinOp<HAdd>(loop_body, DataType::Type::kInt32, i_phi, one_const); + MakeGoto(loop_body); body_value_1->CopyEnvironmentFrom(suspend->GetEnvironment()); body_value_2->CopyEnvironmentFrom(suspend->GetEnvironment()); body_value_3->CopyEnvironmentFrom(suspend->GetEnvironment()); - i_phi->AddInput(i_next); - t_phi->AddInput(t_next_3); + i_phi->ReplaceInput(i_next, 1u); // Update back-edge input. + t_phi->ReplaceInput(t_next_3, 1u); // Update back-edge input. t_next_1->CopyEnvironmentFrom(suspend->GetEnvironment()); t_next_2->CopyEnvironmentFrom(suspend->GetEnvironment()); t_next_3->CopyEnvironmentFrom(suspend->GetEnvironment()); // loop-post - HInstruction* return_inst = new (GetAllocator()) HReturn(t_phi); - loop_post->AddInstruction(return_inst); + MakeReturn(loop_post, t_phi); // exit - SetupExit(exit); + MakeExit(exit); graph_->ClearDominanceInformation(); graph_->ClearLoopInformation(); @@ -1388,56 +1314,39 @@ TEST_F(LoadStoreEliminationTest, ArrayNonLoopPhi) { HInstruction* two_const = graph_->GetConstant(DataType::Type::kInt32, 2); HInstruction* param = MakeParam(DataType::Type::kBool); - HInstruction* entry_goto = new (GetAllocator()) HGoto(); - entry->AddInstruction(entry_goto); + MakeGoto(entry); - HInstruction* alloc_w = new (GetAllocator()) HNewArray(zero_const, two_const, 0, 0); - HInstruction* branch = new (GetAllocator()) HIf(param); - start->AddInstruction(alloc_w); - start->AddInstruction(branch); + HInstruction* alloc_w = MakeNewArray(start, zero_const, two_const); + MakeIf(start, param); // environment ManuallyBuildEnvFor(alloc_w, {}); // left - HInvoke* left_value = MakeInvoke(DataType::Type::kInt32, { zero_const }); + HInvoke* left_value = MakeInvokeStatic(left, DataType::Type::kInt32, { zero_const }); HInstruction* left_set_1 = - new (GetAllocator()) HArraySet(alloc_w, zero_const, left_value, DataType::Type::kInt32, 0); + MakeArraySet(left, alloc_w, zero_const, left_value, DataType::Type::kInt32); HInstruction* left_set_2 = - new (GetAllocator()) HArraySet(alloc_w, one_const, zero_const, DataType::Type::kInt32, 0); - HInstruction* left_goto = new (GetAllocator()) HGoto(); - left->AddInstruction(left_value); - left->AddInstruction(left_set_1); - left->AddInstruction(left_set_2); - left->AddInstruction(left_goto); + MakeArraySet(left, alloc_w, one_const, zero_const, DataType::Type::kInt32); + MakeGoto(left); ManuallyBuildEnvFor(left_value, { alloc_w }); // right - HInvoke* right_value = MakeInvoke(DataType::Type::kInt32, { one_const }); + HInvoke* right_value = MakeInvokeStatic(right, DataType::Type::kInt32, { one_const }); HInstruction* right_set_1 = - new (GetAllocator()) HArraySet(alloc_w, zero_const, right_value, DataType::Type::kInt32, 0); + MakeArraySet(right, alloc_w, zero_const, right_value, DataType::Type::kInt32); HInstruction* right_set_2 = - new (GetAllocator()) HArraySet(alloc_w, one_const, zero_const, DataType::Type::kInt32, 0); - HInstruction* right_goto = new (GetAllocator()) HGoto(); - right->AddInstruction(right_value); - right->AddInstruction(right_set_1); - right->AddInstruction(right_set_2); - right->AddInstruction(right_goto); + MakeArraySet(right, alloc_w, one_const, zero_const, DataType::Type::kInt32); + MakeGoto(right); ManuallyBuildEnvFor(right_value, { alloc_w }); // ret - HInstruction* read_1 = - new (GetAllocator()) HArrayGet(alloc_w, zero_const, DataType::Type::kInt32, 0); - HInstruction* read_2 = - new (GetAllocator()) HArrayGet(alloc_w, one_const, DataType::Type::kInt32, 0); - HInstruction* add = new (GetAllocator()) HAdd(DataType::Type::kInt32, read_1, read_2); - HInstruction* return_inst = new (GetAllocator()) HReturn(add); - ret->AddInstruction(read_1); - ret->AddInstruction(read_2); - ret->AddInstruction(add); - ret->AddInstruction(return_inst); + HInstruction* read_1 = MakeArrayGet(ret, alloc_w, zero_const, DataType::Type::kInt32); + HInstruction* read_2 = MakeArrayGet(ret, alloc_w, one_const, DataType::Type::kInt32); + HInstruction* add = MakeBinOp<HAdd>(ret, DataType::Type::kInt32, read_1, read_2); + MakeReturn(ret, add); // exit - SetupExit(exit); + MakeExit(exit); graph_->ClearDominanceInformation(); graph_->ClearLoopInformation(); @@ -1482,52 +1391,36 @@ TEST_F(LoadStoreEliminationTest, ArrayMergeDefault) { HInstruction* one_const = graph_->GetConstant(DataType::Type::kInt32, 1); HInstruction* two_const = graph_->GetConstant(DataType::Type::kInt32, 2); HInstruction* param = MakeParam(DataType::Type::kBool); - HInstruction* entry_goto = new (GetAllocator()) HGoto(); + MakeGoto(entry); - entry->AddInstruction(entry_goto); - - HInstruction* alloc_w = new (GetAllocator()) HNewArray(zero_const, two_const, 0, 0); - HInstruction* branch = new (GetAllocator()) HIf(param); - start->AddInstruction(alloc_w); - start->AddInstruction(branch); + HInstruction* alloc_w = MakeNewArray(start, zero_const, two_const); + MakeIf(start, param); // environment ArenaVector<HInstruction*> alloc_locals({}, GetAllocator()->Adapter(kArenaAllocInstruction)); ManuallyBuildEnvFor(alloc_w, {}); // left HInstruction* left_set_1 = - new (GetAllocator()) HArraySet(alloc_w, zero_const, one_const, DataType::Type::kInt32, 0); + MakeArraySet(left, alloc_w, zero_const, one_const, DataType::Type::kInt32); HInstruction* left_set_2 = - new (GetAllocator()) HArraySet(alloc_w, zero_const, zero_const, DataType::Type::kInt32, 0); - HInstruction* left_goto = new (GetAllocator()) HGoto(); - left->AddInstruction(left_set_1); - left->AddInstruction(left_set_2); - left->AddInstruction(left_goto); + MakeArraySet(left, alloc_w, zero_const, zero_const, DataType::Type::kInt32); + MakeGoto(left); // right HInstruction* right_set_1 = - new (GetAllocator()) HArraySet(alloc_w, one_const, one_const, DataType::Type::kInt32, 0); + MakeArraySet(right, alloc_w, one_const, one_const, DataType::Type::kInt32); HInstruction* right_set_2 = - new (GetAllocator()) HArraySet(alloc_w, one_const, zero_const, DataType::Type::kInt32, 0); - HInstruction* right_goto = new (GetAllocator()) HGoto(); - right->AddInstruction(right_set_1); - right->AddInstruction(right_set_2); - right->AddInstruction(right_goto); + MakeArraySet(right, alloc_w, one_const, zero_const, DataType::Type::kInt32); + MakeGoto(right); // ret - HInstruction* read_1 = - new (GetAllocator()) HArrayGet(alloc_w, zero_const, DataType::Type::kInt32, 0); - HInstruction* read_2 = - new (GetAllocator()) HArrayGet(alloc_w, one_const, DataType::Type::kInt32, 0); - HInstruction* add = new (GetAllocator()) HAdd(DataType::Type::kInt32, read_1, read_2); - HInstruction* return_inst = new (GetAllocator()) HReturn(add); - ret->AddInstruction(read_1); - ret->AddInstruction(read_2); - ret->AddInstruction(add); - ret->AddInstruction(return_inst); + HInstruction* read_1 = MakeArrayGet(ret, alloc_w, zero_const, DataType::Type::kInt32); + HInstruction* read_2 = MakeArrayGet(ret, alloc_w, one_const, DataType::Type::kInt32); + HInstruction* add = MakeBinOp<HAdd>(ret, DataType::Type::kInt32, read_1, read_2); + MakeReturn(ret, add); // exit - SetupExit(exit); + MakeExit(exit); graph_->ClearDominanceInformation(); graph_->ClearLoopInformation(); @@ -1574,55 +1467,38 @@ TEST_F(LoadStoreEliminationTest, ArrayLoopAliasing1) { HInstruction* c1 = graph_->GetIntConstant(1); // entry - HInstruction* cls = MakeClassLoad(); - HInstruction* array = new (GetAllocator()) HNewArray( - cls, n, /*dex_pc=*/ 0u, DataType::SizeShift(DataType::Type::kInt32)); - HInstruction* entry_goto = new (GetAllocator()) HGoto(); - entry->AddInstruction(cls); - entry->AddInstruction(array); - entry->AddInstruction(entry_goto); + HInstruction* cls = MakeLoadClass(entry); + HInstruction* array = MakeNewArray(entry, cls, n); + MakeGoto(entry); ManuallyBuildEnvFor(cls, {}); ManuallyBuildEnvFor(array, {}); - HInstruction* preheader_goto = new (GetAllocator()) HGoto(); - preheader->AddInstruction(preheader_goto); + MakeGoto(preheader); // loop - HPhi* i_phi = new (GetAllocator()) HPhi(GetAllocator(), 0, 0, DataType::Type::kInt32); - HInstruction* loop_suspend_check = new (GetAllocator()) HSuspendCheck(); - HInstruction* loop_cond = new (GetAllocator()) HLessThan(i_phi, n); - HIf* loop_if = new (GetAllocator()) HIf(loop_cond); - loop->AddPhi(i_phi); - loop->AddInstruction(loop_suspend_check); - loop->AddInstruction(loop_cond); - loop->AddInstruction(loop_if); + HPhi* i_phi = MakePhi(loop, {c0, /*placeholder*/ c0}); + HInstruction* loop_suspend_check = MakeSuspendCheck(loop); + HInstruction* loop_cond = MakeCondition<HLessThan>(loop, i_phi, n); + HIf* loop_if = MakeIf(loop, loop_cond); CHECK(loop_if->IfTrueSuccessor() == body); ManuallyBuildEnvFor(loop_suspend_check, {}); // body HInstruction* body_set = - new (GetAllocator()) HArraySet(array, i_phi, i_phi, DataType::Type::kInt32, /*dex_pc=*/ 0u); - HInstruction* body_add = new (GetAllocator()) HAdd(DataType::Type::kInt32, i_phi, c1); - HInstruction* body_goto = new (GetAllocator()) HGoto(); - body->AddInstruction(body_set); - body->AddInstruction(body_add); - body->AddInstruction(body_goto); + MakeArraySet(body, array, i_phi, i_phi, DataType::Type::kInt32, /*dex_pc=*/ 0u); + HInstruction* body_add = MakeBinOp<HAdd>(body, DataType::Type::kInt32, i_phi, c1); + MakeGoto(body); - // i_phi inputs - i_phi->AddInput(c0); - i_phi->AddInput(body_add); + // Update `i_phi`'s back-edge input. + i_phi->ReplaceInput(body_add, 1u); // ret - HInstruction* ret_sub = new (GetAllocator()) HSub(DataType::Type::kInt32, i_phi, c1); - HInstruction* ret_get = - new (GetAllocator()) HArrayGet(array, ret_sub, DataType::Type::kInt32, /*dex_pc=*/ 0); - HInstruction* ret_return = new (GetAllocator()) HReturn(ret_get); - ret->AddInstruction(ret_sub); - ret->AddInstruction(ret_get); - ret->AddInstruction(ret_return); + HInstruction* ret_sub = MakeBinOp<HSub>(ret, DataType::Type::kInt32, i_phi, c1); + HInstruction* ret_get = MakeArrayGet(ret, array, ret_sub, DataType::Type::kInt32); + MakeReturn(ret, ret_get); // exit - SetupExit(exit); + MakeExit(exit); graph_->ClearDominanceInformation(); graph_->ClearLoopInformation(); @@ -1668,60 +1544,39 @@ TEST_F(LoadStoreEliminationTest, ArrayLoopAliasing2) { HInstruction* c1 = graph_->GetIntConstant(1); // entry - HInstruction* cls = MakeClassLoad(); - HInstruction* array = new (GetAllocator()) HNewArray( - cls, n, /*dex_pc=*/ 0u, DataType::SizeShift(DataType::Type::kInt32)); - HInstruction* entry_goto = new (GetAllocator()) HGoto(); - entry->AddInstruction(cls); - entry->AddInstruction(array); - entry->AddInstruction(entry_goto); + HInstruction* cls = MakeLoadClass(entry); + HInstruction* array = MakeNewArray(entry, cls, n); + MakeGoto(entry); ManuallyBuildEnvFor(cls, {}); ManuallyBuildEnvFor(array, {}); - HInstruction* preheader_goto = new (GetAllocator()) HGoto(); - preheader->AddInstruction(preheader_goto); + MakeGoto(preheader); // loop - HPhi* i_phi = new (GetAllocator()) HPhi(GetAllocator(), 0, 0, DataType::Type::kInt32); - HInstruction* loop_suspend_check = new (GetAllocator()) HSuspendCheck(); - HInstruction* loop_cond = new (GetAllocator()) HLessThan(i_phi, n); - HIf* loop_if = new (GetAllocator()) HIf(loop_cond); - loop->AddPhi(i_phi); - loop->AddInstruction(loop_suspend_check); - loop->AddInstruction(loop_cond); - loop->AddInstruction(loop_if); + HPhi* i_phi = MakePhi(loop, {c0, /* placeholder */ c0}); + HInstruction* loop_suspend_check = MakeSuspendCheck(loop); + HInstruction* loop_cond = MakeCondition<HLessThan>(loop, i_phi, n); + HIf* loop_if = MakeIf(loop, loop_cond); CHECK(loop_if->IfTrueSuccessor() == body); ManuallyBuildEnvFor(loop_suspend_check, {}); // body - HInstruction* body_set = - new (GetAllocator()) HArraySet(array, i_phi, i_phi, DataType::Type::kInt32, /*dex_pc=*/ 0u); - HInstruction* body_add = new (GetAllocator()) HAdd(DataType::Type::kInt32, i_phi, c1); - HInstruction* body_goto = new (GetAllocator()) HGoto(); - body->AddInstruction(body_set); - body->AddInstruction(body_add); - body->AddInstruction(body_goto); + HInstruction* body_set = MakeArraySet(body, array, i_phi, i_phi, DataType::Type::kInt32); + HInstruction* body_add = MakeBinOp<HAdd>(body, DataType::Type::kInt32, i_phi, c1); + MakeGoto(body); - // i_phi inputs - i_phi->AddInput(c0); - i_phi->AddInput(body_add); + // Update `i_phi`'s back-edge input. + i_phi->ReplaceInput(body_add, 1u); // ret - HInstruction* ret_sub = new (GetAllocator()) HSub(DataType::Type::kInt32, i_phi, c1); - HInstruction* ret_get1 = - new (GetAllocator()) HArrayGet(array, ret_sub, DataType::Type::kInt32, /*dex_pc=*/ 0); - HInstruction* ret_get2 = - new (GetAllocator()) HArrayGet(array, i_phi, DataType::Type::kInt32, /*dex_pc=*/ 0); - HInstruction* ret_add = new (GetAllocator()) HAdd(DataType::Type::kInt32, ret_get1, ret_get2); - HInstruction* ret_return = new (GetAllocator()) HReturn(ret_add); - ret->AddInstruction(ret_sub); - ret->AddInstruction(ret_get1); - ret->AddInstruction(ret_get2); - ret->AddInstruction(ret_add); - ret->AddInstruction(ret_return); + HInstruction* ret_sub = MakeBinOp<HSub>(ret, DataType::Type::kInt32, i_phi, c1); + HInstruction* ret_get1 = MakeArrayGet(ret, array, ret_sub, DataType::Type::kInt32); + HInstruction* ret_get2 = MakeArrayGet(ret, array, i_phi, DataType::Type::kInt32); + HInstruction* ret_add = MakeBinOp<HAdd>(ret, DataType::Type::kInt32, ret_get1, ret_get2); + MakeReturn(ret, ret_add); // exit - SetupExit(exit); + MakeExit(exit); graph_->ClearDominanceInformation(); graph_->ClearLoopInformation(); @@ -1810,74 +1665,52 @@ TEST_F(LoadStoreEliminationTest, PartialUnknownMerge) { HInstruction* c3 = graph_->GetIntConstant(3); HInstruction* c5 = graph_->GetIntConstant(5); - HInstruction* cls = MakeClassLoad(); - HInstruction* new_inst = MakeNewInstance(cls); - HInstruction* entry_goto = new (GetAllocator()) HGoto(); - entry->AddInstruction(cls); - entry->AddInstruction(new_inst); - entry->AddInstruction(entry_goto); + HInstruction* cls = MakeLoadClass(entry); + HInstruction* new_inst = MakeNewInstance(entry, cls); + MakeGoto(entry); ManuallyBuildEnvFor(cls, {}); new_inst->CopyEnvironmentFrom(cls->GetEnvironment()); HInstruction* switch_inst = new (GetAllocator()) HPackedSwitch(0, 2, switch_val); bswitch->AddInstruction(switch_inst); - HInstruction* write_c1 = MakeIFieldSet(new_inst, c1, MemberOffset(32)); - HInstruction* call_c1 = MakeInvoke(DataType::Type::kVoid, { new_inst }); - HInstruction* goto_c1 = new (GetAllocator()) HGoto(); - case1->AddInstruction(write_c1); - case1->AddInstruction(call_c1); - case1->AddInstruction(goto_c1); + HInstruction* write_c1 = MakeIFieldSet(case1, new_inst, c1, MemberOffset(32)); + HInstruction* call_c1 = MakeInvokeStatic(case1, DataType::Type::kVoid, { new_inst }); + MakeGoto(case1); call_c1->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* write_c2 = MakeIFieldSet(new_inst, c2, MemberOffset(32)); - HInstruction* call_c2 = MakeInvoke(DataType::Type::kVoid, { new_inst }); - HInstruction* goto_c2 = new (GetAllocator()) HGoto(); - case2->AddInstruction(write_c2); - case2->AddInstruction(call_c2); - case2->AddInstruction(goto_c2); + HInstruction* write_c2 = MakeIFieldSet(case2, new_inst, c2, MemberOffset(32)); + HInstruction* call_c2 = MakeInvokeStatic(case2, DataType::Type::kVoid, { new_inst }); + MakeGoto(case2); call_c2->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* write_c3 = MakeIFieldSet(new_inst, c3, MemberOffset(32)); - HInstruction* goto_c3 = new (GetAllocator()) HGoto(); - case3->AddInstruction(write_c3); - case3->AddInstruction(goto_c3); + HInstruction* write_c3 = MakeIFieldSet(case3, new_inst, c3, MemberOffset(32)); + MakeGoto(case3); - HInstruction* goto_preheader = new (GetAllocator()) HGoto(); - loop_pre_header->AddInstruction(goto_preheader); + MakeGoto(loop_pre_header); - HInstruction* suspend_check_header = new (GetAllocator()) HSuspendCheck(); - HInstruction* call_loop_header = MakeInvoke(DataType::Type::kBool, {}); - HInstruction* if_loop_header = new (GetAllocator()) HIf(call_loop_header); - loop_header->AddInstruction(suspend_check_header); - loop_header->AddInstruction(call_loop_header); - loop_header->AddInstruction(if_loop_header); + HInstruction* suspend_check_header = MakeSuspendCheck(loop_header); + HInstruction* call_loop_header = MakeInvokeStatic(loop_header, DataType::Type::kBool, {}); + MakeIf(loop_header, call_loop_header); call_loop_header->CopyEnvironmentFrom(cls->GetEnvironment()); suspend_check_header->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* call_loop_body = MakeInvoke(DataType::Type::kBool, {}); - HInstruction* if_loop_body = new (GetAllocator()) HIf(call_loop_body); - loop_body->AddInstruction(call_loop_body); - loop_body->AddInstruction(if_loop_body); + HInstruction* call_loop_body = MakeInvokeStatic(loop_body, DataType::Type::kBool, {}); + MakeIf(loop_body, call_loop_body); call_loop_body->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* goto_loop_left = new (GetAllocator()) HGoto(); - loop_if_left->AddInstruction(goto_loop_left); + MakeGoto(loop_if_left); - HInstruction* write_loop_right = MakeIFieldSet(new_inst, c5, MemberOffset(32)); - HInstruction* goto_loop_right = new (GetAllocator()) HGoto(); - loop_if_right->AddInstruction(write_loop_right); - loop_if_right->AddInstruction(goto_loop_right); + HInstruction* write_loop_right = MakeIFieldSet(loop_if_right, new_inst, c5, MemberOffset(32)); + MakeGoto(loop_if_right); - HInstruction* goto_loop_end = new (GetAllocator()) HGoto(); - loop_end->AddInstruction(goto_loop_end); + MakeGoto(loop_end); - HInstruction* read_bottom = MakeIFieldGet(new_inst, DataType::Type::kInt32, MemberOffset(32)); - HInstruction* return_exit = new (GetAllocator()) HReturn(read_bottom); - breturn->AddInstruction(read_bottom); - breturn->AddInstruction(return_exit); + HInstruction* read_bottom = + MakeIFieldGet(breturn, new_inst, DataType::Type::kInt32, MemberOffset(32)); + MakeReturn(breturn, read_bottom); - SetupExit(exit); + MakeExit(exit); PerformLSE(blks); @@ -1922,32 +1755,23 @@ TEST_F(LoadStoreEliminationTest, PartialLoadPreserved) { HInstruction* c1 = graph_->GetIntConstant(1); HInstruction* c2 = graph_->GetIntConstant(2); - HInstruction* cls = MakeClassLoad(); - HInstruction* new_inst = MakeNewInstance(cls); - HInstruction* if_inst = new (GetAllocator()) HIf(bool_value); - entry->AddInstruction(cls); - entry->AddInstruction(new_inst); - entry->AddInstruction(if_inst); + HInstruction* cls = MakeLoadClass(entry); + HInstruction* new_inst = MakeNewInstance(entry, cls); + MakeIf(entry, bool_value); ManuallyBuildEnvFor(cls, {}); new_inst->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* write_left = MakeIFieldSet(new_inst, c1, MemberOffset(32)); - HInstruction* call_left = MakeInvoke(DataType::Type::kVoid, { new_inst }); - HInstruction* goto_left = new (GetAllocator()) HGoto(); - left->AddInstruction(write_left); - left->AddInstruction(call_left); - left->AddInstruction(goto_left); + HInstruction* write_left = MakeIFieldSet(left, new_inst, c1, MemberOffset(32)); + HInstruction* call_left = MakeInvokeStatic(left, DataType::Type::kVoid, { new_inst }); + MakeGoto(left); call_left->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* write_right = MakeIFieldSet(new_inst, c2, MemberOffset(32)); - HInstruction* goto_right = new (GetAllocator()) HGoto(); - right->AddInstruction(write_right); - right->AddInstruction(goto_right); + HInstruction* write_right = MakeIFieldSet(right, new_inst, c2, MemberOffset(32)); + MakeGoto(right); - HInstruction* read_bottom = MakeIFieldGet(new_inst, DataType::Type::kInt32, MemberOffset(32)); - HInstruction* return_exit = new (GetAllocator()) HReturn(read_bottom); - exit->AddInstruction(read_bottom); - exit->AddInstruction(return_exit); + HInstruction* read_bottom = + MakeIFieldGet(exit, new_inst, DataType::Type::kInt32, MemberOffset(32)); + MakeReturn(exit, read_bottom); PerformLSE(blks); @@ -2002,43 +1826,30 @@ TEST_F(LoadStoreEliminationTest, PartialLoadPreserved2) { HInstruction* c2 = graph_->GetIntConstant(2); HInstruction* c3 = graph_->GetIntConstant(3); - HInstruction* cls = MakeClassLoad(); - HInstruction* new_inst = MakeNewInstance(cls); - HInstruction* if_inst = new (GetAllocator()) HIf(bool_value); - entry->AddInstruction(cls); - entry->AddInstruction(new_inst); - entry->AddInstruction(if_inst); + HInstruction* cls = MakeLoadClass(entry); + HInstruction* new_inst = MakeNewInstance(entry, cls); + MakeIf(entry, bool_value); ManuallyBuildEnvFor(cls, {}); new_inst->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* write_left = MakeIFieldSet(new_inst, c1, MemberOffset(32)); - HInstruction* call_left = MakeInvoke(DataType::Type::kVoid, { new_inst }); - HInstruction* goto_left = new (GetAllocator()) HGoto(); - left->AddInstruction(write_left); - left->AddInstruction(call_left); - left->AddInstruction(goto_left); + HInstruction* write_left = MakeIFieldSet(left, new_inst, c1, MemberOffset(32)); + HInstruction* call_left = MakeInvokeStatic(left, DataType::Type::kVoid, { new_inst }); + MakeGoto(left); call_left->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* right_if = new (GetAllocator()) HIf(bool_value_2); - right_start->AddInstruction(right_if); + MakeIf(right_start, bool_value_2); - HInstruction* write_right_first = MakeIFieldSet(new_inst, c2, MemberOffset(32)); - HInstruction* goto_right_first = new (GetAllocator()) HGoto(); - right_first->AddInstruction(write_right_first); - right_first->AddInstruction(goto_right_first); + HInstruction* write_right_first = MakeIFieldSet(right_first, new_inst, c2, MemberOffset(32)); + MakeGoto(right_first); - HInstruction* write_right_second = MakeIFieldSet(new_inst, c3, MemberOffset(32)); - HInstruction* goto_right_second = new (GetAllocator()) HGoto(); - right_second->AddInstruction(write_right_second); - right_second->AddInstruction(goto_right_second); + HInstruction* write_right_second = MakeIFieldSet(right_second, new_inst, c3, MemberOffset(32)); + MakeGoto(right_second); - HInstruction* goto_right_end = new (GetAllocator()) HGoto(); - right_end->AddInstruction(goto_right_end); + MakeGoto(right_end); - HInstruction* read_bottom = MakeIFieldGet(new_inst, DataType::Type::kInt32, MemberOffset(32)); - HInstruction* return_exit = new (GetAllocator()) HReturn(read_bottom); - exit->AddInstruction(read_bottom); - exit->AddInstruction(return_exit); + HInstruction* read_bottom = + MakeIFieldGet(exit, new_inst, DataType::Type::kInt32, MemberOffset(32)); + MakeReturn(exit, read_bottom); PerformLSE(blks); @@ -2101,48 +1912,34 @@ TEST_F(LoadStoreEliminationTest, PartialLoadPreserved3) { HInstruction* c2 = graph_->GetIntConstant(2); HInstruction* c3 = graph_->GetIntConstant(3); - HInstruction* cls = MakeClassLoad(); - HInstruction* new_inst = MakeNewInstance(cls); - HInstruction* goto_entry = new (GetAllocator()) HGoto(); - entry->AddInstruction(cls); - entry->AddInstruction(new_inst); - entry->AddInstruction(goto_entry); + HInstruction* cls = MakeLoadClass(entry); + HInstruction* new_inst = MakeNewInstance(entry, cls); + MakeGoto(entry); ManuallyBuildEnvFor(cls, {}); new_inst->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* if_inst = new (GetAllocator()) HIf(bool_value); - entry_post->AddInstruction(if_inst); + MakeIf(entry_post, bool_value); - HInstruction* write_left_pre = MakeIFieldSet(new_inst, c1, MemberOffset(32)); - HInstruction* goto_left_pre = new (GetAllocator()) HGoto(); - left_pre->AddInstruction(write_left_pre); - left_pre->AddInstruction(goto_left_pre); + HInstruction* write_left_pre = MakeIFieldSet(left_pre, new_inst, c1, MemberOffset(32)); + MakeGoto(left_pre); - HInstruction* suspend_left_loop = new (GetAllocator()) HSuspendCheck(); - HInstruction* call_left_loop = MakeInvoke(DataType::Type::kBool, {new_inst}); - HInstruction* if_left_loop = new (GetAllocator()) HIf(call_left_loop); - left_loop->AddInstruction(suspend_left_loop); - left_loop->AddInstruction(call_left_loop); - left_loop->AddInstruction(if_left_loop); + HInstruction* suspend_left_loop = MakeSuspendCheck(left_loop); + HInstruction* call_left_loop = MakeInvokeStatic(left_loop, DataType::Type::kBool, {new_inst}); + MakeIf(left_loop, call_left_loop); suspend_left_loop->CopyEnvironmentFrom(cls->GetEnvironment()); call_left_loop->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* write_left_loop = MakeIFieldSet(new_inst, c3, MemberOffset(32)); - HInstruction* goto_left_loop = new (GetAllocator()) HGoto(); - left_loop_post->AddInstruction(write_left_loop); - left_loop_post->AddInstruction(goto_left_loop); + HInstruction* write_left_loop = MakeIFieldSet(left_loop_post, new_inst, c3, MemberOffset(32)); + MakeGoto(left_loop_post); - HInstruction* write_right = MakeIFieldSet(new_inst, c2, MemberOffset(32)); - HInstruction* goto_right = new (GetAllocator()) HGoto(); - right->AddInstruction(write_right); - right->AddInstruction(goto_right); + HInstruction* write_right = MakeIFieldSet(right, new_inst, c2, MemberOffset(32)); + MakeGoto(right); - HInstruction* read_return = MakeIFieldGet(new_inst, DataType::Type::kInt32, MemberOffset(32)); - HInstruction* return_final = new (GetAllocator()) HReturn(read_return); - return_block->AddInstruction(read_return); - return_block->AddInstruction(return_final); + HInstruction* read_return = + MakeIFieldGet(return_block, new_inst, DataType::Type::kInt32, MemberOffset(32)); + MakeReturn(return_block, read_return); - SetupExit(exit); + MakeExit(exit); PerformLSE(blks); @@ -2207,48 +2004,34 @@ TEST_F(LoadStoreEliminationTest, DISABLED_PartialLoadPreserved4) { HInstruction* c2 = graph_->GetIntConstant(2); HInstruction* c3 = graph_->GetIntConstant(3); - HInstruction* cls = MakeClassLoad(); - HInstruction* new_inst = MakeNewInstance(cls); - HInstruction* goto_entry = new (GetAllocator()) HGoto(); - entry->AddInstruction(cls); - entry->AddInstruction(new_inst); - entry->AddInstruction(goto_entry); + HInstruction* cls = MakeLoadClass(entry); + HInstruction* new_inst = MakeNewInstance(entry, cls); + MakeGoto(entry); ManuallyBuildEnvFor(cls, {}); new_inst->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* if_inst = new (GetAllocator()) HIf(bool_value); - entry_post->AddInstruction(if_inst); - - HInstruction* write_left_pre = MakeIFieldSet(new_inst, c1, MemberOffset(32)); - HInstruction* goto_left_pre = new (GetAllocator()) HGoto(); - left_pre->AddInstruction(write_left_pre); - left_pre->AddInstruction(goto_left_pre); - - HInstruction* suspend_left_loop = new (GetAllocator()) HSuspendCheck(); - HInstruction* call_left_loop = MakeInvoke(DataType::Type::kBool, {}); - HInstruction* write_left_loop = MakeIFieldSet(new_inst, c3, MemberOffset(32)); - HInstruction* if_left_loop = new (GetAllocator()) HIf(call_left_loop); - left_loop->AddInstruction(suspend_left_loop); - left_loop->AddInstruction(call_left_loop); - left_loop->AddInstruction(write_left_loop); - left_loop->AddInstruction(if_left_loop); + MakeIf(entry_post, bool_value); + + HInstruction* write_left_pre = MakeIFieldSet(left_pre, new_inst, c1, MemberOffset(32)); + MakeGoto(left_pre); + + HInstruction* suspend_left_loop = MakeSuspendCheck(left_loop); + HInstruction* call_left_loop = MakeInvokeStatic(left_loop, DataType::Type::kBool, {}); + HInstruction* write_left_loop = MakeIFieldSet(left_loop, new_inst, c3, MemberOffset(32)); + MakeIf(left_loop, call_left_loop); suspend_left_loop->CopyEnvironmentFrom(cls->GetEnvironment()); call_left_loop->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* write_right = MakeIFieldSet(new_inst, c2, MemberOffset(32)); - HInstruction* call_right = MakeInvoke(DataType::Type::kBool, {new_inst}); - HInstruction* goto_right = new (GetAllocator()) HGoto(); - right->AddInstruction(write_right); - right->AddInstruction(call_right); - right->AddInstruction(goto_right); + HInstruction* write_right = MakeIFieldSet(right, new_inst, c2, MemberOffset(32)); + HInstruction* call_right = MakeInvokeStatic(right, DataType::Type::kBool, {new_inst}); + MakeGoto(right); call_right->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* read_return = MakeIFieldGet(new_inst, DataType::Type::kInt32, MemberOffset(32)); - HInstruction* return_final = new (GetAllocator()) HReturn(read_return); - return_block->AddInstruction(read_return); - return_block->AddInstruction(return_final); + HInstruction* read_return = + MakeIFieldGet(return_block, new_inst, DataType::Type::kInt32, MemberOffset(32)); + MakeReturn(return_block, read_return); - SetupExit(exit); + MakeExit(exit); PerformLSE(blks); @@ -2301,40 +2084,29 @@ TEST_F(LoadStoreEliminationTest, PartialLoadPreserved5) { HInstruction* c1 = graph_->GetIntConstant(1); HInstruction* c2 = graph_->GetIntConstant(2); - HInstruction* cls = MakeClassLoad(); - HInstruction* new_inst = MakeNewInstance(cls); - HInstruction* if_inst = new (GetAllocator()) HIf(bool_value); - entry->AddInstruction(cls); - entry->AddInstruction(new_inst); - entry->AddInstruction(if_inst); + HInstruction* cls = MakeLoadClass(entry); + HInstruction* new_inst = MakeNewInstance(entry, cls); + MakeIf(entry, bool_value); ManuallyBuildEnvFor(cls, {}); new_inst->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* call_left = MakeInvoke(DataType::Type::kVoid, { new_inst }); - HInstruction* write_left = MakeIFieldSet(new_inst, c1, MemberOffset(32)); - HInstruction* call2_left = MakeInvoke(DataType::Type::kVoid, {}); - HInstruction* goto_left = new (GetAllocator()) HGoto(); - left->AddInstruction(call_left); - left->AddInstruction(write_left); - left->AddInstruction(call2_left); - left->AddInstruction(goto_left); + HInstruction* call_left = MakeInvokeStatic(left, DataType::Type::kVoid, { new_inst }); + HInstruction* write_left = MakeIFieldSet(left, new_inst, c1, MemberOffset(32)); + HInstruction* call2_left = MakeInvokeStatic(left, DataType::Type::kVoid, {}); + MakeGoto(left); call_left->CopyEnvironmentFrom(cls->GetEnvironment()); call2_left->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* write_right = MakeIFieldSet(new_inst, c2, MemberOffset(32)); - HInstruction* call_right = MakeInvoke(DataType::Type::kVoid, {}); - HInstruction* goto_right = new (GetAllocator()) HGoto(); - right->AddInstruction(write_right); - right->AddInstruction(call_right); - right->AddInstruction(goto_right); + HInstruction* write_right = MakeIFieldSet(right, new_inst, c2, MemberOffset(32)); + HInstruction* call_right = MakeInvokeStatic(right, DataType::Type::kVoid, {}); + MakeGoto(right); call_right->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* read_bottom = MakeIFieldGet(new_inst, DataType::Type::kInt32, MemberOffset(32)); - HInstruction* return_exit = new (GetAllocator()) HReturn(read_bottom); - breturn->AddInstruction(read_bottom); - breturn->AddInstruction(return_exit); + HInstruction* read_bottom = + MakeIFieldGet(breturn, new_inst, DataType::Type::kInt32, MemberOffset(32)); + MakeReturn(breturn, read_bottom); - SetupExit(exit); + MakeExit(exit); PerformLSE(blks); @@ -2385,39 +2157,28 @@ TEST_F(LoadStoreEliminationTest, DISABLED_PartialLoadPreserved6) { HInstruction* c2 = graph_->GetIntConstant(2); HInstruction* c3 = graph_->GetIntConstant(3); - HInstruction* cls = MakeClassLoad(); - HInstruction* new_inst = MakeNewInstance(cls); - HInstruction* write_entry = MakeIFieldSet(new_inst, c3, MemberOffset(32)); - HInstruction* call_entry = MakeInvoke(DataType::Type::kVoid, {}); - HInstruction* if_inst = new (GetAllocator()) HIf(bool_value); - entry->AddInstruction(cls); - entry->AddInstruction(new_inst); - entry->AddInstruction(write_entry); - entry->AddInstruction(call_entry); - entry->AddInstruction(if_inst); + HInstruction* cls = MakeLoadClass(entry); + HInstruction* new_inst = MakeNewInstance(entry, cls); + HInstruction* write_entry = MakeIFieldSet(entry, new_inst, c3, MemberOffset(32)); + HInstruction* call_entry = MakeInvokeStatic(entry, DataType::Type::kVoid, {}); + MakeIf(entry, bool_value); ManuallyBuildEnvFor(cls, {}); new_inst->CopyEnvironmentFrom(cls->GetEnvironment()); call_entry->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* call_left = MakeInvoke(DataType::Type::kVoid, { new_inst }); - HInstruction* write_left = MakeIFieldSet(new_inst, c1, MemberOffset(32)); - HInstruction* goto_left = new (GetAllocator()) HGoto(); - left->AddInstruction(call_left); - left->AddInstruction(write_left); - left->AddInstruction(goto_left); + HInstruction* call_left = MakeInvokeStatic(left, DataType::Type::kVoid, { new_inst }); + HInstruction* write_left = MakeIFieldSet(left, new_inst, c1, MemberOffset(32)); + MakeGoto(left); call_left->CopyEnvironmentFrom(cls->GetEnvironment()); - HInstruction* write_right = MakeIFieldSet(new_inst, c2, MemberOffset(32)); - HInstruction* goto_right = new (GetAllocator()) HGoto(); - right->AddInstruction(write_right); - right->AddInstruction(goto_right); + HInstruction* write_right = MakeIFieldSet(right, new_inst, c2, MemberOffset(32)); + MakeGoto(right); - HInstruction* read_bottom = MakeIFieldGet(new_inst, DataType::Type::kInt32, MemberOffset(32)); - HInstruction* return_exit = new (GetAllocator()) HReturn(read_bottom); - breturn->AddInstruction(read_bottom); - breturn->AddInstruction(return_exit); + HInstruction* read_bottom = + MakeIFieldGet(breturn, new_inst, DataType::Type::kInt32, MemberOffset(32)); + MakeReturn(breturn, read_bottom); - SetupExit(exit); + MakeExit(exit); PerformLSE(blks); diff --git a/compiler/optimizing/loop_optimization_test.cc b/compiler/optimizing/loop_optimization_test.cc index 7f694fb655..81867beb4b 100644 --- a/compiler/optimizing/loop_optimization_test.cc +++ b/compiler/optimizing/loop_optimization_test.cc @@ -64,13 +64,9 @@ class LoopOptimizationTest : public OptimizingUnitTest { graph_->AddBlock(exit_block_); graph_->SetEntryBlock(entry_block_); graph_->SetExitBlock(exit_block_); - parameter_ = new (GetAllocator()) HParameterValue(graph_->GetDexFile(), - dex::TypeIndex(0), - 0, - DataType::Type::kInt32); - entry_block_->AddInstruction(parameter_); - return_block_->AddInstruction(new (GetAllocator()) HReturnVoid()); - exit_block_->AddInstruction(new (GetAllocator()) HExit()); + parameter_ = MakeParam(DataType::Type::kInt32); + MakeReturnVoid(return_block_); + MakeExit(exit_block_); entry_block_->AddSuccessor(return_block_); return_block_->AddSuccessor(exit_block_); } @@ -85,9 +81,9 @@ class LoopOptimizationTest : public OptimizingUnitTest { position->ReplaceSuccessor(successor, header); header->AddSuccessor(body); header->AddSuccessor(successor); - header->AddInstruction(new (GetAllocator()) HIf(parameter_)); + MakeIf(header, parameter_); body->AddSuccessor(header); - body->AddInstruction(new (GetAllocator()) HGoto()); + MakeGoto(body); return header; } @@ -230,13 +226,12 @@ TEST_F(LoopOptimizationTest, SimplifyLoopReoderPredecessors) { DCHECK(header->GetSuccessors()[1] == return_block_); // Data flow. - header->AddInstruction(new (GetAllocator()) HIf(parameter_)); - body->AddInstruction(new (GetAllocator()) HGoto()); + MakeIf(header, parameter_); + MakeGoto(body); HPhi* phi = new (GetAllocator()) HPhi(GetAllocator(), 0, 0, DataType::Type::kInt32); - HInstruction* add = new (GetAllocator()) HAdd(DataType::Type::kInt32, phi, parameter_); header->AddPhi(phi); - body->AddInstruction(add); + HInstruction* add = MakeBinOp<HAdd>(body, DataType::Type::kInt32, phi, parameter_); phi->AddInput(add); phi->AddInput(parameter_); @@ -281,9 +276,9 @@ TEST_F(LoopOptimizationTest, SimplifyLoopSinglePreheader) { preheader0->AddSuccessor(header); preheader1->AddSuccessor(header); - if_block->AddInstruction(new (GetAllocator()) HIf(parameter_)); - preheader0->AddInstruction(new (GetAllocator()) HGoto()); - preheader1->AddInstruction(new (GetAllocator()) HGoto()); + MakeIf(if_block, parameter_); + MakeGoto(preheader0); + MakeGoto(preheader1); HBasicBlock* body = header->GetSuccessors()[0]; DCHECK(body != return_block_); @@ -293,16 +288,13 @@ TEST_F(LoopOptimizationTest, SimplifyLoopSinglePreheader) { HIntConstant* const_1 = graph_->GetIntConstant(1); HIntConstant* const_2 = graph_->GetIntConstant(2); - HAdd* preheader0_add = new (GetAllocator()) HAdd(DataType::Type::kInt32, parameter_, const_0); - preheader0->AddInstruction(preheader0_add); - HAdd* preheader1_add = new (GetAllocator()) HAdd(DataType::Type::kInt32, parameter_, const_1); - preheader1->AddInstruction(preheader1_add); + HAdd* preheader0_add = MakeBinOp<HAdd>(preheader0, DataType::Type::kInt32, parameter_, const_0); + HAdd* preheader1_add = MakeBinOp<HAdd>(preheader1, DataType::Type::kInt32, parameter_, const_1); HPhi* header_phi = new (GetAllocator()) HPhi(GetAllocator(), 0, 0, DataType::Type::kInt32); header->AddPhi(header_phi); - HAdd* body_add = new (GetAllocator()) HAdd(DataType::Type::kInt32, parameter_, const_2); - body->AddInstruction(body_add); + HAdd* body_add = MakeBinOp<HAdd>(body, DataType::Type::kInt32, parameter_, const_2); DCHECK(header->GetPredecessors()[0] == body); DCHECK(header->GetPredecessors()[1] == preheader0); diff --git a/compiler/optimizing/nodes_test.cc b/compiler/optimizing/nodes_test.cc index 29210fe10f..ce4ad848dd 100644 --- a/compiler/optimizing/nodes_test.cc +++ b/compiler/optimizing/nodes_test.cc @@ -147,22 +147,19 @@ TEST_F(NodeTest, RemoveInstruction) { HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(entry); graph->SetEntryBlock(entry); - HInstruction* parameter = new (GetAllocator()) HParameterValue( - graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); - entry->AddInstruction(parameter); - entry->AddInstruction(new (GetAllocator()) HGoto()); + HInstruction* parameter = MakeParam(DataType::Type::kReference); + MakeGoto(entry); HBasicBlock* first_block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(first_block); entry->AddSuccessor(first_block); - HInstruction* null_check = new (GetAllocator()) HNullCheck(parameter, 0); - first_block->AddInstruction(null_check); - first_block->AddInstruction(new (GetAllocator()) HReturnVoid()); + HInstruction* null_check = MakeNullCheck(first_block, parameter); + MakeReturnVoid(first_block); HBasicBlock* exit_block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(exit_block); first_block->AddSuccessor(exit_block); - exit_block->AddInstruction(new (GetAllocator()) HExit()); + MakeExit(exit_block); HEnvironment* environment = new (GetAllocator()) HEnvironment( GetAllocator(), 1, graph->GetArtMethod(), 0, null_check); @@ -187,13 +184,9 @@ TEST_F(NodeTest, InsertInstruction) { HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(entry); graph->SetEntryBlock(entry); - HInstruction* parameter1 = new (GetAllocator()) HParameterValue( - graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); - HInstruction* parameter2 = new (GetAllocator()) HParameterValue( - graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); - entry->AddInstruction(parameter1); - entry->AddInstruction(parameter2); - entry->AddInstruction(new (GetAllocator()) HExit()); + HInstruction* parameter1 = MakeParam(DataType::Type::kReference); + HInstruction* parameter2 = MakeParam(DataType::Type::kReference); + MakeExit(entry); ASSERT_FALSE(parameter1->HasUses()); @@ -212,14 +205,11 @@ TEST_F(NodeTest, AddInstruction) { HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(entry); graph->SetEntryBlock(entry); - HInstruction* parameter = new (GetAllocator()) HParameterValue( - graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); - entry->AddInstruction(parameter); + HInstruction* parameter = MakeParam(DataType::Type::kReference); ASSERT_FALSE(parameter->HasUses()); - HInstruction* to_add = new (GetAllocator()) HNullCheck(parameter, 0); - entry->AddInstruction(to_add); + MakeNullCheck(entry, parameter); ASSERT_TRUE(parameter->HasUses()); ASSERT_TRUE(parameter->GetUses().HasExactlyOneElement()); @@ -230,12 +220,9 @@ TEST_F(NodeTest, ParentEnvironment) { HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(entry); graph->SetEntryBlock(entry); - HInstruction* parameter1 = new (GetAllocator()) HParameterValue( - graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); - HInstruction* with_environment = new (GetAllocator()) HNullCheck(parameter1, 0); - entry->AddInstruction(parameter1); - entry->AddInstruction(with_environment); - entry->AddInstruction(new (GetAllocator()) HExit()); + HInstruction* parameter1 = MakeParam(DataType::Type::kReference); + HInstruction* with_environment = MakeNullCheck(entry, parameter1); + MakeExit(entry); ASSERT_TRUE(parameter1->HasUses()); ASSERT_TRUE(parameter1->GetUses().HasExactlyOneElement()); diff --git a/compiler/optimizing/nodes_vector_test.cc b/compiler/optimizing/nodes_vector_test.cc index e0a48db84f..6120c11d45 100644 --- a/compiler/optimizing/nodes_vector_test.cc +++ b/compiler/optimizing/nodes_vector_test.cc @@ -41,21 +41,9 @@ class NodesVectorTest : public OptimizingUnitTest { graph_->AddBlock(exit_block_); graph_->SetEntryBlock(entry_block_); graph_->SetExitBlock(exit_block_); - int8_parameter_ = new (GetAllocator()) HParameterValue(graph_->GetDexFile(), - dex::TypeIndex(1), - 0, - DataType::Type::kInt8); - entry_block_->AddInstruction(int8_parameter_); - int16_parameter_ = new (GetAllocator()) HParameterValue(graph_->GetDexFile(), - dex::TypeIndex(2), - 0, - DataType::Type::kInt16); - entry_block_->AddInstruction(int16_parameter_); - int32_parameter_ = new (GetAllocator()) HParameterValue(graph_->GetDexFile(), - dex::TypeIndex(0), - 0, - DataType::Type::kInt32); - entry_block_->AddInstruction(int32_parameter_); + int8_parameter_ = MakeParam(DataType::Type::kInt8); + int16_parameter_ = MakeParam(DataType::Type::kInt16); + int32_parameter_ = MakeParam(DataType::Type::kInt32); } // General building fields. diff --git a/compiler/optimizing/optimizing_unit_test.h b/compiler/optimizing/optimizing_unit_test.h index e1d8969b2b..b256d439fb 100644 --- a/compiler/optimizing/optimizing_unit_test.h +++ b/compiler/optimizing/optimizing_unit_test.h @@ -306,11 +306,6 @@ class OptimizingUnitTestHelper { exit_block_->AddInstruction(new (GetAllocator()) HExit()); } - void AddParameter(HInstruction* parameter) { - entry_block_->AddInstruction(parameter); - parameters_.push_back(parameter); - } - HBasicBlock* AddNewBlock() { HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(block); @@ -391,68 +386,167 @@ class OptimizingUnitTestHelper { OptimizingUnitTestHelper::ManuallyBuildEnvFor(ins, ¤t_locals); } - HLoadClass* MakeClassLoad(std::optional<dex::TypeIndex> ti = std::nullopt, - std::optional<Handle<mirror::Class>> klass = std::nullopt) { - return new (GetAllocator()) HLoadClass(graph_->GetCurrentMethod(), - ti ? *ti : dex::TypeIndex(class_idx_++), - graph_->GetDexFile(), - /* klass= */ klass ? *klass : null_klass_, - /* is_referrers_class= */ false, - /* dex_pc= */ 0, - /* needs_access_check= */ false); + HLoadClass* MakeLoadClass(HBasicBlock* block, + std::optional<dex::TypeIndex> ti = std::nullopt, + std::optional<Handle<mirror::Class>> klass = std::nullopt, + uint32_t dex_pc = kNoDexPc) { + HLoadClass* load_class = new (GetAllocator()) HLoadClass( + graph_->GetCurrentMethod(), + ti ? *ti : dex::TypeIndex(class_idx_++), + graph_->GetDexFile(), + /* klass= */ klass ? *klass : null_klass_, + /* is_referrers_class= */ false, + dex_pc, + /* needs_access_check= */ false); + AddOrInsertInstruction(block, load_class); + return load_class; } - HNewInstance* MakeNewInstance(HInstruction* cls, uint32_t dex_pc = 0u) { + HNewInstance* MakeNewInstance(HBasicBlock* block, HInstruction* cls, uint32_t dex_pc = kNoDexPc) { EXPECT_TRUE(cls->IsLoadClass() || cls->IsClinitCheck()) << *cls; HLoadClass* load = cls->IsLoadClass() ? cls->AsLoadClass() : cls->AsClinitCheck()->GetLoadClass(); - return new (GetAllocator()) HNewInstance(cls, - dex_pc, - load->GetTypeIndex(), - graph_->GetDexFile(), - /* finalizable= */ false, - QuickEntrypointEnum::kQuickAllocObjectInitialized); + HNewInstance* new_instance = new (GetAllocator()) HNewInstance( + cls, + dex_pc, + load->GetTypeIndex(), + graph_->GetDexFile(), + /* finalizable= */ false, + QuickEntrypointEnum::kQuickAllocObjectInitialized); + AddOrInsertInstruction(block, new_instance); + return new_instance; + } + + HInstanceFieldSet* MakeIFieldSet(HBasicBlock* block, + HInstruction* inst, + HInstruction* data, + MemberOffset off, + uint32_t dex_pc = kNoDexPc) { + CHECK(data != nullptr); + return MakeIFieldSet(block, inst, data, data->GetType(), off, dex_pc); } - HInstanceFieldSet* MakeIFieldSet(HInstruction* inst, + HInstanceFieldSet* MakeIFieldSet(HBasicBlock* block, + HInstruction* inst, HInstruction* data, + DataType::Type field_type, MemberOffset off, - uint32_t dex_pc = 0u) { - return new (GetAllocator()) HInstanceFieldSet(inst, - data, - /* field= */ nullptr, - /* field_type= */ data->GetType(), - /* field_offset= */ off, - /* is_volatile= */ false, - /* field_idx= */ 0, - /* declaring_class_def_index= */ 0, - graph_->GetDexFile(), - dex_pc); - } - - HInstanceFieldGet* MakeIFieldGet(HInstruction* inst, + uint32_t dex_pc = kNoDexPc) { + HInstanceFieldSet* ifield_set = new (GetAllocator()) HInstanceFieldSet( + inst, + data, + /* field= */ nullptr, + field_type, + /* field_offset= */ off, + /* is_volatile= */ false, + kUnknownFieldIndex, + kUnknownClassDefIndex, + graph_->GetDexFile(), + dex_pc); + AddOrInsertInstruction(block, ifield_set); + return ifield_set; + } + + HInstanceFieldGet* MakeIFieldGet(HBasicBlock* block, + HInstruction* inst, DataType::Type type, MemberOffset off, - uint32_t dex_pc = 0u) { - return new (GetAllocator()) HInstanceFieldGet(inst, - /* field= */ nullptr, - /* field_type= */ type, - /* field_offset= */ off, - /* is_volatile= */ false, - /* field_idx= */ 0, - /* declaring_class_def_index= */ 0, - graph_->GetDexFile(), - dex_pc); - } - - HInvokeStaticOrDirect* MakeInvoke(DataType::Type return_type, - const std::vector<HInstruction*>& args) { + uint32_t dex_pc = kNoDexPc) { + HInstanceFieldGet* ifield_get = new (GetAllocator()) HInstanceFieldGet( + inst, + /* field= */ nullptr, + /* field_type= */ type, + /* field_offset= */ off, + /* is_volatile= */ false, + kUnknownFieldIndex, + kUnknownClassDefIndex, + graph_->GetDexFile(), + dex_pc); + AddOrInsertInstruction(block, ifield_get); + return ifield_get; + } + + HNewArray* MakeNewArray(HBasicBlock* block, + HInstruction* cls, + HInstruction* length, + size_t component_size_shift = DataType::SizeShift(DataType::Type::kInt32), + uint32_t dex_pc = kNoDexPc) { + HNewArray* new_array = + new (GetAllocator()) HNewArray(cls, length, dex_pc, component_size_shift); + AddOrInsertInstruction(block, new_array); + return new_array; + } + + HArraySet* MakeArraySet(HBasicBlock* block, + HInstruction* array, + HInstruction* index, + HInstruction* value, + DataType::Type type, + uint32_t dex_pc = kNoDexPc) { + HArraySet* array_set = new (GetAllocator()) HArraySet(array, index, value, type, dex_pc); + AddOrInsertInstruction(block, array_set); + return array_set; + } + + HArrayGet* MakeArrayGet(HBasicBlock* block, + HInstruction* array, + HInstruction* index, + DataType::Type type, + uint32_t dex_pc = kNoDexPc) { + HArrayGet* array_get = new (GetAllocator()) HArrayGet(array, index, type, dex_pc); + AddOrInsertInstruction(block, array_get); + return array_get; + } + + HArrayLength* MakeArrayLength(HBasicBlock* block, + HInstruction* array, + uint32_t dex_pc = kNoDexPc) { + HArrayLength* array_length = new (GetAllocator()) HArrayLength(array, dex_pc); + AddOrInsertInstruction(block, array_length); + return array_length; + } + + HNullCheck* MakeNullCheck(HBasicBlock* block, + HInstruction* value, + uint32_t dex_pc = kNoDexPc) { + HNullCheck* null_check = new (GetAllocator()) HNullCheck(value, dex_pc); + AddOrInsertInstruction(block, null_check); + return null_check; + } + + HBoundsCheck* MakeBoundsCheck(HBasicBlock* block, + HInstruction* index, + HInstruction* length, + uint32_t dex_pc = kNoDexPc) { + HBoundsCheck* bounds_check = new (GetAllocator()) HBoundsCheck(index, length, dex_pc); + AddOrInsertInstruction(block, bounds_check); + return bounds_check; + } + + HVecStore* MakeVecStore(HBasicBlock* block, + HInstruction* base, + HInstruction* index, + HInstruction* value, + DataType::Type packed_type, + size_t vector_length = 4, + uint32_t dex_pc = kNoDexPc) { + SideEffects side_effects = SideEffects::ArrayWriteOfType(packed_type); + HVecStore* vec_store = new (GetAllocator()) HVecStore( + GetAllocator(), base, index, value, packed_type, side_effects, vector_length, dex_pc); + AddOrInsertInstruction(block, vec_store); + return vec_store; + } + + HInvokeStaticOrDirect* MakeInvokeStatic(HBasicBlock* block, + DataType::Type return_type, + const std::vector<HInstruction*>& args, + uint32_t dex_pc = kNoDexPc) { MethodReference method_reference{/* file= */ &graph_->GetDexFile(), /* index= */ method_idx_++}; - HInvokeStaticOrDirect* res = new (GetAllocator()) + HInvokeStaticOrDirect* invoke = new (GetAllocator()) HInvokeStaticOrDirect(GetAllocator(), args.size(), return_type, - /* dex_pc= */ 0, + dex_pc, method_reference, /* resolved_method= */ nullptr, HInvokeStaticOrDirect::DispatchInfo{}, @@ -461,25 +555,91 @@ class OptimizingUnitTestHelper { HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, !graph_->IsDebuggable()); for (auto [ins, idx] : ZipCount(MakeIterationRange(args))) { - res->SetRawInputAt(idx, ins); + invoke->SetRawInputAt(idx, ins); + } + AddOrInsertInstruction(block, invoke); + return invoke; + } + + template <typename Type> + Type* MakeBinOp(HBasicBlock* block, + DataType::Type result_type, + HInstruction* left, + HInstruction* right, + uint32_t dex_pc = kNoDexPc) { + static_assert(std::is_base_of_v<HBinaryOperation, Type>); + Type* insn = new (GetAllocator()) Type(result_type, left, right, dex_pc); + AddOrInsertInstruction(block, insn); + return insn; + } + + template <typename Type> + Type* MakeCondition(HBasicBlock* block, + HInstruction* first, + HInstruction* second, + uint32_t dex_pc = kNoDexPc) { + static_assert(std::is_base_of_v<HCondition, Type>); + Type* condition = new (GetAllocator()) Type(first, second, dex_pc); + AddOrInsertInstruction(block, condition); + return condition; + } + + HSuspendCheck* MakeSuspendCheck(HBasicBlock* block, uint32_t dex_pc = kNoDexPc) { + HSuspendCheck* suspend_check = new (GetAllocator()) HSuspendCheck(dex_pc); + AddOrInsertInstruction(block, suspend_check); + return suspend_check; + } + + void AddOrInsertInstruction(HBasicBlock* block, HInstruction* instruction) { + CHECK(!instruction->IsControlFlow()); + if (block->GetLastInstruction() != nullptr && block->GetLastInstruction()->IsControlFlow()) { + block->InsertInstructionBefore(instruction, block->GetLastInstruction()); + } else { + block->AddInstruction(instruction); } - return res; } - HPhi* MakePhi(const std::vector<HInstruction*>& ins) { + HIf* MakeIf(HBasicBlock* block, HInstruction* cond, uint32_t dex_pc = kNoDexPc) { + HIf* if_insn = new (GetAllocator()) HIf(cond, dex_pc); + block->AddInstruction(if_insn); + return if_insn; + } + + HGoto* MakeGoto(HBasicBlock* block, uint32_t dex_pc = kNoDexPc) { + HGoto* goto_insn = new (GetAllocator()) HGoto(dex_pc); + block->AddInstruction(goto_insn); + return goto_insn; + } + + HReturnVoid* MakeReturnVoid(HBasicBlock* block, uint32_t dex_pc = kNoDexPc) { + HReturnVoid* return_void = new (GetAllocator()) HReturnVoid(dex_pc); + block->AddInstruction(return_void); + return return_void; + } + + HReturn* MakeReturn(HBasicBlock* block, HInstruction* value, uint32_t dex_pc = kNoDexPc) { + HReturn* return_insn = new (GetAllocator()) HReturn(value, dex_pc); + block->AddInstruction(return_insn); + return return_insn; + } + + HExit* MakeExit(HBasicBlock* exit_block) { + HExit* exit = new (GetAllocator()) HExit(); + exit_block->AddInstruction(exit); + return exit; + } + + HPhi* MakePhi(HBasicBlock* block, const std::vector<HInstruction*>& ins) { EXPECT_GE(ins.size(), 2u) << "Phi requires at least 2 inputs"; HPhi* phi = new (GetAllocator()) HPhi(GetAllocator(), kNoRegNumber, ins.size(), ins[0]->GetType()); for (auto [i, idx] : ZipCount(MakeIterationRange(ins))) { phi->SetRawInputAt(idx, i); } + block->AddPhi(phi); return phi; } - void SetupExit(HBasicBlock* exit) { - exit->AddInstruction(new (GetAllocator()) HExit()); - } - dex::TypeIndex DefaultTypeIndexForType(DataType::Type type) { switch (type) { case DataType::Type::kBool: @@ -508,7 +668,7 @@ class OptimizingUnitTestHelper { } } - // Creates a parameter. The instruction is automatically added to the entry-block + // Creates a parameter. The instruction is automatically added to the entry-block. HParameterValue* MakeParam(DataType::Type type, std::optional<dex::TypeIndex> ti = std::nullopt) { HParameterValue* val = new (GetAllocator()) HParameterValue( graph_->GetDexFile(), ti ? *ti : DefaultTypeIndexForType(type), param_count_++, type); @@ -532,8 +692,6 @@ class OptimizingUnitTestHelper { HBasicBlock* return_block_; HBasicBlock* exit_block_; - std::vector<HInstruction*> parameters_; - size_t param_count_ = 0; size_t class_idx_ = 42; uint32_t method_idx_ = 100; diff --git a/compiler/optimizing/register_allocator_test.cc b/compiler/optimizing/register_allocator_test.cc index 8f1e724569..e5eb54c2c2 100644 --- a/compiler/optimizing/register_allocator_test.cc +++ b/compiler/optimizing/register_allocator_test.cc @@ -461,25 +461,15 @@ HGraph* RegisterAllocatorTest::BuildIfElseWithPhi(HPhi** phi, HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(entry); graph->SetEntryBlock(entry); - HInstruction* parameter = new (GetAllocator()) HParameterValue( - graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); - entry->AddInstruction(parameter); + HInstruction* parameter = MakeParam(DataType::Type::kReference); HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(block); entry->AddSuccessor(block); - HInstruction* test = new (GetAllocator()) HInstanceFieldGet(parameter, - nullptr, - DataType::Type::kBool, - MemberOffset(22), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0); - block->AddInstruction(test); - block->AddInstruction(new (GetAllocator()) HIf(test)); + HInstruction* test = MakeIFieldGet(block, parameter, DataType::Type::kBool, MemberOffset(22)); + MakeIf(block, test); + HBasicBlock* then = new (GetAllocator()) HBasicBlock(graph); HBasicBlock* else_ = new (GetAllocator()) HBasicBlock(graph); HBasicBlock* join = new (GetAllocator()) HBasicBlock(graph); @@ -491,34 +481,14 @@ HGraph* RegisterAllocatorTest::BuildIfElseWithPhi(HPhi** phi, block->AddSuccessor(else_); then->AddSuccessor(join); else_->AddSuccessor(join); - then->AddInstruction(new (GetAllocator()) HGoto()); - else_->AddInstruction(new (GetAllocator()) HGoto()); - - *phi = new (GetAllocator()) HPhi(GetAllocator(), 0, 0, DataType::Type::kInt32); - join->AddPhi(*phi); - *input1 = new (GetAllocator()) HInstanceFieldGet(parameter, - nullptr, - DataType::Type::kInt32, - MemberOffset(42), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0); - *input2 = new (GetAllocator()) HInstanceFieldGet(parameter, - nullptr, - DataType::Type::kInt32, - MemberOffset(42), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0); - then->AddInstruction(*input1); - else_->AddInstruction(*input2); - join->AddInstruction(new (GetAllocator()) HExit()); - (*phi)->AddInput(*input1); - (*phi)->AddInput(*input2); + MakeGoto(then); + MakeGoto(else_); + + *input1 = MakeIFieldGet(then, parameter, DataType::Type::kInt32, MemberOffset(42)); + *input2 = MakeIFieldGet(else_, parameter, DataType::Type::kInt32, MemberOffset(42)); + + *phi = MakePhi(join, {*input1, *input2}); + MakeExit(join); graph->BuildDominatorTree(); graph->AnalyzeLoops(); @@ -605,31 +575,19 @@ HGraph* RegisterAllocatorTest::BuildFieldReturn(HInstruction** field, HInstructi HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(entry); graph->SetEntryBlock(entry); - HInstruction* parameter = new (GetAllocator()) HParameterValue( - graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); - entry->AddInstruction(parameter); + HInstruction* parameter = MakeParam(DataType::Type::kReference); HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(block); entry->AddSuccessor(block); - *field = new (GetAllocator()) HInstanceFieldGet(parameter, - nullptr, - DataType::Type::kInt32, - MemberOffset(42), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph->GetDexFile(), - 0); - block->AddInstruction(*field); - *ret = new (GetAllocator()) HReturn(*field); - block->AddInstruction(*ret); + *field = MakeIFieldGet(block, parameter, DataType::Type::kInt32, MemberOffset(42)); + *ret = MakeReturn(block, *field); HBasicBlock* exit = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(exit); block->AddSuccessor(exit); - exit->AddInstruction(new (GetAllocator()) HExit()); + MakeExit(exit); graph->BuildDominatorTree(); return graph; @@ -675,9 +633,7 @@ HGraph* RegisterAllocatorTest::BuildTwoSubs(HInstruction** first_sub, HInstructi HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(entry); graph->SetEntryBlock(entry); - HInstruction* parameter = new (GetAllocator()) HParameterValue( - graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kInt32); - entry->AddInstruction(parameter); + HInstruction* parameter = MakeParam(DataType::Type::kInt32); HInstruction* constant1 = graph->GetIntConstant(1); HInstruction* constant2 = graph->GetIntConstant(2); @@ -691,7 +647,7 @@ HGraph* RegisterAllocatorTest::BuildTwoSubs(HInstruction** first_sub, HInstructi *second_sub = new (GetAllocator()) HSub(DataType::Type::kInt32, *first_sub, constant2); block->AddInstruction(*second_sub); - block->AddInstruction(new (GetAllocator()) HExit()); + MakeExit(block); graph->BuildDominatorTree(); return graph; @@ -741,12 +697,8 @@ HGraph* RegisterAllocatorTest::BuildDiv(HInstruction** div) { HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(entry); graph->SetEntryBlock(entry); - HInstruction* first = new (GetAllocator()) HParameterValue( - graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kInt32); - HInstruction* second = new (GetAllocator()) HParameterValue( - graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kInt32); - entry->AddInstruction(first); - entry->AddInstruction(second); + HInstruction* first = MakeParam(DataType::Type::kInt32); + HInstruction* second = MakeParam(DataType::Type::kInt32); HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(block); @@ -756,7 +708,7 @@ HGraph* RegisterAllocatorTest::BuildDiv(HInstruction** div) { DataType::Type::kInt32, first, second, 0); // don't care about dex_pc. block->AddInstruction(*div); - block->AddInstruction(new (GetAllocator()) HExit()); + MakeExit(block); graph->BuildDominatorTree(); return graph; @@ -788,23 +740,15 @@ TEST_F(RegisterAllocatorTest, SpillInactive) { HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(entry); graph->SetEntryBlock(entry); - HInstruction* one = new (GetAllocator()) HParameterValue( - graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kInt32); - HInstruction* two = new (GetAllocator()) HParameterValue( - graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kInt32); - HInstruction* three = new (GetAllocator()) HParameterValue( - graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kInt32); - HInstruction* four = new (GetAllocator()) HParameterValue( - graph->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kInt32); - entry->AddInstruction(one); - entry->AddInstruction(two); - entry->AddInstruction(three); - entry->AddInstruction(four); + HInstruction* one = MakeParam(DataType::Type::kInt32); + HInstruction* two = MakeParam(DataType::Type::kInt32); + HInstruction* three = MakeParam(DataType::Type::kInt32); + HInstruction* four = MakeParam(DataType::Type::kInt32); HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph); graph->AddBlock(block); entry->AddSuccessor(block); - block->AddInstruction(new (GetAllocator()) HExit()); + MakeExit(block); // We create a synthesized user requesting a register, to avoid just spilling the // intervals. diff --git a/compiler/optimizing/scheduler_test.cc b/compiler/optimizing/scheduler_test.cc index 0b020f1460..f613e0a9e2 100644 --- a/compiler/optimizing/scheduler_test.cc +++ b/compiler/optimizing/scheduler_test.cc @@ -93,43 +93,24 @@ class SchedulerTest : public CommonCompilerTest, public OptimizingUnitTestHelper // array_get2 ArrayGet [array, add1] // array_set2 ArraySet [array, add1, add2] - HInstruction* array = new (GetAllocator()) HParameterValue(graph_->GetDexFile(), - dex::TypeIndex(0), - 0, - DataType::Type::kReference); + HInstruction* array = MakeParam(DataType::Type::kReference); HInstruction* c1 = graph_->GetIntConstant(1); HInstruction* c2 = graph_->GetIntConstant(10); - HInstruction* add1 = new (GetAllocator()) HAdd(DataType::Type::kInt32, c1, c2); - HInstruction* add2 = new (GetAllocator()) HAdd(DataType::Type::kInt32, add1, c2); - HInstruction* mul = new (GetAllocator()) HMul(DataType::Type::kInt32, add1, add2); + + HInstruction* add1 = MakeBinOp<HAdd>(block1, DataType::Type::kInt32, c1, c2); + HInstruction* add2 = MakeBinOp<HAdd>(block1, DataType::Type::kInt32, add1, c2); + HInstruction* mul = MakeBinOp<HMul>(block1, DataType::Type::kInt32, add1, add2); HInstruction* div_check = new (GetAllocator()) HDivZeroCheck(add2, 0); + block1->AddInstruction(div_check); HInstruction* div = new (GetAllocator()) HDiv(DataType::Type::kInt32, add1, div_check, 0); - HInstruction* array_get1 = - new (GetAllocator()) HArrayGet(array, add1, DataType::Type::kInt32, 0); - HInstruction* array_set1 = - new (GetAllocator()) HArraySet(array, add1, add2, DataType::Type::kInt32, 0); - HInstruction* array_get2 = - new (GetAllocator()) HArrayGet(array, add1, DataType::Type::kInt32, 0); - HInstruction* array_set2 = - new (GetAllocator()) HArraySet(array, add1, add2, DataType::Type::kInt32, 0); + block1->AddInstruction(div); + HInstruction* array_get1 = MakeArrayGet(block1, array, add1, DataType::Type::kInt32); + HInstruction* array_set1 = MakeArraySet(block1, array, add1, add2, DataType::Type::kInt32); + HInstruction* array_get2 = MakeArrayGet(block1, array, add1, DataType::Type::kInt32); + HInstruction* array_set2 = MakeArraySet(block1, array, add1, add2, DataType::Type::kInt32); DCHECK(div_check->CanThrow()); - entry->AddInstruction(array); - - HInstruction* block_instructions[] = {add1, - add2, - mul, - div_check, - div, - array_get1, - array_set1, - array_get2, - array_set2}; - for (HInstruction* instr : block_instructions) { - block1->AddInstruction(instr); - } - HEnvironment* environment = new (GetAllocator()) HEnvironment(GetAllocator(), 2, graph_->GetArtMethod(), @@ -143,8 +124,8 @@ class SchedulerTest : public CommonCompilerTest, public OptimizingUnitTestHelper TestSchedulingGraph scheduling_graph(GetScopedAllocator()); // Instructions must be inserted in reverse order into the scheduling graph. - for (HInstruction* instr : ReverseRange(block_instructions)) { - scheduling_graph.AddNode(instr); + for (HBackwardInstructionIterator it(block1->GetInstructions()); !it.Done(); it.Advance()) { + scheduling_graph.AddNode(it.Current()); } // Should not have dependencies cross basic blocks. @@ -201,88 +182,41 @@ class SchedulerTest : public CommonCompilerTest, public OptimizingUnitTestHelper void TestDependencyGraphOnAliasingArrayAccesses(HScheduler* scheduler) { HBasicBlock* entry = new (GetAllocator()) HBasicBlock(graph_); + HBasicBlock* block1 = new (GetAllocator()) HBasicBlock(graph_); graph_->AddBlock(entry); + graph_->AddBlock(block1); graph_->SetEntryBlock(entry); - graph_->BuildDominatorTree(); - - HInstruction* arr = new (GetAllocator()) HParameterValue(graph_->GetDexFile(), - dex::TypeIndex(0), - 0, - DataType::Type::kReference); - HInstruction* i = new (GetAllocator()) HParameterValue(graph_->GetDexFile(), - dex::TypeIndex(1), - 1, - DataType::Type::kInt32); - HInstruction* j = new (GetAllocator()) HParameterValue(graph_->GetDexFile(), - dex::TypeIndex(1), - 1, - DataType::Type::kInt32); - HInstruction* object = new (GetAllocator()) HParameterValue(graph_->GetDexFile(), - dex::TypeIndex(0), - 0, - DataType::Type::kReference); + + HInstruction* arr = MakeParam(DataType::Type::kReference); + HInstruction* i = MakeParam(DataType::Type::kInt32); + HInstruction* j = MakeParam(DataType::Type::kInt32); + HInstruction* object = MakeParam(DataType::Type::kReference); HInstruction* c0 = graph_->GetIntConstant(0); HInstruction* c1 = graph_->GetIntConstant(1); - HInstruction* add0 = new (GetAllocator()) HAdd(DataType::Type::kInt32, i, c0); - HInstruction* add1 = new (GetAllocator()) HAdd(DataType::Type::kInt32, i, c1); - HInstruction* sub0 = new (GetAllocator()) HSub(DataType::Type::kInt32, i, c0); - HInstruction* sub1 = new (GetAllocator()) HSub(DataType::Type::kInt32, i, c1); - HInstruction* arr_set_0 = - new (GetAllocator()) HArraySet(arr, c0, c0, DataType::Type::kInt32, 0); - HInstruction* arr_set_1 = - new (GetAllocator()) HArraySet(arr, c1, c0, DataType::Type::kInt32, 0); - HInstruction* arr_set_i = new (GetAllocator()) HArraySet(arr, i, c0, DataType::Type::kInt32, 0); - HInstruction* arr_set_add0 = - new (GetAllocator()) HArraySet(arr, add0, c0, DataType::Type::kInt32, 0); - HInstruction* arr_set_add1 = - new (GetAllocator()) HArraySet(arr, add1, c0, DataType::Type::kInt32, 0); - HInstruction* arr_set_sub0 = - new (GetAllocator()) HArraySet(arr, sub0, c0, DataType::Type::kInt32, 0); - HInstruction* arr_set_sub1 = - new (GetAllocator()) HArraySet(arr, sub1, c0, DataType::Type::kInt32, 0); - HInstruction* arr_set_j = new (GetAllocator()) HArraySet(arr, j, c0, DataType::Type::kInt32, 0); - HInstanceFieldSet* set_field10 = new (GetAllocator()) HInstanceFieldSet(object, - c1, - nullptr, - DataType::Type::kInt32, - MemberOffset(10), - false, - kUnknownFieldIndex, - kUnknownClassDefIndex, - graph_->GetDexFile(), - 0); - - HInstruction* block_instructions[] = {arr, - i, - j, - object, - add0, - add1, - sub0, - sub1, - arr_set_0, - arr_set_1, - arr_set_i, - arr_set_add0, - arr_set_add1, - arr_set_sub0, - arr_set_sub1, - arr_set_j, - set_field10}; - - for (HInstruction* instr : block_instructions) { - entry->AddInstruction(instr); - } + + HInstruction* add0 = MakeBinOp<HAdd>(block1, DataType::Type::kInt32, i, c0); + HInstruction* add1 = MakeBinOp<HAdd>(block1, DataType::Type::kInt32, i, c1); + HInstruction* sub0 = MakeBinOp<HSub>(block1, DataType::Type::kInt32, i, c0); + HInstruction* sub1 = MakeBinOp<HSub>(block1, DataType::Type::kInt32, i, c1); + HInstruction* arr_set_0 = MakeArraySet(block1, arr, c0, c0, DataType::Type::kInt32); + HInstruction* arr_set_1 = MakeArraySet(block1, arr, c1, c0, DataType::Type::kInt32); + HInstruction* arr_set_i = MakeArraySet(block1, arr, i, c0, DataType::Type::kInt32); + HInstruction* arr_set_add0 = MakeArraySet(block1, arr, add0, c0, DataType::Type::kInt32); + HInstruction* arr_set_add1 = MakeArraySet(block1, arr, add1, c0, DataType::Type::kInt32); + HInstruction* arr_set_sub0 = MakeArraySet(block1, arr, sub0, c0, DataType::Type::kInt32); + HInstruction* arr_set_sub1 = MakeArraySet(block1, arr, sub1, c0, DataType::Type::kInt32); + HInstruction* arr_set_j = MakeArraySet(block1, arr, j, c0, DataType::Type::kInt32); + HInstanceFieldSet* set_field10 = MakeIFieldSet(block1, object, c1, MemberOffset(10)); HeapLocationCollector heap_location_collector(graph_, GetScopedAllocator()); - heap_location_collector.VisitBasicBlock(entry); + heap_location_collector.VisitBasicBlock(block1); heap_location_collector.BuildAliasingMatrix(); TestSchedulingGraph scheduling_graph(GetScopedAllocator(), &heap_location_collector); - for (HInstruction* instr : ReverseRange(block_instructions)) { + for (HBackwardInstructionIterator it(block1->GetInstructions()); !it.Done(); it.Advance()) { // Build scheduling graph with memory access aliasing information // from LSA/heap_location_collector. - scheduling_graph.AddNode(instr); + scheduling_graph.AddNode(it.Current()); } // LSA/HeapLocationCollector should see those ArraySet instructions. diff --git a/compiler/optimizing/select_generator_test.cc b/compiler/optimizing/select_generator_test.cc index fc9e150d92..501bebb9dd 100644 --- a/compiler/optimizing/select_generator_test.cc +++ b/compiler/optimizing/select_generator_test.cc @@ -27,14 +27,6 @@ namespace art HIDDEN { class SelectGeneratorTest : public OptimizingUnitTest { protected: - void InitGraphAndParameters() { - InitGraph(); - AddParameter(new (GetAllocator()) HParameterValue(graph_->GetDexFile(), - dex::TypeIndex(0), - 0, - DataType::Type::kInt32)); - } - void ConstructBasicGraphForSelect(HInstruction* instr) { HBasicBlock* if_block = AddNewBlock(); HBasicBlock* then_block = AddNewBlock(); @@ -47,24 +39,17 @@ class SelectGeneratorTest : public OptimizingUnitTest { then_block->AddSuccessor(return_block_); else_block->AddSuccessor(return_block_); - HParameterValue* bool_param = new (GetAllocator()) HParameterValue(graph_->GetDexFile(), - dex::TypeIndex(0), - 1, - DataType::Type::kBool); - entry_block_->AddInstruction(bool_param); + HParameterValue* bool_param = MakeParam(DataType::Type::kBool); HIntConstant* const1 = graph_->GetIntConstant(1); - if_block->AddInstruction(new (GetAllocator()) HIf(bool_param)); + MakeIf(if_block, bool_param); then_block->AddInstruction(instr); - then_block->AddInstruction(new (GetAllocator()) HGoto()); + MakeGoto(then_block); - else_block->AddInstruction(new (GetAllocator()) HGoto()); + MakeGoto(else_block); - HPhi* phi = new (GetAllocator()) HPhi(GetAllocator(), 0, 0, DataType::Type::kInt32); - return_block_->AddPhi(phi); - phi->AddInput(instr); - phi->AddInput(const1); + HPhi* phi = MakePhi(return_block_, {instr, const1}); } bool CheckGraphAndTrySelectGenerator() { @@ -79,11 +64,12 @@ class SelectGeneratorTest : public OptimizingUnitTest { // HDivZeroCheck might throw and should not be hoisted from the conditional to an unconditional. TEST_F(SelectGeneratorTest, testZeroCheck) { - InitGraphAndParameters(); - HDivZeroCheck* instr = new (GetAllocator()) HDivZeroCheck(parameters_[0], 0); + InitGraph(); + HParameterValue* param = MakeParam(DataType::Type::kInt32); + HDivZeroCheck* instr = new (GetAllocator()) HDivZeroCheck(param, 0); ConstructBasicGraphForSelect(instr); - ArenaVector<HInstruction*> current_locals({parameters_[0], graph_->GetIntConstant(1)}, + ArenaVector<HInstruction*> current_locals({param, graph_->GetIntConstant(1)}, GetAllocator()->Adapter(kArenaAllocInstruction)); ManuallyBuildEnvFor(instr, ¤t_locals); @@ -92,10 +78,9 @@ TEST_F(SelectGeneratorTest, testZeroCheck) { // Test that SelectGenerator succeeds with HAdd. TEST_F(SelectGeneratorTest, testAdd) { - InitGraphAndParameters(); - HAdd* instr = new (GetAllocator()) HAdd(DataType::Type::kInt32, - parameters_[0], - parameters_[0], 0); + InitGraph(); + HParameterValue* param = MakeParam(DataType::Type::kInt32); + HAdd* instr = new (GetAllocator()) HAdd(DataType::Type::kInt32, param, param, /*dex_pc=*/ 0); ConstructBasicGraphForSelect(instr); EXPECT_TRUE(CheckGraphAndTrySelectGenerator()); } diff --git a/compiler/optimizing/ssa_liveness_analysis_test.cc b/compiler/optimizing/ssa_liveness_analysis_test.cc index 2df0f34c7d..a951796526 100644 --- a/compiler/optimizing/ssa_liveness_analysis_test.cc +++ b/compiler/optimizing/ssa_liveness_analysis_test.cc @@ -58,14 +58,11 @@ class SsaLivenessAnalysisTest : public OptimizingUnitTest { }; TEST_F(SsaLivenessAnalysisTest, TestReturnArg) { - HInstruction* arg = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kInt32); - entry_->AddInstruction(arg); + HInstruction* arg = MakeParam(DataType::Type::kInt32); HBasicBlock* block = CreateSuccessor(entry_); - HInstruction* ret = new (GetAllocator()) HReturn(arg); - block->AddInstruction(ret); - block->AddInstruction(new (GetAllocator()) HExit()); + MakeReturn(block, arg); + MakeExit(block); graph_->BuildDominatorTree(); SsaLivenessAnalysis ssa_analysis(graph_, codegen_.get(), GetScopedAllocator()); @@ -78,24 +75,15 @@ TEST_F(SsaLivenessAnalysisTest, TestReturnArg) { } TEST_F(SsaLivenessAnalysisTest, TestAput) { - HInstruction* array = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); - HInstruction* index = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(1), 1, DataType::Type::kInt32); - HInstruction* value = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(2), 2, DataType::Type::kInt32); - HInstruction* extra_arg1 = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(3), 3, DataType::Type::kInt32); - HInstruction* extra_arg2 = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(4), 4, DataType::Type::kReference); + HInstruction* array = MakeParam(DataType::Type::kReference); + HInstruction* index = MakeParam(DataType::Type::kInt32); + HInstruction* value = MakeParam(DataType::Type::kInt32); + HInstruction* extra_arg1 = MakeParam(DataType::Type::kInt32); + HInstruction* extra_arg2 = MakeParam(DataType::Type::kReference); HInstruction* const args[] = { array, index, value, extra_arg1, extra_arg2 }; - for (HInstruction* insn : args) { - entry_->AddInstruction(insn); - } HBasicBlock* block = CreateSuccessor(entry_); - HInstruction* null_check = new (GetAllocator()) HNullCheck(array, 0); - block->AddInstruction(null_check); + HInstruction* null_check = MakeNullCheck(block, array); HEnvironment* null_check_env = new (GetAllocator()) HEnvironment(GetAllocator(), /* number_of_vregs= */ 5, /* method= */ nullptr, @@ -103,10 +91,8 @@ TEST_F(SsaLivenessAnalysisTest, TestAput) { null_check); null_check_env->CopyFrom(ArrayRef<HInstruction* const>(args)); null_check->SetRawEnvironment(null_check_env); - HInstruction* length = new (GetAllocator()) HArrayLength(array, 0); - block->AddInstruction(length); - HInstruction* bounds_check = new (GetAllocator()) HBoundsCheck(index, length, /* dex_pc= */ 0u); - block->AddInstruction(bounds_check); + HInstruction* length = MakeArrayLength(block, array); + HInstruction* bounds_check = MakeBoundsCheck(block, index, length); HEnvironment* bounds_check_env = new (GetAllocator()) HEnvironment(GetAllocator(), /* number_of_vregs= */ 5, /* method= */ nullptr, @@ -114,9 +100,7 @@ TEST_F(SsaLivenessAnalysisTest, TestAput) { bounds_check); bounds_check_env->CopyFrom(ArrayRef<HInstruction* const>(args)); bounds_check->SetRawEnvironment(bounds_check_env); - HInstruction* array_set = - new (GetAllocator()) HArraySet(array, index, value, DataType::Type::kInt32, /* dex_pc= */ 0); - block->AddInstruction(array_set); + MakeArraySet(block, array, index, value, DataType::Type::kInt32); graph_->BuildDominatorTree(); SsaLivenessAnalysis ssa_analysis(graph_, codegen_.get(), GetScopedAllocator()); @@ -147,24 +131,15 @@ TEST_F(SsaLivenessAnalysisTest, TestAput) { } TEST_F(SsaLivenessAnalysisTest, TestDeoptimize) { - HInstruction* array = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(0), 0, DataType::Type::kReference); - HInstruction* index = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(1), 1, DataType::Type::kInt32); - HInstruction* value = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(2), 2, DataType::Type::kInt32); - HInstruction* extra_arg1 = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(3), 3, DataType::Type::kInt32); - HInstruction* extra_arg2 = new (GetAllocator()) HParameterValue( - graph_->GetDexFile(), dex::TypeIndex(4), 4, DataType::Type::kReference); + HInstruction* array = MakeParam(DataType::Type::kReference); + HInstruction* index = MakeParam(DataType::Type::kInt32); + HInstruction* value = MakeParam(DataType::Type::kInt32); + HInstruction* extra_arg1 = MakeParam(DataType::Type::kInt32); + HInstruction* extra_arg2 = MakeParam(DataType::Type::kReference); HInstruction* const args[] = { array, index, value, extra_arg1, extra_arg2 }; - for (HInstruction* insn : args) { - entry_->AddInstruction(insn); - } HBasicBlock* block = CreateSuccessor(entry_); - HInstruction* null_check = new (GetAllocator()) HNullCheck(array, 0); - block->AddInstruction(null_check); + HInstruction* null_check = MakeNullCheck(block, array); HEnvironment* null_check_env = new (GetAllocator()) HEnvironment(GetAllocator(), /* number_of_vregs= */ 5, /* method= */ nullptr, @@ -172,11 +147,9 @@ TEST_F(SsaLivenessAnalysisTest, TestDeoptimize) { null_check); null_check_env->CopyFrom(ArrayRef<HInstruction* const>(args)); null_check->SetRawEnvironment(null_check_env); - HInstruction* length = new (GetAllocator()) HArrayLength(array, 0); - block->AddInstruction(length); + HInstruction* length = MakeArrayLength(block, array); // Use HAboveOrEqual+HDeoptimize as the bounds check. - HInstruction* ae = new (GetAllocator()) HAboveOrEqual(index, length); - block->AddInstruction(ae); + HInstruction* ae = MakeCondition<HAboveOrEqual>(block, index, length); HInstruction* deoptimize = new(GetAllocator()) HDeoptimize( GetAllocator(), ae, DeoptimizationKind::kBlockBCE, /* dex_pc= */ 0u); block->AddInstruction(deoptimize); @@ -187,9 +160,7 @@ TEST_F(SsaLivenessAnalysisTest, TestDeoptimize) { deoptimize); deoptimize_env->CopyFrom(ArrayRef<HInstruction* const>(args)); deoptimize->SetRawEnvironment(deoptimize_env); - HInstruction* array_set = - new (GetAllocator()) HArraySet(array, index, value, DataType::Type::kInt32, /* dex_pc= */ 0); - block->AddInstruction(array_set); + MakeArraySet(block, array, index, value, DataType::Type::kInt32); graph_->BuildDominatorTree(); SsaLivenessAnalysis ssa_analysis(graph_, codegen_.get(), GetScopedAllocator()); diff --git a/compiler/optimizing/superblock_cloner_test.cc b/compiler/optimizing/superblock_cloner_test.cc index ea2563ea7d..9345fd175f 100644 --- a/compiler/optimizing/superblock_cloner_test.cc +++ b/compiler/optimizing/superblock_cloner_test.cc @@ -35,10 +35,7 @@ class SuperblockClonerTest : public OptimizingUnitTest { protected: void InitGraphAndParameters() { InitGraph(); - AddParameter(new (GetAllocator()) HParameterValue(graph_->GetDexFile(), - dex::TypeIndex(0), - 0, - DataType::Type::kInt32)); + param_ = MakeParam(DataType::Type::kInt32); } void CreateBasicLoopControlFlow(HBasicBlock* position, @@ -70,48 +67,37 @@ class SuperblockClonerTest : public OptimizingUnitTest { HIntConstant* const_128 = graph_->GetIntConstant(128); // Header block. - HPhi* phi = new (GetAllocator()) HPhi(GetAllocator(), 0, 0, DataType::Type::kInt32); - HInstruction* suspend_check = new (GetAllocator()) HSuspendCheck(); - HInstruction* loop_check = new (GetAllocator()) HGreaterThanOrEqual(phi, const_128); - - loop_header->AddPhi(phi); - loop_header->AddInstruction(suspend_check); - loop_header->AddInstruction(loop_check); - loop_header->AddInstruction(new (GetAllocator()) HIf(loop_check)); + HPhi* phi = MakePhi(loop_header, {const_0, /* placeholder */ const_0}); + HInstruction* suspend_check = MakeSuspendCheck(loop_header); + HInstruction* loop_check = MakeCondition<HGreaterThanOrEqual>(loop_header, phi, const_128); + MakeIf(loop_header, loop_check); // Loop body block. - HInstruction* null_check = new (GetAllocator()) HNullCheck(parameters_[0], dex_pc); - HInstruction* array_length = new (GetAllocator()) HArrayLength(null_check, dex_pc); - HInstruction* bounds_check = new (GetAllocator()) HBoundsCheck(phi, array_length, dex_pc); + HInstruction* null_check = MakeNullCheck(loop_body, param_, dex_pc); + HInstruction* array_length = MakeArrayLength(loop_body, null_check, dex_pc); + HInstruction* bounds_check = MakeBoundsCheck(loop_body, phi, array_length, dex_pc); HInstruction* array_get = - new (GetAllocator()) HArrayGet(null_check, bounds_check, DataType::Type::kInt32, dex_pc); - HInstruction* add = new (GetAllocator()) HAdd(DataType::Type::kInt32, array_get, const_1); - HInstruction* array_set = new (GetAllocator()) HArraySet( - null_check, bounds_check, add, DataType::Type::kInt32, dex_pc); - HInstruction* induction_inc = new (GetAllocator()) HAdd(DataType::Type::kInt32, phi, const_1); - - loop_body->AddInstruction(null_check); - loop_body->AddInstruction(array_length); - loop_body->AddInstruction(bounds_check); - loop_body->AddInstruction(array_get); - loop_body->AddInstruction(add); - loop_body->AddInstruction(array_set); - loop_body->AddInstruction(induction_inc); - loop_body->AddInstruction(new (GetAllocator()) HGoto()); - - phi->AddInput(const_0); - phi->AddInput(induction_inc); + MakeArrayGet(loop_body, null_check, bounds_check, DataType::Type::kInt32, dex_pc); + HInstruction* add = MakeBinOp<HAdd>(loop_body, DataType::Type::kInt32, array_get, const_1); + HInstruction* array_set = + MakeArraySet(loop_body, null_check, bounds_check, add, DataType::Type::kInt32, dex_pc); + HInstruction* induction_inc = MakeBinOp<HAdd>(loop_body, DataType::Type::kInt32, phi, const_1); + MakeGoto(loop_body); + + phi->ReplaceInput(induction_inc, 1u); // Update back-edge input. graph_->SetHasBoundsChecks(true); // Adjust HEnvironment for each instruction which require that. - ArenaVector<HInstruction*> current_locals({phi, const_128, parameters_[0]}, + ArenaVector<HInstruction*> current_locals({phi, const_128, param_}, GetAllocator()->Adapter(kArenaAllocInstruction)); HEnvironment* env = ManuallyBuildEnvFor(suspend_check, ¤t_locals); null_check->CopyEnvironmentFrom(env); bounds_check->CopyEnvironmentFrom(env); } + + HParameterValue* param_ = nullptr; }; TEST_F(SuperblockClonerTest, IndividualInstrCloner) { @@ -428,16 +414,14 @@ TEST_F(SuperblockClonerTest, LoopPeelingMultipleBackEdges) { if_block->AddSuccessor(temp1); temp1->AddSuccessor(header); - if_block->AddInstruction(new (GetAllocator()) HIf(parameters_[0])); + MakeIf(if_block, param_); HInstructionIterator it(header->GetPhis()); DCHECK(!it.Done()); HPhi* loop_phi = it.Current()->AsPhi(); - HInstruction* temp_add = new (GetAllocator()) HAdd(DataType::Type::kInt32, - loop_phi, - graph_->GetIntConstant(2)); - temp1->AddInstruction(temp_add); - temp1->AddInstruction(new (GetAllocator()) HGoto()); + HInstruction* temp_add = + MakeBinOp<HAdd>(temp1, DataType::Type::kInt32, loop_phi, graph_->GetIntConstant(2)); + MakeGoto(temp1); loop_phi->AddInput(temp_add); graph_->BuildDominatorTree(); @@ -592,7 +576,7 @@ TEST_F(SuperblockClonerTest, NestedCaseExitToOutermost) { // Change the loop3 - insert an exit which leads to loop1. HBasicBlock* loop3_extra_if_block = AddNewBlock(); - loop3_extra_if_block->AddInstruction(new (GetAllocator()) HIf(parameters_[0])); + MakeIf(loop3_extra_if_block, param_); loop3_header->ReplaceSuccessor(loop_body3, loop3_extra_if_block); loop3_extra_if_block->AddSuccessor(loop_body1); // Long exit. |