summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/optimizing/bounds_check_elimination_test.cc932
-rw-r--r--compiler/optimizing/codegen_test.cc71
-rw-r--r--compiler/optimizing/constant_folding_test.cc10
-rw-r--r--compiler/optimizing/graph_checker_test.cc4
-rw-r--r--compiler/optimizing/graph_test.cc12
-rw-r--r--compiler/optimizing/gvn_test.cc263
-rw-r--r--compiler/optimizing/induction_var_analysis_test.cc44
-rw-r--r--compiler/optimizing/induction_var_range_test.cc67
-rw-r--r--compiler/optimizing/instruction_simplifier_test.cc55
-rw-r--r--compiler/optimizing/licm_test.cc68
-rw-r--r--compiler/optimizing/load_store_analysis_test.cc756
-rw-r--r--compiler/optimizing/load_store_elimination_test.cc769
-rw-r--r--compiler/optimizing/loop_optimization_test.cc36
-rw-r--r--compiler/optimizing/nodes_test.cc39
-rw-r--r--compiler/optimizing/nodes_vector_test.cc18
-rw-r--r--compiler/optimizing/optimizing_unit_test.h282
-rw-r--r--compiler/optimizing/register_allocator_test.cc108
-rw-r--r--compiler/optimizing/scheduler_test.cc140
-rw-r--r--compiler/optimizing/select_generator_test.cc39
-rw-r--r--compiler/optimizing/ssa_liveness_analysis_test.cc71
-rw-r--r--compiler/optimizing/superblock_cloner_test.cc64
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, &current_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, &current_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, &current_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, &current_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.