mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-12 05:56:28 +00:00
[Hexagon] Shrink-wrap stack frame (Hexagon-specific)
llvm-svn: 235603
This commit is contained in:
parent
7916d2dce4
commit
a9abedec24
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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;
|
||||
|
36
test/CodeGen/Hexagon/shrink-frame-basic.ll
Normal file
36
test/CodeGen/Hexagon/shrink-frame-basic.ll
Normal 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 }
|
||||
|
Loading…
Reference in New Issue
Block a user