1 //===-- MipsEmitGPRestore.cpp - Emit GP restore instruction----------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This pass emits instructions that restore $gp right
11 // after jalr instructions.
13 //===----------------------------------------------------------------------===//
15 #define DEBUG_TYPE "emit-gp-restore"
18 #include "MipsTargetMachine.h"
19 #include "MipsMachineFunction.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/Target/TargetInstrInfo.h"
23 #include "llvm/ADT/Statistic.h"
28 struct Inserter
: public MachineFunctionPass
{
31 const TargetInstrInfo
*TII
;
34 Inserter(TargetMachine
&tm
)
35 : MachineFunctionPass(ID
), TM(tm
), TII(tm
.getInstrInfo()) { }
37 virtual const char *getPassName() const {
38 return "Mips Emit GP Restore";
41 bool runOnMachineFunction(MachineFunction
&F
);
43 char Inserter::ID
= 0;
44 } // end of anonymous namespace
46 bool Inserter::runOnMachineFunction(MachineFunction
&F
) {
47 if (TM
.getRelocationModel() != Reloc::PIC_
)
51 int FI
= F
.getInfo
<MipsFunctionInfo
>()->getGPFI();
53 for (MachineFunction::iterator MFI
= F
.begin(), MFE
= F
.end();
55 MachineBasicBlock
& MBB
= *MFI
;
56 MachineBasicBlock::iterator I
= MFI
->begin();
58 // If MBB is a landing pad, insert instruction that restores $gp after
60 if (MBB
.isLandingPad()) {
61 // Find EH_LABEL first.
62 for (; I
->getOpcode() != TargetOpcode::EH_LABEL
; ++I
) ;
66 DebugLoc dl
= I
!= MBB
.end() ? I
->getDebugLoc() : DebugLoc();
67 BuildMI(MBB
, I
, dl
, TII
->get(Mips::LW
), Mips::GP
).addFrameIndex(FI
)
72 while (I
!= MFI
->end()) {
73 if (I
->getOpcode() != Mips::JALR
) {
78 DebugLoc dl
= I
->getDebugLoc();
79 // emit lw $gp, ($gp save slot on stack) after jalr
80 BuildMI(MBB
, ++I
, dl
, TII
->get(Mips::LW
), Mips::GP
).addFrameIndex(FI
)
89 /// createMipsEmitGPRestorePass - Returns a pass that emits instructions that
90 /// restores $gp clobbered by jalr instructions.
91 FunctionPass
*llvm::createMipsEmitGPRestorePass(MipsTargetMachine
&tm
) {
92 return new Inserter(tm
);