summaryrefslogtreecommitdiff
path: root/src/ir/possible-contents.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir/possible-contents.cpp')
-rw-r--r--src/ir/possible-contents.cpp26
1 files changed, 19 insertions, 7 deletions
diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp
index b2a0b417a..83762a458 100644
--- a/src/ir/possible-contents.cpp
+++ b/src/ir/possible-contents.cpp
@@ -197,18 +197,17 @@ void PossibleContents::intersectWithFullCone(const PossibleContents& other) {
return;
}
- if (isLiteral() || isGlobal()) {
+ if (isLiteral()) {
// The information about the value being identical to a particular literal
- // or immutable global is not removed by intersection, if the type is in the
- // cone we are intersecting with.
+ // is not removed by intersection, if the type is in the cone we are
+ // intersecting with.
if (isSubType) {
return;
}
- // The type must change, so continue down to the generic code path.
- // TODO: for globals we could perhaps refine the type here, but then the
- // type on GlobalInfo would not match the module, so that needs some
- // refactoring.
+ // The type must change in a nontrivial manner, so continue down to the
+ // generic code path. This will stop being a Literal. TODO: can we do better
+ // here?
}
// Intersect the cones, as there is no more specific information we can use.
@@ -226,6 +225,14 @@ void PossibleContents::intersectWithFullCone(const PossibleContents& other) {
newHeapType = heapType;
}
+ // Note the global's information, if we started as a global. In that case, the
+ // code below will refine our type but we can remain a global, which we will
+ // accomplish by restoring our global status at the end.
+ std::optional<Name> globalName;
+ if (isGlobal()) {
+ globalName = getGlobal();
+ }
+
auto newType = Type(newHeapType, nullability);
// By assumption |other| has full depth. Consider the other cone in |this|.
@@ -261,6 +268,11 @@ void PossibleContents::intersectWithFullCone(const PossibleContents& other) {
value = ConeType{newType, newDepth};
}
+
+ if (globalName) {
+ // Restore the global but keep the new and refined type.
+ value = GlobalInfo{*globalName, getType()};
+ }
}
bool PossibleContents::haveIntersection(const PossibleContents& a,