Home | History | Annotate | Download | only in Mips
      1 //===-- MipsEmitGPRestore.cpp - Emit GP restore instruction----------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This pass emits instructions that restore $gp right
     11 // after jalr instructions.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #define DEBUG_TYPE "emit-gp-restore"
     16 
     17 #include "Mips.h"
     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"
     24 
     25 using namespace llvm;
     26 
     27 namespace {
     28   struct Inserter : public MachineFunctionPass {
     29 
     30     TargetMachine &TM;
     31     const TargetInstrInfo *TII;
     32 
     33     static char ID;
     34     Inserter(TargetMachine &tm)
     35       : MachineFunctionPass(ID), TM(tm), TII(tm.getInstrInfo()) { }
     36 
     37     virtual const char *getPassName() const {
     38       return "Mips Emit GP Restore";
     39     }
     40 
     41     bool runOnMachineFunction(MachineFunction &F);
     42   };
     43   char Inserter::ID = 0;
     44 } // end of anonymous namespace
     45 
     46 bool Inserter::runOnMachineFunction(MachineFunction &F) {
     47   if (TM.getRelocationModel() != Reloc::PIC_)
     48     return false;
     49 
     50   bool Changed = false;
     51   int FI =  F.getInfo<MipsFunctionInfo>()->getGPFI();
     52 
     53   for (MachineFunction::iterator MFI = F.begin(), MFE = F.end();
     54        MFI != MFE; ++MFI) {
     55     MachineBasicBlock& MBB = *MFI;
     56     MachineBasicBlock::iterator I = MFI->begin();
     57 
     58     // If MBB is a landing pad, insert instruction that restores $gp after
     59     // EH_LABEL.
     60     if (MBB.isLandingPad()) {
     61       // Find EH_LABEL first.
     62       for (; I->getOpcode() != TargetOpcode::EH_LABEL; ++I) ;
     63 
     64       // Insert lw.
     65       ++I;
     66       DebugLoc dl = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
     67       BuildMI(MBB, I, dl, TII->get(Mips::LW), Mips::GP).addFrameIndex(FI)
     68                                                        .addImm(0);
     69       Changed = true;
     70     }
     71 
     72     while (I != MFI->end()) {
     73       if (I->getOpcode() != Mips::JALR) {
     74         ++I;
     75         continue;
     76       }
     77 
     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)
     81                                                          .addImm(0);
     82       Changed = true;
     83     }
     84   }
     85 
     86   return Changed;
     87 }
     88 
     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);
     93 }
     94 
     95