| 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.
|
|
|