[Hexagon] Shrink-wrap stack frame (Hexagon-specific)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235603 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Krzysztof Parzyszek 2015-04-23 16:05:39 +00:00
parent 69c69df308
commit de0d4bf1d4
4 changed files with 603 additions and 391 deletions

File diff suppressed because it is too large Load Diff

View File

@ -16,45 +16,42 @@
namespace llvm {
class HexagonInstrInfo;
class HexagonRegisterInfo;
class HexagonFrameLowering : public TargetFrameLowering {
private:
void expandAlloca(MachineInstr *AI, const HexagonInstrInfo &TII,
unsigned SP, unsigned CF) const;
public:
explicit HexagonFrameLowering()
: TargetFrameLowering(StackGrowsDown, 8, 0, 1, true) {}
// All of the prolog/epilog functionality, including saving and restoring
// callee-saved registers is handled in emitPrologue. This is to have the
// logic for shrink-wrapping in one place.
void emitPrologue(MachineFunction &MF) const override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const
override {}
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const override {
return true;
}
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const override {
return true;
}
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override;
void processFunctionBeforeFrameFinalized(MachineFunction &MF,
RegScavenger *RS = nullptr) const override;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const override;
bool targetHandlesStackFrameRounding() const override {
return true;
}
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const override;
void
eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
bool
restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const override;
void processFunctionBeforeFrameFinalized(MachineFunction &MF,
RegScavenger *RS = NULL) const override;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const override;
int getFrameIndexOffset(const MachineFunction &MF, int FI) const override;
bool hasFP(const MachineFunction &MF) const override;
bool hasTailCall(MachineBasicBlock &MBB) const;
void adjustForCalleeSavedRegsSpillCall(MachineFunction &MF) const;
bool replacePredRegPseudoSpillCode(MachineFunction &MF) const;
const SpillSlot *getCalleeSavedSpillSlots(unsigned &NumEntries)
const override {
@ -66,17 +63,39 @@ public:
{ Hexagon::R25, -36 }, { Hexagon::R24, -40 }, { Hexagon::D12, -40 },
{ Hexagon::R27, -44 }, { Hexagon::R26, -48 }, { Hexagon::D13, -48 }
};
NumEntries = array_lengthof(Offsets);
return Offsets;
}
bool assignCalleeSavedSpillSlots(MachineFunction &MF,
const TargetRegisterInfo *TRI,
std::vector<CalleeSavedInfo> &CSI) const override;
const TargetRegisterInfo *TRI, std::vector<CalleeSavedInfo> &CSI)
const override;
bool needsAligna(const MachineFunction &MF) const;
MachineInstr *getAlignaInstr(MachineFunction &MF) const;
private:
typedef std::vector<CalleeSavedInfo> CSIVect;
void expandAlloca(MachineInstr *AI, const HexagonInstrInfo &TII,
unsigned SP, unsigned CF) const;
void insertPrologueInBlock(MachineBasicBlock &MBB) const;
void insertEpilogueInBlock(MachineBasicBlock &MBB) const;
bool insertCSRSpillsInBlock(MachineBasicBlock &MBB, const CSIVect &CSI,
const HexagonRegisterInfo &HRI) const;
bool insertCSRRestoresInBlock(MachineBasicBlock &MBB, const CSIVect &CSI,
const HexagonRegisterInfo &HRI) const;
void adjustForCalleeSavedRegsSpillCall(MachineFunction &MF) const;
bool replacePredRegPseudoSpillCode(MachineFunction &MF) const;
bool replaceVecPredRegPseudoSpillCode(MachineFunction &MF) const;
void findShrunkPrologEpilog(MachineFunction &MF, MachineBasicBlock *&PrologB,
MachineBasicBlock *&EpilogB) const;
bool shouldInlineCSR(llvm::MachineFunction&, const CSIVect&) const;
bool useSpillFunction(MachineFunction &MF, const CSIVect &CSI) const;
bool useRestoreFunction(MachineFunction &MF, const CSIVect &CSI) const;
};
} // End llvm namespace

View File

@ -37,11 +37,13 @@
#define HEXAGON_RESERVED_REG_2 Hexagon::R11
namespace llvm {
struct HexagonRegisterInfo : public HexagonGenRegisterInfo {
class HexagonRegisterInfo : public HexagonGenRegisterInfo {
public:
HexagonRegisterInfo();
/// Code Generation virtual methods...
const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF)
const override;
BitVector getReservedRegs(const MachineFunction &MF) const override;
@ -76,7 +78,8 @@ struct HexagonRegisterInfo : public HexagonGenRegisterInfo {
unsigned getFrameRegister() const;
unsigned getStackRegister() const;
const uint16_t *getCallerSavedRegs(const MachineFunction *MF) const;
const MCPhysReg *getCallerSavedRegs(const MachineFunction *MF) const;
unsigned getFirstCallerSavedNonParamReg() const;
bool isEHReturnCalleeSaveReg(unsigned Reg) const;

View File

@ -0,0 +1,36 @@
; RUN: llc < %s | FileCheck %s
; Check for allocframe in a non-entry block LBB0_n.
; CHECK: LBB0_{{[0-9]+}}:
; CHECK: allocframe
; Deallocframe may be in a different block, but must follow.
; CHECK: deallocframe
target datalayout = "e-m:e-p:32:32-i1:32-i64:64-a:0-v32:32-n16:32"
target triple = "hexagon"
; Function Attrs: nounwind
define i32 @foo(i32 %n, i32* %p) #0 {
entry:
%cmp = icmp eq i32* %p, null
br i1 %cmp, label %if.end, label %if.then
if.then: ; preds = %entry
%0 = load i32, i32* %p, align 4
%inc = add nsw i32 %0, 1
store i32 %inc, i32* %p, align 4
br label %return
if.end: ; preds = %entry
%call = tail call i32 bitcast (i32 (...)* @bar to i32 (i32)*)(i32 %n) #0
%add = add nsw i32 %call, 1
br label %return
return: ; preds = %if.end, %if.then
%retval.0 = phi i32 [ %0, %if.then ], [ %add, %if.end ]
ret i32 %retval.0
}
declare i32 @bar(...) #0
attributes #0 = { nounwind }