mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-11 13:46:13 +00:00
Targets: commonize some stack realignment code
This patch does the following: * Fix FIXME on `needsStackRealignment`: it is now shared between multiple targets, implemented in `TargetRegisterInfo`, and isn't `virtual` anymore. This will break out-of-tree targets, silently if they used `virtual` and with a build error if they used `override`. * Factor out `canRealignStack` as a `virtual` function on `TargetRegisterInfo`, by default only looks for the `no-realign-stack` function attribute. Multiple targets duplicated the same `needsStackRealignment` code: - Aarch64. - ARM. - Mips almost: had extra `DEBUG` diagnostic, which the default implementation now has. - PowerPC. - WebAssembly. - x86 almost: has an extra `-force-align-stack` option, which the default implementation now has. The default implementation of `needsStackRealignment` used to just return `false`. My current patch changes the behavior by simply using the above shared behavior. This affects: - AMDGPU - BPF - CppBackend - MSP430 - NVPTX - Sparc - SystemZ - XCore - Out-of-tree targets This is a breaking change! `make check` passes. The only implementation of the `virtual` function (besides the slight different in x86) was Hexagon (which did `MF.getFrameInfo()->getMaxAlignment() > 8`), and potentially some out-of-tree targets. Hexagon now uses the default implementation. `needsStackRealignment` was being overwritten in `<Target>GenRegisterInfo.inc`, to return `false` as the default also did. That was odd and is now gone. Reviewers: sunfish Subscribers: aemerson, llvm-commits, jfb Differential Revision: http://reviews.llvm.org/D11160 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242727 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
dfc9688bd9
commit
9994b911f4
@ -21,6 +21,7 @@
|
|||||||
#include "llvm/CodeGen/MachineValueType.h"
|
#include "llvm/CodeGen/MachineValueType.h"
|
||||||
#include "llvm/IR/CallingConv.h"
|
#include "llvm/IR/CallingConv.h"
|
||||||
#include "llvm/MC/MCRegisterInfo.h"
|
#include "llvm/MC/MCRegisterInfo.h"
|
||||||
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
@ -34,6 +35,8 @@ class VirtRegMap;
|
|||||||
class raw_ostream;
|
class raw_ostream;
|
||||||
class LiveRegMatrix;
|
class LiveRegMatrix;
|
||||||
|
|
||||||
|
extern cl::opt<bool> ForceStackAlign;
|
||||||
|
|
||||||
class TargetRegisterClass {
|
class TargetRegisterClass {
|
||||||
public:
|
public:
|
||||||
typedef const MCPhysReg* iterator;
|
typedef const MCPhysReg* iterator;
|
||||||
@ -784,12 +787,14 @@ public:
|
|||||||
return false;
|
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
|
/// needsStackRealignment - true if storage within the function requires the
|
||||||
/// stack pointer to be aligned more than the normal calling convention calls
|
/// stack pointer to be aligned more than the normal calling convention calls
|
||||||
/// for.
|
/// for. This cannot be overriden by the target, but canRealignStack can be
|
||||||
virtual bool needsStackRealignment(const MachineFunction &MF) const {
|
/// overriden.
|
||||||
return false;
|
bool needsStackRealignment(const MachineFunction &MF) const;
|
||||||
}
|
|
||||||
|
|
||||||
/// getFrameIndexInstrOffset - Get the offset from the referenced frame
|
/// getFrameIndexInstrOffset - Get the offset from the referenced frame
|
||||||
/// index in the instruction, if there is one.
|
/// index in the instruction, if there is one.
|
||||||
|
@ -11,13 +11,26 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/Target/TargetRegisterInfo.h"
|
|
||||||
#include "llvm/ADT/BitVector.h"
|
#include "llvm/ADT/BitVector.h"
|
||||||
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
#include "llvm/CodeGen/VirtRegMap.h"
|
#include "llvm/CodeGen/VirtRegMap.h"
|
||||||
|
#include "llvm/IR/Function.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/raw_ostream.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<bool>
|
||||||
|
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;
|
using namespace llvm;
|
||||||
|
|
||||||
@ -296,6 +309,26 @@ TargetRegisterInfo::getRegAllocationHints(unsigned VirtReg,
|
|||||||
Hints.push_back(Phys);
|
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)
|
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||||
void
|
void
|
||||||
TargetRegisterInfo::dumpReg(unsigned Reg, unsigned SubRegIndex,
|
TargetRegisterInfo::dumpReg(unsigned Reg, unsigned SubRegIndex,
|
||||||
|
@ -186,29 +186,6 @@ bool AArch64RegisterInfo::hasBasePointer(const MachineFunction &MF) const {
|
|||||||
return false;
|
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
|
unsigned
|
||||||
AArch64RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
|
AArch64RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
|
||||||
const AArch64FrameLowering *TFI = getFrameLowering(MF);
|
const AArch64FrameLowering *TFI = getFrameLowering(MF);
|
||||||
|
@ -93,9 +93,6 @@ public:
|
|||||||
|
|
||||||
unsigned getRegPressureLimit(const TargetRegisterClass *RC,
|
unsigned getRegPressureLimit(const TargetRegisterClass *RC,
|
||||||
MachineFunction &MF) const override;
|
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
|
} // end namespace llvm
|
||||||
|
@ -339,7 +339,7 @@ bool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const {
|
|||||||
// 1. Dynamic stack realignment is explicitly disabled,
|
// 1. Dynamic stack realignment is explicitly disabled,
|
||||||
// 2. This is a Thumb1 function (it's not useful, so we don't bother), or
|
// 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.
|
// 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;
|
return false;
|
||||||
if (AFI->isThumb1OnlyFunction())
|
if (AFI->isThumb1OnlyFunction())
|
||||||
return false;
|
return false;
|
||||||
@ -356,18 +356,6 @@ bool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const {
|
|||||||
return MRI->canReserveReg(BasePtr);
|
return MRI->canReserveReg(BasePtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
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::
|
bool ARMBaseRegisterInfo::
|
||||||
cannotEliminateFrame(const MachineFunction &MF) const {
|
cannotEliminateFrame(const MachineFunction &MF) const {
|
||||||
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
|
@ -134,8 +134,7 @@ public:
|
|||||||
|
|
||||||
bool hasBasePointer(const MachineFunction &MF) const;
|
bool hasBasePointer(const MachineFunction &MF) const;
|
||||||
|
|
||||||
bool canRealignStack(const MachineFunction &MF) const;
|
bool canRealignStack(const MachineFunction &MF) const override;
|
||||||
bool needsStackRealignment(const MachineFunction &MF) const override;
|
|
||||||
int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
|
int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
|
||||||
int Idx) const override;
|
int Idx) const override;
|
||||||
bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
|
bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
|
||||||
|
@ -245,13 +245,6 @@ HexagonRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
HexagonRegisterInfo::needsStackRealignment(const MachineFunction &MF) const {
|
|
||||||
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
|
||||||
return MFI->getMaxAlignment() > 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned HexagonRegisterInfo::getFirstCallerSavedNonParamReg() const {
|
unsigned HexagonRegisterInfo::getFirstCallerSavedNonParamReg() const {
|
||||||
return Hexagon::R6;
|
return Hexagon::R6;
|
||||||
}
|
}
|
||||||
|
@ -63,8 +63,6 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool needsStackRealignment(const MachineFunction &MF) const override;
|
|
||||||
|
|
||||||
/// Returns true if the frame pointer is valid.
|
/// Returns true if the frame pointer is valid.
|
||||||
bool useFPForScavengingIndex(const MachineFunction &MF) const override;
|
bool useFPForScavengingIndex(const MachineFunction &MF) const override;
|
||||||
|
|
||||||
|
@ -284,6 +284,16 @@ getFrameRegister(const MachineFunction &MF) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool MipsRegisterInfo::canRealignStack(const MachineFunction &MF) const {
|
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<MipsSubtarget>();
|
const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
|
||||||
unsigned FP = Subtarget.isGP32bit() ? Mips::FP : Mips::FP_64;
|
unsigned FP = Subtarget.isGP32bit() ? Mips::FP : Mips::FP_64;
|
||||||
unsigned BP = Subtarget.isGP32bit() ? Mips::S7 : Mips::S7_64;
|
unsigned BP = Subtarget.isGP32bit() ? Mips::S7 : Mips::S7_64;
|
||||||
@ -306,42 +316,3 @@ bool MipsRegisterInfo::canRealignStack(const MachineFunction &MF) const {
|
|||||||
// sized objects.
|
// sized objects.
|
||||||
return MF.getRegInfo().canReserveReg(BP);
|
return MF.getRegInfo().canReserveReg(BP);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MipsRegisterInfo::needsStackRealignment(const MachineFunction &MF) const {
|
|
||||||
const MipsSubtarget &Subtarget = MF.getSubtarget<MipsSubtarget>();
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
@ -61,9 +61,7 @@ public:
|
|||||||
RegScavenger *RS = nullptr) const;
|
RegScavenger *RS = nullptr) const;
|
||||||
|
|
||||||
// Stack realignment queries.
|
// Stack realignment queries.
|
||||||
bool canRealignStack(const MachineFunction &MF) const;
|
bool canRealignStack(const MachineFunction &MF) const override;
|
||||||
|
|
||||||
bool needsStackRealignment(const MachineFunction &MF) const override;
|
|
||||||
|
|
||||||
/// Debug information queries.
|
/// Debug information queries.
|
||||||
unsigned getFrameRegister(const MachineFunction &MF) const override;
|
unsigned getFrameRegister(const MachineFunction &MF) const override;
|
||||||
|
@ -898,24 +898,6 @@ bool PPCRegisterInfo::hasBasePointer(const MachineFunction &MF) const {
|
|||||||
return needsStackRealignment(MF);
|
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
|
/// Returns true if the instruction's frame index
|
||||||
/// reference would be better served by a base register other than FP
|
/// reference would be better served by a base register other than FP
|
||||||
/// or SP. Used by LocalStackFrameAllocation to determine which frame index
|
/// or SP. Used by LocalStackFrameAllocation to determine which frame index
|
||||||
|
@ -136,8 +136,6 @@ public:
|
|||||||
// Base pointer (stack realignment) support.
|
// Base pointer (stack realignment) support.
|
||||||
unsigned getBaseRegister(const MachineFunction &MF) const;
|
unsigned getBaseRegister(const MachineFunction &MF) const;
|
||||||
bool hasBasePointer(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
|
} // end namespace llvm
|
||||||
|
@ -66,22 +66,3 @@ WebAssemblyRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
|
|||||||
const WebAssemblyFrameLowering *TFI = getFrameLowering(MF);
|
const WebAssemblyFrameLowering *TFI = getFrameLowering(MF);
|
||||||
return Regs[TFI->hasFP(MF)][TT.isArch64Bit()];
|
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);
|
|
||||||
}
|
|
||||||
|
@ -41,10 +41,6 @@ public:
|
|||||||
|
|
||||||
// Debug information queries.
|
// Debug information queries.
|
||||||
unsigned getFrameRegister(const MachineFunction &MF) const override;
|
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
|
} // end namespace llvm
|
||||||
|
@ -27,16 +27,12 @@
|
|||||||
#include "llvm/IR/Function.h"
|
#include "llvm/IR/Function.h"
|
||||||
#include "llvm/MC/MCAsmInfo.h"
|
#include "llvm/MC/MCAsmInfo.h"
|
||||||
#include "llvm/MC/MCSymbol.h"
|
#include "llvm/MC/MCSymbol.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
|
||||||
#include "llvm/Target/TargetOptions.h"
|
#include "llvm/Target/TargetOptions.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
// FIXME: completely move here.
|
|
||||||
extern cl::opt<bool> ForceStackAlign;
|
|
||||||
|
|
||||||
X86FrameLowering::X86FrameLowering(const X86Subtarget &STI,
|
X86FrameLowering::X86FrameLowering(const X86Subtarget &STI,
|
||||||
unsigned StackAlignOverride)
|
unsigned StackAlignOverride)
|
||||||
: TargetFrameLowering(StackGrowsDown, StackAlignOverride,
|
: TargetFrameLowering(StackGrowsDown, StackAlignOverride,
|
||||||
|
@ -44,12 +44,6 @@ using namespace llvm;
|
|||||||
#define GET_REGINFO_TARGET_DESC
|
#define GET_REGINFO_TARGET_DESC
|
||||||
#include "X86GenRegisterInfo.inc"
|
#include "X86GenRegisterInfo.inc"
|
||||||
|
|
||||||
cl::opt<bool>
|
|
||||||
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<bool>
|
static cl::opt<bool>
|
||||||
EnableBasePointer("x86-use-base-pointer", cl::Hidden, cl::init(true),
|
EnableBasePointer("x86-use-base-pointer", cl::Hidden, cl::init(true),
|
||||||
cl::desc("Enable use of a base pointer for complex stack frames"));
|
cl::desc("Enable use of a base pointer for complex stack frames"));
|
||||||
@ -457,7 +451,7 @@ bool X86RegisterInfo::hasBasePointer(const MachineFunction &MF) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool X86RegisterInfo::canRealignStack(const MachineFunction &MF) const {
|
bool X86RegisterInfo::canRealignStack(const MachineFunction &MF) const {
|
||||||
if (MF.getFunction()->hasFnAttribute("no-realign-stack"))
|
if (!TargetRegisterInfo::canRealignStack(MF))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
@ -475,21 +469,6 @@ bool X86RegisterInfo::canRealignStack(const MachineFunction &MF) const {
|
|||||||
return true;
|
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,
|
bool X86RegisterInfo::hasReservedSpillSlot(const MachineFunction &MF,
|
||||||
unsigned Reg, int &FrameIdx) const {
|
unsigned Reg, int &FrameIdx) const {
|
||||||
// Since X86 defines assignCalleeSavedSpillSlots which always return true
|
// Since X86 defines assignCalleeSavedSpillSlots which always return true
|
||||||
|
@ -108,9 +108,7 @@ public:
|
|||||||
|
|
||||||
bool hasBasePointer(const MachineFunction &MF) const;
|
bool hasBasePointer(const MachineFunction &MF) const;
|
||||||
|
|
||||||
bool canRealignStack(const MachineFunction &MF) const;
|
bool canRealignStack(const MachineFunction &MF) const override;
|
||||||
|
|
||||||
bool needsStackRealignment(const MachineFunction &MF) const override;
|
|
||||||
|
|
||||||
bool hasReservedSpillSlot(const MachineFunction &MF, unsigned Reg,
|
bool hasReservedSpillSlot(const MachineFunction &MF, unsigned Reg,
|
||||||
int &FrameIdx) const override;
|
int &FrameIdx) const override;
|
||||||
|
27
test/CodeGen/Generic/ForceStackAlign.ll
Normal file
27
test/CodeGen/Generic/ForceStackAlign.ll
Normal file
@ -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
|
@ -1074,9 +1074,7 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
|
|
||||||
OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"
|
OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"
|
||||||
<< " explicit " << ClassName
|
<< " explicit " << ClassName
|
||||||
<< "(unsigned RA, unsigned D = 0, unsigned E = 0, unsigned PC = 0);\n"
|
<< "(unsigned RA, unsigned D = 0, unsigned E = 0, unsigned PC = 0);\n";
|
||||||
<< " bool needsStackRealignment(const MachineFunction &) const override\n"
|
|
||||||
<< " { return false; }\n";
|
|
||||||
if (!RegBank.getSubRegIndices().empty()) {
|
if (!RegBank.getSubRegIndices().empty()) {
|
||||||
OS << " unsigned composeSubRegIndicesImpl"
|
OS << " unsigned composeSubRegIndicesImpl"
|
||||||
<< "(unsigned, unsigned) const override;\n"
|
<< "(unsigned, unsigned) const override;\n"
|
||||||
|
Loading…
Reference in New Issue
Block a user