Commit 752e59fa by Sagar Thakur Committed by Jim Stichnoth

[Subzero][MIPS32] Fix stack offset assignment of spilled variables on MIPS32

BUG=none R=stichnot@chromium.org Review URL: https://codereview.chromium.org/2166643003 . Patch from Sagar Thakur <sagar.thakur@imgtec.com>.
parent 1608a913
...@@ -105,6 +105,36 @@ uint32_t applyStackAlignment(uint32_t Value) { ...@@ -105,6 +105,36 @@ uint32_t applyStackAlignment(uint32_t Value) {
TargetMIPS32::TargetMIPS32(Cfg *Func) : TargetLowering(Func) {} TargetMIPS32::TargetMIPS32(Cfg *Func) : TargetLowering(Func) {}
void TargetMIPS32::assignVarStackSlots(VarList &SortedSpilledVariables,
size_t SpillAreaPaddingBytes,
size_t SpillAreaSizeBytes,
size_t GlobalsAndSubsequentPaddingSize) {
const VariablesMetadata *VMetadata = Func->getVMetadata();
size_t GlobalsSpaceUsed = SpillAreaPaddingBytes;
size_t NextStackOffset = SpillAreaPaddingBytes;
CfgVector<size_t> LocalsSize(Func->getNumNodes());
const bool SimpleCoalescing = !callsReturnsTwice();
for (Variable *Var : SortedSpilledVariables) {
size_t Increment = typeWidthInBytesOnStack(Var->getType());
if (SimpleCoalescing && VMetadata->isTracked(Var)) {
if (VMetadata->isMultiBlock(Var)) {
GlobalsSpaceUsed += Increment;
NextStackOffset = GlobalsSpaceUsed;
} else {
SizeT NodeIndex = VMetadata->getLocalUseNode(Var)->getIndex();
LocalsSize[NodeIndex] += Increment;
NextStackOffset = SpillAreaPaddingBytes +
GlobalsAndSubsequentPaddingSize +
LocalsSize[NodeIndex];
}
} else {
NextStackOffset += Increment;
}
Var->setStackOffset(SpillAreaSizeBytes - NextStackOffset);
}
}
void TargetMIPS32::staticInit(GlobalContext *Ctx) { void TargetMIPS32::staticInit(GlobalContext *Ctx) {
(void)Ctx; (void)Ctx;
RegNumT::setLimit(RegMIPS32::Reg_NUM); RegNumT::setLimit(RegMIPS32::Reg_NUM);
...@@ -853,9 +883,20 @@ void TargetMIPS32::addProlog(CfgNode *Node) { ...@@ -853,9 +883,20 @@ void TargetMIPS32::addProlog(CfgNode *Node) {
GlobalsSize + LocalsSlotsPaddingBytes; GlobalsSize + LocalsSlotsPaddingBytes;
// Adds the out args space to the stack, and align SP if necessary. // Adds the out args space to the stack, and align SP if necessary.
TotalStackSizeBytes = PreservedRegsSizeBytes + SpillAreaSizeBytes + if (!NeedsStackAlignment) {
FixedAllocaSizeBytes + SpillAreaSizeBytes += MaxOutArgsSizeBytes * (VariableAllocaUsed ? 0 : 1);
(MaxOutArgsSizeBytes * (VariableAllocaUsed ? 0 : 1)); } else {
uint32_t StackOffset = PreservedRegsSizeBytes;
uint32_t StackSize = applyStackAlignment(StackOffset + SpillAreaSizeBytes);
if (!VariableAllocaUsed)
StackSize = applyStackAlignment(StackSize + MaxOutArgsSizeBytes);
SpillAreaSizeBytes = StackSize - StackOffset;
}
// Combine fixed alloca with SpillAreaSize.
SpillAreaSizeBytes += FixedAllocaSizeBytes;
TotalStackSizeBytes = PreservedRegsSizeBytes + SpillAreaSizeBytes;
// Generate "addiu sp, sp, -TotalStackSizeBytes" // Generate "addiu sp, sp, -TotalStackSizeBytes"
if (TotalStackSizeBytes) { if (TotalStackSizeBytes) {
...@@ -911,8 +952,7 @@ void TargetMIPS32::addProlog(CfgNode *Node) { ...@@ -911,8 +952,7 @@ void TargetMIPS32::addProlog(CfgNode *Node) {
// Fill in stack offsets for locals. // Fill in stack offsets for locals.
assignVarStackSlots(SortedSpilledVariables, SpillAreaPaddingBytes, assignVarStackSlots(SortedSpilledVariables, SpillAreaPaddingBytes,
SpillAreaSizeBytes, GlobalsAndSubsequentPaddingSize, SpillAreaSizeBytes, GlobalsAndSubsequentPaddingSize);
UsesFramePointer);
this->HasComputedFrame = true; this->HasComputedFrame = true;
if (BuildDefs::dump() && Func->isVerbose(IceV_Frame)) { if (BuildDefs::dump() && Func->isVerbose(IceV_Frame)) {
......
...@@ -420,6 +420,16 @@ public: ...@@ -420,6 +420,16 @@ public:
void lowerArguments() override; void lowerArguments() override;
/// Make a pass through the SortedSpilledVariables and actually assign stack
/// slots. SpillAreaPaddingBytes takes into account stack alignment padding.
/// The SpillArea starts after that amount of padding. This matches the scheme
/// in getVarStackSlotParams, where there may be a separate multi-block global
/// var spill area and a local var spill area.
void assignVarStackSlots(VarList &SortedSpilledVariables,
size_t SpillAreaPaddingBytes,
size_t SpillAreaSizeBytes,
size_t GlobalsAndSubsequentPaddingSize);
/// Operand legalization helpers. To deal with address mode constraints, /// Operand legalization helpers. To deal with address mode constraints,
/// the helpers will create a new Operand and emit instructions that /// the helpers will create a new Operand and emit instructions that
/// guarantee that the Operand kind is one of those indicated by the /// guarantee that the Operand kind is one of those indicated by the
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment