Index: include/llvm/Target/TargetRegisterInfo.h =================================================================== --- include/llvm/Target/TargetRegisterInfo.h +++ include/llvm/Target/TargetRegisterInfo.h @@ -21,6 +21,7 @@ #include "llvm/CodeGen/MachineValueType.h" #include "llvm/IR/CallingConv.h" #include "llvm/MC/MCRegisterInfo.h" +#include "llvm/Support/CommandLine.h" #include #include @@ -33,6 +34,8 @@ class VirtRegMap; class raw_ostream; +extern cl::opt ForceStackAlign; + class TargetRegisterClass { public: typedef const MCPhysReg* iterator; @@ -781,12 +784,14 @@ return false; } + /// canRealignStack - true if the stack can be realigned for the target. + virtual bool canRealignStack(const MachineFunction &MF) const; + /// needsStackRealignment - true if storage within the function requires the /// stack pointer to be aligned more than the normal calling convention calls - /// for. - virtual bool needsStackRealignment(const MachineFunction &MF) const { - return false; - } + /// for. This cannot be overriden by the target, but canRealignStack can be + /// overriden. + bool needsStackRealignment(const MachineFunction &MF) const; /// getFrameIndexInstrOffset - Get the offset from the referenced frame /// index in the instruction, if there is one. Index: lib/CodeGen/TargetRegisterInfo.cpp =================================================================== --- lib/CodeGen/TargetRegisterInfo.cpp +++ lib/CodeGen/TargetRegisterInfo.cpp @@ -11,13 +11,26 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/ADT/BitVector.h" +#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/VirtRegMap.h" +#include "llvm/IR/Function.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetFrameLowering.h" +#include "llvm/Target/TargetRegisterInfo.h" + +#define DEBUG_TYPE "target-reg-info" + +namespace llvm { +cl::opt + ForceStackAlign("force-align-stack", + cl::desc("Force align the stack to the minimum alignment" + " needed for the function."), + cl::init(false), cl::Hidden); +} // end namespace llvm using namespace llvm; @@ -295,6 +308,26 @@ Hints.push_back(Phys); } +bool TargetRegisterInfo::canRealignStack(const MachineFunction &MF) const { + return !MF.getFunction()->hasFnAttribute("no-realign-stack"); +} + +bool TargetRegisterInfo::needsStackRealignment( + const MachineFunction &MF) const { + const MachineFrameInfo *MFI = MF.getFrameInfo(); + const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); + const Function *F = MF.getFunction(); + unsigned StackAlign = TFI->getStackAlignment(); + bool requiresRealignment = ((MFI->getMaxAlignment() > StackAlign) || + F->hasFnAttribute(Attribute::StackAlignment)); + if (ForceStackAlign || requiresRealignment) { + if (canRealignStack(MF)) + return true; + DEBUG(dbgs() << "Can't realign function's stack: " << F->getName() << "\n"); + } + return false; +} + #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void TargetRegisterInfo::dumpReg(unsigned Reg, unsigned SubRegIndex, Index: lib/Target/AArch64/AArch64RegisterInfo.h =================================================================== --- lib/Target/AArch64/AArch64RegisterInfo.h +++ lib/Target/AArch64/AArch64RegisterInfo.h @@ -93,9 +93,6 @@ unsigned getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const override; - // Base pointer (stack realignment) support. - bool canRealignStack(const MachineFunction &MF) const; - bool needsStackRealignment(const MachineFunction &MF) const override; }; } // end namespace llvm Index: lib/Target/AArch64/AArch64RegisterInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64RegisterInfo.cpp +++ lib/Target/AArch64/AArch64RegisterInfo.cpp @@ -186,29 +186,6 @@ return false; } -bool AArch64RegisterInfo::canRealignStack(const MachineFunction &MF) const { - - if (MF.getFunction()->hasFnAttribute("no-realign-stack")) - return false; - - return true; -} - -// FIXME: share this with other backends with identical implementation? -bool -AArch64RegisterInfo::needsStackRealignment(const MachineFunction &MF) const { - const MachineFrameInfo *MFI = MF.getFrameInfo(); - const AArch64FrameLowering *TFI = getFrameLowering(MF); - const Function *F = MF.getFunction(); - unsigned StackAlign = TFI->getStackAlignment(); - bool requiresRealignment = - ((MFI->getMaxAlignment() > StackAlign) || - F->getAttributes().hasAttribute(AttributeSet::FunctionIndex, - Attribute::StackAlignment)); - - return requiresRealignment && canRealignStack(MF); -} - unsigned AArch64RegisterInfo::getFrameRegister(const MachineFunction &MF) const { const AArch64FrameLowering *TFI = getFrameLowering(MF); Index: lib/Target/ARM/ARMBaseRegisterInfo.h =================================================================== --- lib/Target/ARM/ARMBaseRegisterInfo.h +++ lib/Target/ARM/ARMBaseRegisterInfo.h @@ -133,8 +133,7 @@ bool hasBasePointer(const MachineFunction &MF) const; - bool canRealignStack(const MachineFunction &MF) const; - bool needsStackRealignment(const MachineFunction &MF) const override; + bool canRealignStack(const MachineFunction &MF) const override; int64_t getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const override; bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override; Index: lib/Target/ARM/ARMBaseRegisterInfo.cpp =================================================================== --- lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -338,7 +338,7 @@ // 1. Dynamic stack realignment is explicitly disabled, // 2. This is a Thumb1 function (it's not useful, so we don't bother), or // 3. There are VLAs in the function and the base pointer is disabled. - if (MF.getFunction()->hasFnAttribute("no-realign-stack")) + if (!TargetRegisterInfo::canRealignStack(MF)) return false; if (AFI->isThumb1OnlyFunction()) return false; @@ -356,18 +356,6 @@ } bool ARMBaseRegisterInfo:: -needsStackRealignment(const MachineFunction &MF) const { - const MachineFrameInfo *MFI = MF.getFrameInfo(); - const ARMFrameLowering *TFI = getFrameLowering(MF); - const Function *F = MF.getFunction(); - unsigned StackAlign = TFI->getStackAlignment(); - bool requiresRealignment = ((MFI->getMaxAlignment() > StackAlign) || - F->hasFnAttribute(Attribute::StackAlignment)); - - return requiresRealignment && canRealignStack(MF); -} - -bool ARMBaseRegisterInfo:: cannotEliminateFrame(const MachineFunction &MF) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); if (MF.getTarget().Options.DisableFramePointerElim(MF) && MFI->adjustsStack()) Index: lib/Target/Hexagon/HexagonRegisterInfo.h =================================================================== --- lib/Target/Hexagon/HexagonRegisterInfo.h +++ lib/Target/Hexagon/HexagonRegisterInfo.h @@ -63,8 +63,6 @@ return true; } - bool needsStackRealignment(const MachineFunction &MF) const override; - /// Returns true if the frame pointer is valid. bool useFPForScavengingIndex(const MachineFunction &MF) const override; Index: lib/Target/Hexagon/HexagonRegisterInfo.cpp =================================================================== --- lib/Target/Hexagon/HexagonRegisterInfo.cpp +++ lib/Target/Hexagon/HexagonRegisterInfo.cpp @@ -245,13 +245,6 @@ } -bool -HexagonRegisterInfo::needsStackRealignment(const MachineFunction &MF) const { - const MachineFrameInfo *MFI = MF.getFrameInfo(); - return MFI->getMaxAlignment() > 8; -} - - unsigned HexagonRegisterInfo::getFirstCallerSavedNonParamReg() const { return Hexagon::R6; } Index: lib/Target/Mips/MipsRegisterInfo.h =================================================================== --- lib/Target/Mips/MipsRegisterInfo.h +++ lib/Target/Mips/MipsRegisterInfo.h @@ -61,9 +61,7 @@ RegScavenger *RS = nullptr) const; // Stack realignment queries. - bool canRealignStack(const MachineFunction &MF) const; - - bool needsStackRealignment(const MachineFunction &MF) const override; + bool canRealignStack(const MachineFunction &MF) const override; /// Debug information queries. unsigned getFrameRegister(const MachineFunction &MF) const override; Index: lib/Target/Mips/MipsRegisterInfo.cpp =================================================================== --- lib/Target/Mips/MipsRegisterInfo.cpp +++ lib/Target/Mips/MipsRegisterInfo.cpp @@ -284,6 +284,16 @@ } bool MipsRegisterInfo::canRealignStack(const MachineFunction &MF) const { + // Avoid realigning functions that explicitly do not want to be realigned. + // Normally, we should report an error when a function should be dynamically + // realigned but also has the attribute no-realign-stack. Unfortunately, + // with this attribute, MachineFrameInfo clamps each new object's alignment + // to that of the stack's alignment as specified by the ABI. As a result, + // the information of whether we have objects with larger alignment + // requirement than the stack's alignment is already lost at this point. + if (!TargetRegisterInfo::canRealignStack(MF)) + return false; + const MipsSubtarget &Subtarget = MF.getSubtarget(); unsigned FP = Subtarget.isGP32bit() ? Mips::FP : Mips::FP_64; unsigned BP = Subtarget.isGP32bit() ? Mips::S7 : Mips::S7_64; @@ -306,42 +316,3 @@ // sized objects. return MF.getRegInfo().canReserveReg(BP); } - -bool MipsRegisterInfo::needsStackRealignment(const MachineFunction &MF) const { - const MipsSubtarget &Subtarget = MF.getSubtarget(); - const MachineFrameInfo *MFI = MF.getFrameInfo(); - - bool CanRealign = canRealignStack(MF); - - // Avoid realigning functions that explicitly do not want to be realigned. - // Normally, we should report an error when a function should be dynamically - // realigned but also has the attribute no-realign-stack. Unfortunately, - // with this attribute, MachineFrameInfo clamps each new object's alignment - // to that of the stack's alignment as specified by the ABI. As a result, - // the information of whether we have objects with larger alignment - // requirement than the stack's alignment is already lost at this point. - if (MF.getFunction()->hasFnAttribute("no-realign-stack")) - return false; - - const Function *F = MF.getFunction(); - if (F->hasFnAttribute(Attribute::StackAlignment)) { -#ifdef DEBUG - if (!CanRealign) - DEBUG(dbgs() << "It's not possible to realign the stack of the function: " - << F->getName() << "\n"); -#endif - return CanRealign; - } - - unsigned StackAlignment = Subtarget.getFrameLowering()->getStackAlignment(); - if (MFI->getMaxAlignment() > StackAlignment) { -#ifdef DEBUG - if (!CanRealign) - DEBUG(dbgs() << "It's not possible to realign the stack of the function: " - << F->getName() << "\n"); -#endif - return CanRealign; - } - - return false; -} Index: lib/Target/PowerPC/PPCRegisterInfo.h =================================================================== --- lib/Target/PowerPC/PPCRegisterInfo.h +++ lib/Target/PowerPC/PPCRegisterInfo.h @@ -136,8 +136,6 @@ // Base pointer (stack realignment) support. unsigned getBaseRegister(const MachineFunction &MF) const; bool hasBasePointer(const MachineFunction &MF) const; - bool canRealignStack(const MachineFunction &MF) const; - bool needsStackRealignment(const MachineFunction &MF) const override; }; } // end namespace llvm Index: lib/Target/PowerPC/PPCRegisterInfo.cpp =================================================================== --- lib/Target/PowerPC/PPCRegisterInfo.cpp +++ lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -898,24 +898,6 @@ return needsStackRealignment(MF); } -bool PPCRegisterInfo::canRealignStack(const MachineFunction &MF) const { - if (MF.getFunction()->hasFnAttribute("no-realign-stack")) - return false; - - return true; -} - -bool PPCRegisterInfo::needsStackRealignment(const MachineFunction &MF) const { - const PPCFrameLowering *TFI = getFrameLowering(MF); - const MachineFrameInfo *MFI = MF.getFrameInfo(); - const Function *F = MF.getFunction(); - unsigned StackAlign = TFI->getStackAlignment(); - bool requiresRealignment = ((MFI->getMaxAlignment() > StackAlign) || - F->hasFnAttribute(Attribute::StackAlignment)); - - return requiresRealignment && canRealignStack(MF); -} - /// Returns true if the instruction's frame index /// reference would be better served by a base register other than FP /// or SP. Used by LocalStackFrameAllocation to determine which frame index Index: lib/Target/WebAssembly/WebAssemblyRegisterInfo.h =================================================================== --- lib/Target/WebAssembly/WebAssemblyRegisterInfo.h +++ lib/Target/WebAssembly/WebAssemblyRegisterInfo.h @@ -41,10 +41,6 @@ // Debug information queries. unsigned getFrameRegister(const MachineFunction &MF) const override; - - // Base pointer (stack realignment) support. - bool canRealignStack(const MachineFunction &MF) const; - bool needsStackRealignment(const MachineFunction &MF) const override; }; } // end namespace llvm Index: lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp =================================================================== --- lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp +++ lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp @@ -66,22 +66,3 @@ const WebAssemblyFrameLowering *TFI = getFrameLowering(MF); return Regs[TFI->hasFP(MF)][TT.isArch64Bit()]; } - -bool WebAssemblyRegisterInfo::canRealignStack(const MachineFunction &MF) const { - return !MF.getFunction()->hasFnAttribute("no-realign-stack"); -} - -// FIXME: share this with other backends with identical implementation? -bool WebAssemblyRegisterInfo::needsStackRealignment( - const MachineFunction &MF) const { - const MachineFrameInfo *MFI = MF.getFrameInfo(); - const WebAssemblyFrameLowering *TFI = getFrameLowering(MF); - const Function *F = MF.getFunction(); - unsigned StackAlign = TFI->getStackAlignment(); - bool requiresRealignment = - ((MFI->getMaxAlignment() > StackAlign) || - F->getAttributes().hasAttribute(AttributeSet::FunctionIndex, - Attribute::StackAlignment)); - - return requiresRealignment && canRealignStack(MF); -} Index: lib/Target/X86/X86FrameLowering.cpp =================================================================== --- lib/Target/X86/X86FrameLowering.cpp +++ lib/Target/X86/X86FrameLowering.cpp @@ -27,16 +27,12 @@ #include "llvm/IR/Function.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Support/Debug.h" #include using namespace llvm; -// FIXME: completely move here. -extern cl::opt ForceStackAlign; - X86FrameLowering::X86FrameLowering(const X86Subtarget &STI, unsigned StackAlignOverride) : TargetFrameLowering(StackGrowsDown, StackAlignOverride, Index: lib/Target/X86/X86RegisterInfo.h =================================================================== --- lib/Target/X86/X86RegisterInfo.h +++ lib/Target/X86/X86RegisterInfo.h @@ -108,9 +108,7 @@ bool hasBasePointer(const MachineFunction &MF) const; - bool canRealignStack(const MachineFunction &MF) const; - - bool needsStackRealignment(const MachineFunction &MF) const override; + bool canRealignStack(const MachineFunction &MF) const override; bool hasReservedSpillSlot(const MachineFunction &MF, unsigned Reg, int &FrameIdx) const override; Index: lib/Target/X86/X86RegisterInfo.cpp =================================================================== --- lib/Target/X86/X86RegisterInfo.cpp +++ lib/Target/X86/X86RegisterInfo.cpp @@ -44,12 +44,6 @@ #define GET_REGINFO_TARGET_DESC #include "X86GenRegisterInfo.inc" -cl::opt -ForceStackAlign("force-align-stack", - cl::desc("Force align the stack to the minimum alignment" - " needed for the function."), - cl::init(false), cl::Hidden); - static cl::opt EnableBasePointer("x86-use-base-pointer", cl::Hidden, cl::init(true), cl::desc("Enable use of a base pointer for complex stack frames")); @@ -457,7 +451,7 @@ } bool X86RegisterInfo::canRealignStack(const MachineFunction &MF) const { - if (MF.getFunction()->hasFnAttribute("no-realign-stack")) + if (!TargetRegisterInfo::canRealignStack(MF)) return false; const MachineFrameInfo *MFI = MF.getFrameInfo(); @@ -475,21 +469,6 @@ return true; } -bool X86RegisterInfo::needsStackRealignment(const MachineFunction &MF) const { - const MachineFrameInfo *MFI = MF.getFrameInfo(); - const X86FrameLowering *TFI = getFrameLowering(MF); - const Function *F = MF.getFunction(); - unsigned StackAlign = TFI->getStackAlignment(); - bool requiresRealignment = ((MFI->getMaxAlignment() > StackAlign) || - F->hasFnAttribute(Attribute::StackAlignment)); - - // If we've requested that we force align the stack do so now. - if (ForceStackAlign) - return canRealignStack(MF); - - return requiresRealignment && canRealignStack(MF); -} - bool X86RegisterInfo::hasReservedSpillSlot(const MachineFunction &MF, unsigned Reg, int &FrameIdx) const { // Since X86 defines assignCalleeSavedSpillSlots which always return true Index: test/CodeGen/Generic/ForceStackAlign.ll =================================================================== --- /dev/null +++ test/CodeGen/Generic/ForceStackAlign.ll @@ -0,0 +1,27 @@ +; Check that stack alignment can be forced. Individual targets should test their +; specific implementation details. + +; RUN: llc < %s -force-align-stack -stack-alignment=32 | FileCheck %s +; CHECK-LABEL: @f +; CHECK-LABEL: @g + +define i32 @f(i8* %p) nounwind { +entry: + %0 = load i8, i8* %p + %conv = sext i8 %0 to i32 + ret i32 %conv +} + +define i64 @g(i32 %i) nounwind { +entry: + br label %if.then + +if.then: + %0 = alloca i8, i32 %i + call void @llvm.memset.p0i8.i32(i8* %0, i8 0, i32 %i, i32 1, i1 false) + %call = call i32 @f(i8* %0) + %conv = sext i32 %call to i64 + ret i64 %conv +} + +declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i32, i1) nounwind Index: utils/TableGen/RegisterInfoEmitter.cpp =================================================================== --- utils/TableGen/RegisterInfoEmitter.cpp +++ utils/TableGen/RegisterInfoEmitter.cpp @@ -1074,9 +1074,7 @@ OS << "struct " << ClassName << " : public TargetRegisterInfo {\n" << " explicit " << ClassName - << "(unsigned RA, unsigned D = 0, unsigned E = 0, unsigned PC = 0);\n" - << " bool needsStackRealignment(const MachineFunction &) const override\n" - << " { return false; }\n"; + << "(unsigned RA, unsigned D = 0, unsigned E = 0, unsigned PC = 0);\n"; if (!RegBank.getSubRegIndices().empty()) { OS << " unsigned composeSubRegIndicesImpl" << "(unsigned, unsigned) const override;\n"