forked from OSchip/llvm-project
[Hexagon] Shrink-wrap stack frame (Hexagon-specific)
llvm-svn: 235603
This commit is contained in:
parent
a17cebd219
commit
876a19d855
File diff suppressed because it is too large
Load Diff
|
@ -16,45 +16,42 @@
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class HexagonInstrInfo;
|
class HexagonInstrInfo;
|
||||||
|
class HexagonRegisterInfo;
|
||||||
|
|
||||||
class HexagonFrameLowering : public TargetFrameLowering {
|
class HexagonFrameLowering : public TargetFrameLowering {
|
||||||
private:
|
|
||||||
void expandAlloca(MachineInstr *AI, const HexagonInstrInfo &TII,
|
|
||||||
unsigned SP, unsigned CF) const;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit HexagonFrameLowering()
|
explicit HexagonFrameLowering()
|
||||||
: TargetFrameLowering(StackGrowsDown, 8, 0, 1, true) {}
|
: 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 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 {
|
bool targetHandlesStackFrameRounding() const override {
|
||||||
return true;
|
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;
|
int getFrameIndexOffset(const MachineFunction &MF, int FI) const override;
|
||||||
bool hasFP(const MachineFunction &MF) 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 SpillSlot *getCalleeSavedSpillSlots(unsigned &NumEntries)
|
||||||
const override {
|
const override {
|
||||||
|
@ -66,17 +63,39 @@ public:
|
||||||
{ Hexagon::R25, -36 }, { Hexagon::R24, -40 }, { Hexagon::D12, -40 },
|
{ Hexagon::R25, -36 }, { Hexagon::R24, -40 }, { Hexagon::D12, -40 },
|
||||||
{ Hexagon::R27, -44 }, { Hexagon::R26, -48 }, { Hexagon::D13, -48 }
|
{ Hexagon::R27, -44 }, { Hexagon::R26, -48 }, { Hexagon::D13, -48 }
|
||||||
};
|
};
|
||||||
|
|
||||||
NumEntries = array_lengthof(Offsets);
|
NumEntries = array_lengthof(Offsets);
|
||||||
return Offsets;
|
return Offsets;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool assignCalleeSavedSpillSlots(MachineFunction &MF,
|
bool assignCalleeSavedSpillSlots(MachineFunction &MF,
|
||||||
const TargetRegisterInfo *TRI,
|
const TargetRegisterInfo *TRI, std::vector<CalleeSavedInfo> &CSI)
|
||||||
std::vector<CalleeSavedInfo> &CSI) const override;
|
const override;
|
||||||
|
|
||||||
bool needsAligna(const MachineFunction &MF) const;
|
bool needsAligna(const MachineFunction &MF) const;
|
||||||
MachineInstr *getAlignaInstr(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
|
} // End llvm namespace
|
||||||
|
|
|
@ -37,11 +37,13 @@
|
||||||
#define HEXAGON_RESERVED_REG_2 Hexagon::R11
|
#define HEXAGON_RESERVED_REG_2 Hexagon::R11
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
struct HexagonRegisterInfo : public HexagonGenRegisterInfo {
|
class HexagonRegisterInfo : public HexagonGenRegisterInfo {
|
||||||
|
public:
|
||||||
HexagonRegisterInfo();
|
HexagonRegisterInfo();
|
||||||
|
|
||||||
/// Code Generation virtual methods...
|
/// 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;
|
BitVector getReservedRegs(const MachineFunction &MF) const override;
|
||||||
|
@ -76,7 +78,8 @@ struct HexagonRegisterInfo : public HexagonGenRegisterInfo {
|
||||||
unsigned getFrameRegister() const;
|
unsigned getFrameRegister() const;
|
||||||
unsigned getStackRegister() const;
|
unsigned getStackRegister() const;
|
||||||
|
|
||||||
const uint16_t *getCallerSavedRegs(const MachineFunction *MF) const;
|
const MCPhysReg *getCallerSavedRegs(const MachineFunction *MF) const;
|
||||||
|
|
||||||
unsigned getFirstCallerSavedNonParamReg() const;
|
unsigned getFirstCallerSavedNonParamReg() const;
|
||||||
|
|
||||||
bool isEHReturnCalleeSaveReg(unsigned Reg) const;
|
bool isEHReturnCalleeSaveReg(unsigned Reg) const;
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
Loading…
Reference in New Issue