Clean up art::HConstant predicates.
- Make the difference between arithmetic zero and zero-bit
pattern non ambiguous.
- Introduce Boolean predicates in art::HIntConstant for when
they are used as Booleans.
- Introduce aritmetic positive and negative zero predicates
for floating-point constants.
Bug: 27639313
Change-Id: Ia04ecc6f6aa7450136028c5362ed429760c883bd
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 3733850..88d39d1 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -2427,8 +2427,13 @@
bool CanBeMoved() const OVERRIDE { return true; }
+ // Is this constant -1 in the arithmetic sense?
virtual bool IsMinusOne() const { return false; }
- virtual bool IsZero() const { return false; }
+ // Is this constant 0 in the arithmetic sense?
+ virtual bool IsArithmeticZero() const { return false; }
+ // Is this constant a 0-bit pattern?
+ virtual bool IsZeroBitPattern() const { return false; }
+ // Is this constant 1 in the arithmetic sense?
virtual bool IsOne() const { return false; }
virtual uint64_t GetValueAsUint64() const = 0;
@@ -2449,6 +2454,9 @@
size_t ComputeHashCode() const OVERRIDE { return 0; }
+ // The null constant representation is a 0-bit pattern.
+ virtual bool IsZeroBitPattern() const { return true; }
+
DECLARE_INSTRUCTION(NullConstant);
private:
@@ -2476,9 +2484,15 @@
size_t ComputeHashCode() const OVERRIDE { return GetValue(); }
bool IsMinusOne() const OVERRIDE { return GetValue() == -1; }
- bool IsZero() const OVERRIDE { return GetValue() == 0; }
+ bool IsArithmeticZero() const OVERRIDE { return GetValue() == 0; }
+ bool IsZeroBitPattern() const OVERRIDE { return GetValue() == 0; }
bool IsOne() const OVERRIDE { return GetValue() == 1; }
+ // Integer constants are used to encode Boolean values as well,
+ // where 1 means true and 0 means false.
+ bool IsTrue() const { return GetValue() == 1; }
+ bool IsFalse() const { return GetValue() == 0; }
+
DECLARE_INSTRUCTION(IntConstant);
private:
@@ -2509,7 +2523,8 @@
size_t ComputeHashCode() const OVERRIDE { return static_cast<size_t>(GetValue()); }
bool IsMinusOne() const OVERRIDE { return GetValue() == -1; }
- bool IsZero() const OVERRIDE { return GetValue() == 0; }
+ bool IsArithmeticZero() const OVERRIDE { return GetValue() == 0; }
+ bool IsZeroBitPattern() const OVERRIDE { return GetValue() == 0; }
bool IsOne() const OVERRIDE { return GetValue() == 1; }
DECLARE_INSTRUCTION(LongConstant);
@@ -2542,7 +2557,16 @@
bool IsMinusOne() const OVERRIDE {
return bit_cast<uint32_t, float>(value_) == bit_cast<uint32_t, float>((-1.0f));
}
- bool IsZero() const OVERRIDE {
+ bool IsArithmeticZero() const OVERRIDE {
+ return std::fpclassify(value_) == FP_ZERO;
+ }
+ bool IsArithmeticPositiveZero() const {
+ return IsArithmeticZero() && !std::signbit(value_);
+ }
+ bool IsArithmeticNegativeZero() const {
+ return IsArithmeticZero() && std::signbit(value_);
+ }
+ bool IsZeroBitPattern() const OVERRIDE {
return bit_cast<uint32_t, float>(value_) == bit_cast<uint32_t, float>(0.0f);
}
bool IsOne() const OVERRIDE {
@@ -2584,7 +2608,16 @@
bool IsMinusOne() const OVERRIDE {
return bit_cast<uint64_t, double>(value_) == bit_cast<uint64_t, double>((-1.0));
}
- bool IsZero() const OVERRIDE {
+ bool IsArithmeticZero() const OVERRIDE {
+ return std::fpclassify(value_) == FP_ZERO;
+ }
+ bool IsArithmeticPositiveZero() const {
+ return IsArithmeticZero() && !std::signbit(value_);
+ }
+ bool IsArithmeticNegativeZero() const {
+ return IsArithmeticZero() && std::signbit(value_);
+ }
+ bool IsZeroBitPattern() const OVERRIDE {
return bit_cast<uint64_t, double>(value_) == bit_cast<uint64_t, double>((0.0));
}
bool IsOne() const OVERRIDE {