Index: src/IceCfg.cpp |
diff --git a/src/IceCfg.cpp b/src/IceCfg.cpp |
index 6ae12bb10b356bd38b0e474a24904f037e83aa43..65844b9f9872c03ddf45bfa00be1d0cee6b2eda3 100644 |
--- a/src/IceCfg.cpp |
+++ b/src/IceCfg.cpp |
@@ -494,53 +494,44 @@ void Cfg::sortAndCombineAllocas(CfgVector<Inst *> &Allocas, |
uint32_t TotalSize = Utils::applyAlignment(CurrentOffset, CombinedAlignment); |
// Ensure every alloca was assigned an offset. |
assert(Allocas.size() == Offsets.size()); |
- Variable *BaseVariable = makeVariable(IceType_i32); |
- Variable *AllocaDest = BaseVariable; |
- // Emit one addition for each alloca after the first. |
- for (size_t i = 0; i < Allocas.size(); ++i) { |
- auto *Alloca = llvm::cast<InstAlloca>(Allocas[i]); |
- switch (BaseVariableType) { |
- case BVT_FramePointer: |
- case BVT_UserPointer: { |
+ |
+ switch (BaseVariableType) { |
+ case BVT_UserPointer: { |
+ Variable *BaseVariable = makeVariable(IceType_i32); |
+ for (SizeT i = 0; i < Allocas.size(); ++i) { |
+ auto *Alloca = llvm::cast<InstAlloca>(Allocas[i]); |
// Emit a new addition operation to replace the alloca. |
Operand *AllocaOffset = Ctx->getConstantInt32(Offsets[i]); |
InstArithmetic *Add = |
InstArithmetic::create(this, InstArithmetic::Add, Alloca->getDest(), |
BaseVariable, AllocaOffset); |
Insts.push_front(Add); |
- } break; |
- case BVT_StackPointer: { |
+ Alloca->setDeleted(); |
+ } |
+ Operand *AllocaSize = Ctx->getConstantInt32(TotalSize); |
+ InstAlloca *CombinedAlloca = |
+ InstAlloca::create(this, BaseVariable, AllocaSize, CombinedAlignment); |
+ CombinedAlloca->setKnownFrameOffset(); |
+ Insts.push_front(CombinedAlloca); |
+ } break; |
+ case BVT_StackPointer: |
+ case BVT_FramePointer: { |
+ for (SizeT i = 0; i < Allocas.size(); ++i) { |
+ auto *Alloca = llvm::cast<InstAlloca>(Allocas[i]); |
// Emit a fake definition of the rematerializable variable. |
Variable *Dest = Alloca->getDest(); |
InstFakeDef *Def = InstFakeDef::create(this, Dest); |
- Dest->setRematerializable(getTarget()->getStackReg(), Offsets[i]); |
+ if (BaseVariableType == BVT_StackPointer) |
+ Dest->setRematerializable(getTarget()->getStackReg(), Offsets[i]); |
+ else |
+ Dest->setRematerializable(getTarget()->getFrameReg(), Offsets[i]); |
Insts.push_front(Def); |
- } break; |
+ Alloca->setDeleted(); |
} |
- Alloca->setDeleted(); |
- } |
- Operand *AllocaSize = Ctx->getConstantInt32(TotalSize); |
- switch (BaseVariableType) { |
- case BVT_FramePointer: { |
- // Adjust the return of the alloca to the top of the returned region. |
- AllocaDest = makeVariable(IceType_i32); |
- InstArithmetic *Add = InstArithmetic::create( |
- this, InstArithmetic::Add, BaseVariable, AllocaDest, AllocaSize); |
- Insts.push_front(Add); |
+ // Allocate the fixed area in the function prolog. |
+ getTarget()->reserveFixedAllocaArea(TotalSize, CombinedAlignment); |
} break; |
- case BVT_StackPointer: { |
- // Emit a fake use to keep the Alloca live. |
- InstFakeUse *Use = InstFakeUse::create(this, AllocaDest); |
- Insts.push_front(Use); |
- } break; |
- case BVT_UserPointer: |
- break; |
} |
- // And insert the fused alloca. |
- InstAlloca *CombinedAlloca = |
- InstAlloca::create(this, AllocaSize, CombinedAlignment, AllocaDest); |
- CombinedAlloca->setKnownFrameOffset(); |
- Insts.push_front(CombinedAlloca); |
} |
void Cfg::processAllocas(bool SortAndCombine) { |
@@ -595,7 +586,7 @@ void Cfg::processAllocas(bool SortAndCombine) { |
// Allocas in the entry block that have constant size and alignment greater |
// than the function's stack alignment. |
CfgVector<Inst *> AlignedAllocas; |
- // Maximum alignment used for the dynamic/aligned allocas. |
+ // Maximum alignment used by any alloca. |
uint32_t MaxAlignment = StackAlignment; |
for (Inst &Instr : EntryNode->getInsts()) { |
if (auto *Alloca = llvm::dyn_cast<InstAlloca>(&Instr)) { |
@@ -623,14 +614,16 @@ void Cfg::processAllocas(bool SortAndCombine) { |
// do not have a known offset from either the stack or frame pointer. |
// They grow up from a user pointer from an alloca. |
sortAndCombineAllocas(AlignedAllocas, MaxAlignment, Insts, BVT_UserPointer); |
+ // Fixed size allocas are addressed relative to the frame pointer. |
+ sortAndCombineAllocas(FixedAllocas, StackAlignment, Insts, |
+ BVT_FramePointer); |
+ } else { |
+ // Otherwise, fixed size allocas are addressed relative to the stack unless |
+ // there are dynamic allocas. |
+ const AllocaBaseVariableType BasePointerType = |
+ (HasDynamicAllocation ? BVT_FramePointer : BVT_StackPointer); |
+ sortAndCombineAllocas(FixedAllocas, MaxAlignment, Insts, BasePointerType); |
} |
- // Otherwise, fixed size allocas are always addressed relative to the stack |
- // unless there are dynamic allocas. |
- // TODO(sehr): re-enable frame pointer and decrementing addressing. |
- AllocaBaseVariableType BasePointerType = |
- (HasDynamicAllocation ? BVT_UserPointer : BVT_StackPointer); |
- sortAndCombineAllocas(FixedAllocas, MaxAlignment, Insts, BasePointerType); |
- |
if (!FixedAllocas.empty() || !AlignedAllocas.empty()) |
// No use calling findRematerializable() unless there is some |
// rematerializable alloca instruction to seed it. |