Index: src/IceOperand.h |
diff --git a/src/IceOperand.h b/src/IceOperand.h |
index 041adfd1556716e6e2b1acd4a7122782fa0eb0fd..5033592e56253f907813dc8d1cfbecd9bea757c3 100644 |
--- a/src/IceOperand.h |
+++ b/src/IceOperand.h |
@@ -696,12 +696,27 @@ public: |
return IgnoreLiveness || IsRematerializable; |
} |
+ /// Returns true if the variable either has a definite stack offset, or has |
+ /// the UndeterminedStackOffset such that it is guaranteed to have a definite |
+ /// stack offset at emission time. |
bool hasStackOffset() const { return StackOffset != InvalidStackOffset; } |
+ /// Returns true if the variable has a stack offset that is known at this |
+ /// time. |
+ bool hasKnownStackOffset() const { |
+ return StackOffset != InvalidStackOffset && |
+ StackOffset != UndeterminedStackOffset; |
+ } |
int32_t getStackOffset() const { |
- assert(hasStackOffset()); |
+ assert(hasKnownStackOffset()); |
return StackOffset; |
} |
void setStackOffset(int32_t Offset) { StackOffset = Offset; } |
+ /// Set a "placeholder" stack offset before its actual offset has been |
+ /// determined. |
+ void setHasStackOffset() { |
+ if (!hasStackOffset()) |
+ StackOffset = UndeterminedStackOffset; |
+ } |
/// Returns the variable's stack offset in symbolic form, to improve |
/// readability in DecorateAsm mode. |
std::string getSymbolicStackOffset() const { |
@@ -729,6 +744,7 @@ public: |
bool mustNotHaveReg() const { |
return RegRequirement == RR_MustNotHaveRegister; |
} |
+ bool mayHaveReg() const { return RegRequirement == RR_MayHaveRegister; } |
void setRematerializable(RegNumT NewRegNum, int32_t NewOffset) { |
IsRematerializable = true; |
setRegNum(NewRegNum); |
@@ -789,6 +805,18 @@ public: |
Root = Root->LinkedTo; |
return Root; |
} |
+ /// Follow the LinkedTo chain up to the furthest stack-allocated ancestor. |
+ /// This is only certain to be accurate after register allocation and stack |
+ /// slot assignment have completed. |
+ Variable *getLinkedToStackRoot() const { |
+ Variable *FurthestStackVar = nullptr; |
+ for (Variable *Root = LinkedTo; Root != nullptr; Root = Root->LinkedTo) { |
+ if (!Root->hasReg() && Root->hasStackOffset()) { |
+ FurthestStackVar = Root; |
+ } |
+ } |
+ return FurthestStackVar; |
+ } |
static bool classof(const Operand *Operand) { |
OperandKind Kind = Operand->getKind(); |
@@ -825,7 +853,10 @@ protected: |
RegNumT RegNum; |
/// RegNumTmp is the tentative assignment during register allocation. |
RegNumT RegNumTmp; |
- static constexpr int32_t InvalidStackOffset = -1; |
+ static constexpr int32_t InvalidStackOffset = |
+ std::numeric_limits<int32_t>::min(); |
+ static constexpr int32_t UndeterminedStackOffset = |
+ 1 + std::numeric_limits<int32_t>::min(); |
/// StackOffset is the canonical location on stack (only if |
/// RegNum.hasNoValue() || IsArgument). |
int32_t StackOffset = InvalidStackOffset; |