mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	[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:
		
										
											
												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; | ||||||
|   | |||||||
							
								
								
									
										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 } | ||||||
|  |  | ||||||
		Reference in New Issue
	
	Block a user