Fix and improve static evaluation of constant expressions.
- Fix the definition of art::HSub::Evaluate.
- Qualify Evaluate methods as OVERRIDE.
- Evaluate comparisons in a deterministic way: if a
comparison is true, always return 1 (instead of letting
the compiler return any non-null value).
- Better exercise static evaluation of constant expressions
in compiler/optimizing/constant_propagation_test.cc.
Change-Id: I13d0862e5f4eba1275016fb8c3c17e9aff54408b
diff --git a/compiler/optimizing/constant_propagation_test.cc b/compiler/optimizing/constant_propagation_test.cc
index d08d14d..342777a 100644
--- a/compiler/optimizing/constant_propagation_test.cc
+++ b/compiler/optimizing/constant_propagation_test.cc
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <functional>
+
#include "constant_propagation.h"
#include "dead_code_elimination.h"
#include "pretty_printer.h"
@@ -28,6 +30,7 @@
const std::string& expected_before,
const std::string& expected_after_cp,
const std::string& expected_after_dce,
+ std::function<void(HGraph*)> check_after_cp,
Primitive::Type return_type = Primitive::kPrimInt) {
ArenaPool pool;
ArenaAllocator allocator(&pool);
@@ -49,6 +52,8 @@
std::string actual_after_cp = printer_after_cp.str();
ASSERT_EQ(expected_after_cp, actual_after_cp);
+ check_after_cp(graph);
+
DeadCodeElimination(graph).Run();
StringPrettyPrinter printer_after_dce(graph);
@@ -101,6 +106,13 @@
};
std::string expected_after_cp = Patch(expected_before, expected_cp_diff);
+ // Check the value of the computed constant.
+ auto check_after_cp = [](HGraph* graph) {
+ HInstruction* inst = graph->GetBlock(1)->GetFirstInstruction();
+ ASSERT_TRUE(inst->IsIntConstant());
+ ASSERT_EQ(inst->AsIntConstant()->GetValue(), 3);
+ };
+
// Expected difference after dead code elimination.
diff_t expected_dce_diff = {
{ " 3: IntConstant\n", removed },
@@ -108,7 +120,11 @@
};
std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff);
- TestCode(data, expected_before, expected_after_cp, expected_after_dce);
+ TestCode(data,
+ expected_before,
+ expected_after_cp,
+ expected_after_dce,
+ check_after_cp);
}
/**
@@ -166,6 +182,19 @@
};
std::string expected_after_cp = Patch(expected_before, expected_cp_diff);
+ // Check the values of the computed constants.
+ auto check_after_cp = [](HGraph* graph) {
+ HInstruction* inst1 = graph->GetBlock(1)->GetFirstInstruction();
+ ASSERT_TRUE(inst1->IsIntConstant());
+ ASSERT_EQ(inst1->AsIntConstant()->GetValue(), 3);
+ HInstruction* inst2 = inst1->GetNext();
+ ASSERT_TRUE(inst2->IsIntConstant());
+ ASSERT_EQ(inst2->AsIntConstant()->GetValue(), 7);
+ HInstruction* inst3 = inst2->GetNext();
+ ASSERT_TRUE(inst3->IsIntConstant());
+ ASSERT_EQ(inst3->AsIntConstant()->GetValue(), 10);
+ };
+
// Expected difference after dead code elimination.
diff_t expected_dce_diff = {
{ " 3: IntConstant\n", removed },
@@ -177,7 +206,11 @@
};
std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff);
- TestCode(data, expected_before, expected_after_cp, expected_after_dce);
+ TestCode(data,
+ expected_before,
+ expected_after_cp,
+ expected_after_dce,
+ check_after_cp);
}
/**
@@ -219,6 +252,13 @@
};
std::string expected_after_cp = Patch(expected_before, expected_cp_diff);
+ // Check the value of the computed constant.
+ auto check_after_cp = [](HGraph* graph) {
+ HInstruction* inst = graph->GetBlock(1)->GetFirstInstruction();
+ ASSERT_TRUE(inst->IsIntConstant());
+ ASSERT_EQ(inst->AsIntConstant()->GetValue(), 1);
+ };
+
// Expected difference after dead code elimination.
diff_t expected_dce_diff = {
{ " 3: IntConstant\n", removed },
@@ -226,7 +266,11 @@
};
std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff);
- TestCode(data, expected_before, expected_after_cp, expected_after_dce);
+ TestCode(data,
+ expected_before,
+ expected_after_cp,
+ expected_after_dce,
+ check_after_cp);
}
#define SIX_REGISTERS_CODE_ITEM(...) \
@@ -273,6 +317,13 @@
};
std::string expected_after_cp = Patch(expected_before, expected_cp_diff);
+ // Check the value of the computed constant.
+ auto check_after_cp = [](HGraph* graph) {
+ HInstruction* inst = graph->GetBlock(1)->GetFirstInstruction();
+ ASSERT_TRUE(inst->IsLongConstant());
+ ASSERT_EQ(inst->AsLongConstant()->GetValue(), 3);
+ };
+
// Expected difference after dead code elimination.
diff_t expected_dce_diff = {
{ " 6: LongConstant\n", removed },
@@ -280,7 +331,12 @@
};
std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff);
- TestCode(data, expected_before, expected_after_cp, expected_after_dce, Primitive::kPrimLong);
+ TestCode(data,
+ expected_before,
+ expected_after_cp,
+ expected_after_dce,
+ check_after_cp,
+ Primitive::kPrimLong);
}
/**
@@ -324,6 +380,13 @@
};
std::string expected_after_cp = Patch(expected_before, expected_cp_diff);
+ // Check the value of the computed constant.
+ auto check_after_cp = [](HGraph* graph) {
+ HInstruction* inst = graph->GetBlock(1)->GetFirstInstruction();
+ ASSERT_TRUE(inst->IsLongConstant());
+ ASSERT_EQ(inst->AsLongConstant()->GetValue(), 1);
+ };
+
// Expected difference after dead code elimination.
diff_t expected_dce_diff = {
{ " 6: LongConstant\n", removed },
@@ -331,7 +394,12 @@
};
std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff);
- TestCode(data, expected_before, expected_after_cp, expected_after_dce, Primitive::kPrimLong);
+ TestCode(data,
+ expected_before,
+ expected_after_cp,
+ expected_after_dce,
+ check_after_cp,
+ Primitive::kPrimLong);
}
/**
@@ -371,26 +439,26 @@
std::string expected_before =
"BasicBlock 0, succ: 1\n"
- " 3: IntConstant [9]\n"
- " 5: IntConstant [9]\n"
- " 13: IntConstant [14]\n"
- " 18: IntConstant [19]\n"
- " 24: IntConstant [25]\n"
+ " 3: IntConstant [9]\n" // v0 <- 0
+ " 5: IntConstant [9]\n" // v1 <- 1
+ " 13: IntConstant [14]\n" // const 3
+ " 18: IntConstant [19]\n" // const 2
+ " 24: IntConstant [25]\n" // const 4
" 30: SuspendCheck\n"
" 31: Goto 1\n"
"BasicBlock 1, pred: 0, succ: 3\n"
- " 9: Add(3, 5) [19]\n"
- " 11: Goto 3\n"
- "BasicBlock 2, pred: 3, succ: 4\n"
- " 14: Add(19, 13) [25]\n"
- " 16: Goto 4\n"
- "BasicBlock 3, pred: 1, succ: 2\n"
- " 19: Add(9, 18) [14]\n"
+ " 9: Add(3, 5) [19]\n" // v2 <- v0 + v1 = 0 + 1 = 1
+ " 11: Goto 3\n" // goto L2
+ "BasicBlock 2, pred: 3, succ: 4\n" // L1:
+ " 14: Add(19, 13) [25]\n" // v1 <- v0 + 3 = 3 + 3 = 6
+ " 16: Goto 4\n" // goto L3
+ "BasicBlock 3, pred: 1, succ: 2\n" // L2:
+ " 19: Add(9, 18) [14]\n" // v0 <- v2 + 2 = 1 + 2 = 3
" 21: SuspendCheck\n"
- " 22: Goto 2\n"
- "BasicBlock 4, pred: 2, succ: 5\n"
- " 25: Add(14, 24) [28]\n"
- " 28: Return(25)\n"
+ " 22: Goto 2\n" // goto L1
+ "BasicBlock 4, pred: 2, succ: 5\n" // L3:
+ " 25: Add(14, 24) [28]\n" // v2 <- v1 + 4 = 6 + 4 = 10
+ " 28: Return(25)\n" // return v2
"BasicBlock 5, pred: 4\n"
" 29: Exit\n";
@@ -409,6 +477,22 @@
};
std::string expected_after_cp = Patch(expected_before, expected_cp_diff);
+ // Check the values of the computed constants.
+ auto check_after_cp = [](HGraph* graph) {
+ HInstruction* inst1 = graph->GetBlock(1)->GetFirstInstruction();
+ ASSERT_TRUE(inst1->IsIntConstant());
+ ASSERT_EQ(inst1->AsIntConstant()->GetValue(), 1);
+ HInstruction* inst2 = graph->GetBlock(2)->GetFirstInstruction();
+ ASSERT_TRUE(inst2->IsIntConstant());
+ ASSERT_EQ(inst2->AsIntConstant()->GetValue(), 6);
+ HInstruction* inst3 = graph->GetBlock(3)->GetFirstInstruction();
+ ASSERT_TRUE(inst3->IsIntConstant());
+ ASSERT_EQ(inst3->AsIntConstant()->GetValue(), 3);
+ HInstruction* inst4 = graph->GetBlock(4)->GetFirstInstruction();
+ ASSERT_TRUE(inst4->IsIntConstant());
+ ASSERT_EQ(inst4->AsIntConstant()->GetValue(), 10);
+ };
+
// Expected difference after dead code elimination.
diff_t expected_dce_diff = {
{ " 3: IntConstant\n", removed },
@@ -419,7 +503,11 @@
};
std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff);
- TestCode(data, expected_before, expected_after_cp, expected_after_dce);
+ TestCode(data,
+ expected_before,
+ expected_after_cp,
+ expected_after_dce,
+ check_after_cp);
}
@@ -474,6 +562,13 @@
};
std::string expected_after_cp = Patch(expected_before, expected_cp_diff);
+ // Check the values of the computed constants.
+ auto check_after_cp = [](HGraph* graph) {
+ HInstruction* inst = graph->GetBlock(1)->GetFirstInstruction();
+ ASSERT_TRUE(inst->IsIntConstant());
+ ASSERT_EQ(inst->AsIntConstant()->GetValue(), 1);
+ };
+
// Expected difference after dead code elimination.
diff_t expected_dce_diff = {
{ " 3: IntConstant [15, 22]\n", " 3: IntConstant [22]\n" },
@@ -482,7 +577,11 @@
};
std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff);
- TestCode(data, expected_before, expected_after_cp, expected_after_dce);
+ TestCode(data,
+ expected_before,
+ expected_after_cp,
+ expected_after_dce,
+ check_after_cp);
}
} // namespace art