summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
author Roland Levillain <rpl@google.com> 2014-12-11 12:14:33 +0000
committer Roland Levillain <rpl@google.com> 2015-08-05 11:01:40 +0100
commitc90bc7c07f9bd24b5424cfb1e3f064fbae5334d6 (patch)
treea462fa0cc21489d4250febb6d098aacc7a265279 /compiler/optimizing
parentc2abe2fe9036b57c581e3003d0b820d1c54dbd30 (diff)
Add constant folding for long unary operations in opt. compiler.
Add tests to exercise the constant folding of these instructions. Also, prevent Java methods from run-tests exercising the code generation of these instruction from being inlined, so that they continue to check the generated code (and not the code produced by the constant folding pass). Change-Id: I28efca7cdb5142ac2b6d158ba296fb9136d62481
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/constant_folding_test.cc65
-rw-r--r--compiler/optimizing/nodes.cc8
2 files changed, 66 insertions, 7 deletions
diff --git a/compiler/optimizing/constant_folding_test.cc b/compiler/optimizing/constant_folding_test.cc
index 11f6362294..10e4bc98a6 100644
--- a/compiler/optimizing/constant_folding_test.cc
+++ b/compiler/optimizing/constant_folding_test.cc
@@ -81,7 +81,7 @@ static void TestCode(const uint16_t* data,
* offset
* ------
* v0 <- 1 0. const/4 v0, #+1
- * v1 <- -v0 1. neg-int v0, v1
+ * v1 <- -v0 1. neg-int v1, v0
* return v1 2. return v1
*/
TEST(ConstantFolding, IntConstantFoldingNegation) {
@@ -132,6 +132,69 @@ TEST(ConstantFolding, IntConstantFoldingNegation) {
}
/**
+ * Tiny three-register program exercising long constant folding on negation.
+ *
+ * 16-bit
+ * offset
+ * ------
+ * (v0, v1) <- 4294967296 0. const-wide v0 #+4294967296
+ * (v2, v3) <- -(v0, v1) 1. neg-long v2, v0
+ * return (v2, v3) 2. return-wide v2
+ */
+TEST(ConstantFolding, LongConstantFoldingNegation) {
+ const int64_t input = INT64_C(4294967296); // 2^32
+ const uint16_t word0 = Low16Bits(Low32Bits(input)); // LSW.
+ const uint16_t word1 = High16Bits(Low32Bits(input));
+ const uint16_t word2 = Low16Bits(High32Bits(input));
+ const uint16_t word3 = High16Bits(High32Bits(input)); // MSW.
+ const uint16_t data[] = FOUR_REGISTERS_CODE_ITEM(
+ Instruction::CONST_WIDE | 0 << 8, word0, word1, word2, word3,
+ Instruction::NEG_LONG | 2 << 8 | 0 << 12,
+ Instruction::RETURN_WIDE | 2 << 8);
+
+ std::string expected_before =
+ "BasicBlock 0, succ: 1\n"
+ " 4: LongConstant [7]\n"
+ " 12: SuspendCheck\n"
+ " 13: Goto 1\n"
+ "BasicBlock 1, pred: 0, succ: 2\n"
+ " 7: Neg(4) [10]\n"
+ " 10: Return(7)\n"
+ "BasicBlock 2, pred: 1\n"
+ " 11: Exit\n";
+
+ // Expected difference after constant folding.
+ diff_t expected_cf_diff = {
+ { " 4: LongConstant [7]\n", " 4: LongConstant\n" },
+ { " 12: SuspendCheck\n", " 12: SuspendCheck\n"
+ " 14: LongConstant [10]\n" },
+ { " 7: Neg(4) [10]\n", removed },
+ { " 10: Return(7)\n", " 10: Return(14)\n" }
+ };
+ std::string expected_after_cf = Patch(expected_before, expected_cf_diff);
+
+ // Check the value of the computed constant.
+ auto check_after_cf = [](HGraph* graph) {
+ HInstruction* inst = graph->GetBlock(1)->GetFirstInstruction()->InputAt(0);
+ ASSERT_TRUE(inst->IsLongConstant());
+ ASSERT_EQ(inst->AsLongConstant()->GetValue(), INT64_C(-4294967296));
+ };
+
+ // Expected difference after dead code elimination.
+ diff_t expected_dce_diff = {
+ { " 4: LongConstant\n", removed },
+ };
+ std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff);
+
+ TestCode(data,
+ expected_before,
+ expected_after_cf,
+ expected_after_dce,
+ check_after_cf,
+ Primitive::kPrimLong);
+}
+
+/**
* Tiny three-register program exercising int constant folding on addition.
*
* 16-bit
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 296c1b02fc..efaf48cc9f 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -1008,12 +1008,8 @@ HConstant* HUnaryOperation::TryStaticEvaluation() const {
int32_t value = Evaluate(GetInput()->AsIntConstant()->GetValue());
return GetBlock()->GetGraph()->GetIntConstant(value);
} else if (GetInput()->IsLongConstant()) {
- // TODO: Implement static evaluation of long unary operations.
- //
- // Do not exit with a fatal condition here. Instead, simply
- // return `null' to notify the caller that this instruction
- // cannot (yet) be statically evaluated.
- return nullptr;
+ int64_t value = Evaluate(GetInput()->AsLongConstant()->GetValue());
+ return GetBlock()->GetGraph()->GetLongConstant(value);
}
return nullptr;
}