diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index 8f8a852480d..6720758e646 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -85,6 +85,13 @@ class MachineFrameInfo { /// to be allocated on entry to the function. /// unsigned StackSize; + + /// MaxAlignment - The prolog/epilog code inserter may process objects + /// that require greater alignment than the default alignment the target + /// provides. In these cases, MaxAlignment is set to the new alignment + /// necessary to easily calculate fixed offsets for each stack object. + /// + unsigned MaxAlignment; /// HasCalls - Set to true if this function has any function calls. This is /// only valid during and after prolog/epilog code insertion. @@ -99,7 +106,7 @@ class MachineFrameInfo { unsigned MaxCallFrameSize; public: MachineFrameInfo() { - NumFixedObjects = StackSize = 0; + NumFixedObjects = StackSize = MaxAlignment = 0; HasVarSizedObjects = false; HasCalls = false; MaxCallFrameSize = 0; @@ -163,6 +170,16 @@ public: /// void setStackSize(unsigned Size) { StackSize = Size; } + /// getMaxAlignment - Return the alignment in bytes that this function must be + /// aligned to, which is greater than the default stack alignment provided by + /// the target. + /// + unsigned getMaxAlignment() const { return MaxAlignment; } + + /// setMaxAlignment - Set the preferred alignment. + /// + void setMaxAlignment(unsigned Align) { MaxAlignment = Align; } + /// hasCalls - Return true if the current function has no function calls. /// This is only valid during or after prolog/epilog code emission. /// diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index e38c740e8dd..95932207a58 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -258,6 +258,7 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { MachineFrameInfo *FFI = Fn.getFrameInfo(); unsigned StackAlignment = TFI.getStackAlignment(); + unsigned MaxAlign = StackAlignment; // Start at the beginning of the local area. // The Offset is the distance from the stack top in the direction @@ -295,9 +296,11 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { Offset += FFI->getObjectSize(i); unsigned Align = FFI->getObjectAlignment(i); - assert(Align <= StackAlignment && "Cannot align stack object to higher " - "alignment boundary than the stack itself!"); - Offset = (Offset+Align-1)/Align*Align; // Adjust to Alignment boundary... + // If the alignment of this object is greater than that of the stack, then + // increase the stack alignment to match. + MaxAlign = std::max(MaxAlign, Align); + // Adjust to alignment boundary + Offset = (Offset+Align-1)/Align*Align; if (StackGrowsDown) { FFI->setObjectOffset(i, -Offset); // Set the computed offset @@ -315,6 +318,11 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { // Set the final value of the stack pointer... FFI->setStackSize(Offset+TFI.getOffsetOfLocalArea()); + // If we have a new stack alignment, set the preferred stack alignment so that + // the targets can do the appropriate thing to properly align the stack above + // the default alignment. + if (MaxAlign > StackAlignment) + FFI->setMaxAlignment(MaxAlign); } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 3b5ef32e3c3..64256c963eb 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -147,7 +147,9 @@ FunctionLoweringInfo::FunctionLoweringInfo(TargetLowering &tli, if (ConstantUInt *CUI = dyn_cast(AI->getArraySize())) { const Type *Ty = AI->getAllocatedType(); uint64_t TySize = TLI.getTargetData().getTypeSize(Ty); - unsigned Align = TLI.getTargetData().getTypeAlignment(Ty); + unsigned Align = + std::max((unsigned)TLI.getTargetData().getTypeAlignment(Ty), + AI->getAlignment()); // If the alignment of the value is smaller than the size of the value, // and if the size of the value is particularly small (<= 8 bytes), @@ -636,7 +638,8 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) { const Type *Ty = I.getAllocatedType(); uint64_t TySize = TLI.getTargetData().getTypeSize(Ty); - unsigned Align = TLI.getTargetData().getTypeAlignment(Ty); + unsigned Align = std::max((unsigned)TLI.getTargetData().getTypeAlignment(Ty), + I.getAlignment()); SDOperand AllocSize = getValue(I.getArraySize()); MVT::ValueType IntPtr = TLI.getPointerTy(); diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index 658e294ec82..ae136cbc420 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -26,6 +26,7 @@ #include "llvm/Target/TargetOptions.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/MathExtras.h" #include "llvm/ADT/STLExtras.h" #include #include @@ -294,6 +295,11 @@ void PPCRegisterInfo::emitPrologue(MachineFunction &MF) const { // Get the number of bytes to allocate from the FrameInfo unsigned NumBytes = MFI->getStackSize(); + + // Get the alignments provided by the target, and the maximum alignment + // (if any) of the fixed frame objects. + unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment(); + unsigned MaxAlign = MFI->getMaxAlignment(); // If we have calls, we cannot use the red zone to store callee save registers // and we must set up a stack frame, so calculate the necessary size here. @@ -307,14 +313,15 @@ void PPCRegisterInfo::emitPrologue(MachineFunction &MF) const { // If we are a leaf function, and use up to 224 bytes of stack space, // and don't have a frame pointer, then we do not need to adjust the stack // pointer (we fit in the Red Zone). - if ((NumBytes == 0) || (NumBytes <= 224 && !hasFP(MF) && !MFI->hasCalls())) { + if ((NumBytes == 0) || (NumBytes <= 224 && !hasFP(MF) && !MFI->hasCalls() && + MaxAlign <= TargetAlign)) { MFI->setStackSize(0); return; } // Add the size of R1 to NumBytes size for the store of R1 to the bottom // of the stack and round the size to a multiple of the alignment. - unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); + unsigned Align = std::max(TargetAlign, MaxAlign); unsigned GPRSize = 4; unsigned Size = hasFP(MF) ? GPRSize + GPRSize : GPRSize; NumBytes = (NumBytes+Size+Align-1)/Align*Align; @@ -336,7 +343,23 @@ void PPCRegisterInfo::emitPrologue(MachineFunction &MF) const { MI = BuildMI(PPC::STWUX, 3).addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0); MBB.insert(MBBI, MI); } - + + // If there is a preferred stack alignment, align R1 now + // FIXME: If this ever matters, this could be made more efficient by folding + // this into the code above, so that we don't issue two store+update + // instructions. + if (MaxAlign > TargetAlign) { + assert(isPowerOf2_32(MaxAlign) && MaxAlign < 32767 && "Invalid alignment!"); + MI = BuildMI(PPC::RLWINM, 4, PPC::R0).addReg(PPC::R1).addImm(0) + .addImm(32-Log2_32(MaxAlign)).addImm(31); + MBB.insert(MBBI, MI); + MI = BuildMI(PPC::SUBFIC, 2, PPC::R0).addReg(PPC::R0).addImm(MaxAlign); + MBB.insert(MBBI, MI); + MI = BuildMI(PPC::STWUX, 3).addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0); + MBB.insert(MBBI, MI); + } + + // If there is a frame pointer, copy R1 (SP) into R31 (FP) if (hasFP(MF)) { MI = BuildMI(PPC::STW, 3).addReg(PPC::R31).addSImm(GPRSize).addReg(PPC::R1); MBB.insert(MBBI, MI);