[optimizing] Fold HTypeConversion of constants
While looking into optimizing long shifts on x86, I found that the
compiler wasn't folding HTypeConversion of constants. Add simple
conversions of constants, taking care of float/double values
with NaNs and small/large values, ensuring Java conversion semantics.
Add checker cases to see that constant folding of HTypeConversion is
done.
Ensure 422-type-conversion type conversion routiness don't get
inlined to avoid compile time folding.
Change-Id: I5a4eb376b64bc4e41bf908af5875bed312efb228
Signed-off-by: Mark Mendell <mark.p.mendell@intel.com>
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 41adc72..47da9cc 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -16,6 +16,7 @@
#include "nodes.h"
+#include "code_generator.h"
#include "ssa_builder.h"
#include "base/bit_vector-inl.h"
#include "utils/growable_array.h"
@@ -794,6 +795,84 @@
}
}
+HConstant* HTypeConversion::TryStaticEvaluation() const {
+ HGraph* graph = GetBlock()->GetGraph();
+ if (GetInput()->IsIntConstant()) {
+ int32_t value = GetInput()->AsIntConstant()->GetValue();
+ switch (GetResultType()) {
+ case Primitive::kPrimLong:
+ return graph->GetLongConstant(static_cast<int64_t>(value));
+ case Primitive::kPrimFloat:
+ return graph->GetFloatConstant(static_cast<float>(value));
+ case Primitive::kPrimDouble:
+ return graph->GetDoubleConstant(static_cast<double>(value));
+ default:
+ return nullptr;
+ }
+ } else if (GetInput()->IsLongConstant()) {
+ int64_t value = GetInput()->AsLongConstant()->GetValue();
+ switch (GetResultType()) {
+ case Primitive::kPrimInt:
+ return graph->GetIntConstant(static_cast<int32_t>(value));
+ case Primitive::kPrimFloat:
+ return graph->GetFloatConstant(static_cast<float>(value));
+ case Primitive::kPrimDouble:
+ return graph->GetDoubleConstant(static_cast<double>(value));
+ default:
+ return nullptr;
+ }
+ } else if (GetInput()->IsFloatConstant()) {
+ float value = GetInput()->AsFloatConstant()->GetValue();
+ switch (GetResultType()) {
+ case Primitive::kPrimInt:
+ if (std::isnan(value))
+ return graph->GetIntConstant(0);
+ if (value >= kPrimIntMax)
+ return graph->GetIntConstant(kPrimIntMax);
+ if (value <= kPrimIntMin)
+ return graph->GetIntConstant(kPrimIntMin);
+ return graph->GetIntConstant(static_cast<int32_t>(value));
+ case Primitive::kPrimLong:
+ if (std::isnan(value))
+ return graph->GetLongConstant(0);
+ if (value >= kPrimLongMax)
+ return graph->GetLongConstant(kPrimLongMax);
+ if (value <= kPrimLongMin)
+ return graph->GetLongConstant(kPrimLongMin);
+ return graph->GetLongConstant(static_cast<int64_t>(value));
+ case Primitive::kPrimDouble:
+ return graph->GetDoubleConstant(static_cast<double>(value));
+ default:
+ return nullptr;
+ }
+ } else if (GetInput()->IsDoubleConstant()) {
+ double value = GetInput()->AsDoubleConstant()->GetValue();
+ switch (GetResultType()) {
+ case Primitive::kPrimInt:
+ if (std::isnan(value))
+ return graph->GetIntConstant(0);
+ if (value >= kPrimIntMax)
+ return graph->GetIntConstant(kPrimIntMax);
+ if (value <= kPrimLongMin)
+ return graph->GetIntConstant(kPrimIntMin);
+ return graph->GetIntConstant(static_cast<int32_t>(value));
+ case Primitive::kPrimLong:
+ if (std::isnan(value))
+ return graph->GetLongConstant(0);
+ if (value >= kPrimLongMax)
+ return graph->GetLongConstant(kPrimLongMax);
+ if (value <= kPrimLongMin)
+ return graph->GetLongConstant(kPrimLongMin);
+ return graph->GetLongConstant(static_cast<int64_t>(value));
+ case Primitive::kPrimFloat:
+ return graph->GetFloatConstant(static_cast<float>(value));
+ default:
+ return nullptr;
+ }
+ }
+ return nullptr;
+}
+
HConstant* HUnaryOperation::TryStaticEvaluation() const {
if (GetInput()->IsIntConstant()) {
int32_t value = Evaluate(GetInput()->AsIntConstant()->GetValue());