diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/possible-constant.h | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/src/ir/possible-constant.h b/src/ir/possible-constant.h index c75669dab..f8b690a93 100644 --- a/src/ir/possible-constant.h +++ b/src/ir/possible-constant.h @@ -72,22 +72,9 @@ public: // Note either a Literal or a Name. template<typename T> void note(T curr) { - if (std::get_if<None>(&value)) { - // This is the first value. - value = curr; - return; - } - - if (std::get_if<Many>(&value)) { - // This was already representing multiple values; nothing changes. - return; - } - - // This is a subsequent value. Check if it is different from all previous - // ones. - if (Variant(curr) != value) { - noteUnknown(); - } + PossibleConstantValues other; + other.value = curr; + combine(other); } // Notes a value that is unknown - it can be anything. We have failed to @@ -118,6 +105,22 @@ public: return true; } + // Nulls compare equal, and we could consider any of the input nulls as the + // combination of the two (as any of them would be valid to place in the + // location we are working to optimize). In order to have simple symmetric + // behavior here, which does not depend on the order of the inputs, use the + // LUB. + if (isNull() && other.isNull()) { + auto type = getConstantLiteral().type.getHeapType(); + auto otherType = other.getConstantLiteral().type.getHeapType(); + auto lub = HeapType::getLeastUpperBound(type, otherType); + if (lub != type) { + value = Literal::makeNull(lub); + return true; + } + return false; + } + return false; } @@ -130,6 +133,10 @@ public: bool isConstantGlobal() const { return std::get_if<Name>(&value); } + bool isNull() const { + return isConstantLiteral() && getConstantLiteral().isNull(); + } + // Returns the single constant value. Literal getConstantLiteral() const { assert(isConstant()); |