LLVM API Documentation

MipsOptimizePICCall.cpp
Go to the documentation of this file.
00001 //===--------- MipsOptimizePICCall.cpp - Optimize PIC Calls ---------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This pass eliminates unnecessary instructions that set up $gp and replace
00011 // instructions that load target function addresses with copy instructions.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "Mips.h"
00016 #include "MCTargetDesc/MipsBaseInfo.h"
00017 #include "MipsMachineFunction.h"
00018 #include "MipsTargetMachine.h"
00019 #include "llvm/ADT/ScopedHashTable.h"
00020 #include "llvm/CodeGen/MachineDominators.h"
00021 #include "llvm/CodeGen/MachineRegisterInfo.h"
00022 #include "llvm/Support/CommandLine.h"
00023 
00024 using namespace llvm;
00025 
00026 #define DEBUG_TYPE "optimize-mips-pic-call"
00027 
00028 static cl::opt<bool> LoadTargetFromGOT("mips-load-target-from-got",
00029                                        cl::init(true),
00030                                        cl::desc("Load target address from GOT"),
00031                                        cl::Hidden);
00032 
00033 static cl::opt<bool> EraseGPOpnd("mips-erase-gp-opnd",
00034                                  cl::init(true), cl::desc("Erase GP Operand"),
00035                                  cl::Hidden);
00036 
00037 namespace {
00038 typedef PointerUnion<const Value *, const PseudoSourceValue *> ValueType;
00039 
00040 typedef std::pair<unsigned, unsigned> CntRegP;
00041 typedef RecyclingAllocator<BumpPtrAllocator,
00042                            ScopedHashTableVal<ValueType, CntRegP> >
00043 AllocatorTy;
00044 typedef ScopedHashTable<ValueType, CntRegP, DenseMapInfo<ValueType>,
00045                         AllocatorTy> ScopedHTType;
00046 
00047 class MBBInfo {
00048 public:
00049   MBBInfo(MachineDomTreeNode *N);
00050   const MachineDomTreeNode *getNode() const;
00051   bool isVisited() const;
00052   void preVisit(ScopedHTType &ScopedHT);
00053   void postVisit();
00054 
00055 private:
00056   MachineDomTreeNode *Node;
00057   ScopedHTType::ScopeTy *HTScope;
00058 };
00059 
00060 class OptimizePICCall : public MachineFunctionPass {
00061 public:
00062   OptimizePICCall(TargetMachine &tm) : MachineFunctionPass(ID) {}
00063 
00064   const char *getPassName() const override { return "Mips OptimizePICCall"; }
00065 
00066   bool runOnMachineFunction(MachineFunction &F) override;
00067 
00068   void getAnalysisUsage(AnalysisUsage &AU) const override {
00069     AU.addRequired<MachineDominatorTree>();
00070     MachineFunctionPass::getAnalysisUsage(AU);
00071   }
00072 
00073 private:
00074   /// \brief Visit MBB.
00075   bool visitNode(MBBInfo &MBBI);
00076 
00077   /// \brief Test if MI jumps to a function via a register.
00078   ///
00079   /// Also, return the virtual register containing the target function's address
00080   /// and the underlying object in Reg and Val respectively, if the function's
00081   /// address can be resolved lazily.
00082   bool isCallViaRegister(MachineInstr &MI, unsigned &Reg,
00083                          ValueType &Val) const;
00084 
00085   /// \brief Return the number of instructions that dominate the current
00086   /// instruction and load the function address from object Entry.
00087   unsigned getCount(ValueType Entry);
00088 
00089   /// \brief Return the destination virtual register of the last instruction
00090   /// that loads from object Entry.
00091   unsigned getReg(ValueType Entry);
00092 
00093   /// \brief Update ScopedHT.
00094   void incCntAndSetReg(ValueType Entry, unsigned Reg);
00095 
00096   ScopedHTType ScopedHT;
00097   static char ID;
00098 };
00099 
00100 char OptimizePICCall::ID = 0;
00101 } // end of anonymous namespace
00102 
00103 /// Return the first MachineOperand of MI if it is a used virtual register.
00104 static MachineOperand *getCallTargetRegOpnd(MachineInstr &MI) {
00105   if (MI.getNumOperands() == 0)
00106     return nullptr;
00107 
00108   MachineOperand &MO = MI.getOperand(0);
00109 
00110   if (!MO.isReg() || !MO.isUse() ||
00111       !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
00112     return nullptr;
00113 
00114   return &MO;
00115 }
00116 
00117 /// Return type of register Reg.
00118 static MVT::SimpleValueType getRegTy(unsigned Reg, MachineFunction &MF) {
00119   const TargetRegisterClass *RC = MF.getRegInfo().getRegClass(Reg);
00120   assert(RC->vt_end() - RC->vt_begin() == 1);
00121   return *RC->vt_begin();
00122 }
00123 
00124 /// Do the following transformation:
00125 ///
00126 /// jalr $vreg
00127 /// =>
00128 /// copy $t9, $vreg
00129 /// jalr $t9
00130 static void setCallTargetReg(MachineBasicBlock *MBB,
00131                              MachineBasicBlock::iterator I) {
00132   MachineFunction &MF = *MBB->getParent();
00133   const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
00134   unsigned SrcReg = I->getOperand(0).getReg();
00135   unsigned DstReg = getRegTy(SrcReg, MF) == MVT::i32 ? Mips::T9 : Mips::T9_64;
00136   BuildMI(*MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), DstReg)
00137       .addReg(SrcReg);
00138   I->getOperand(0).setReg(DstReg);
00139 }
00140 
00141 /// Search MI's operands for register GP and erase it.
00142 static void eraseGPOpnd(MachineInstr &MI) {
00143   if (!EraseGPOpnd)
00144     return;
00145 
00146   MachineFunction &MF = *MI.getParent()->getParent();
00147   MVT::SimpleValueType Ty = getRegTy(MI.getOperand(0).getReg(), MF);
00148   unsigned Reg = Ty == MVT::i32 ? Mips::GP : Mips::GP_64;
00149 
00150   for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
00151     MachineOperand &MO = MI.getOperand(I);
00152     if (MO.isReg() && MO.getReg() == Reg) {
00153       MI.RemoveOperand(I);
00154       return;
00155     }
00156   }
00157 
00158   llvm_unreachable(nullptr);
00159 }
00160 
00161 MBBInfo::MBBInfo(MachineDomTreeNode *N) : Node(N), HTScope(nullptr) {}
00162 
00163 const MachineDomTreeNode *MBBInfo::getNode() const { return Node; }
00164 
00165 bool MBBInfo::isVisited() const { return HTScope; }
00166 
00167 void MBBInfo::preVisit(ScopedHTType &ScopedHT) {
00168   HTScope = new ScopedHTType::ScopeTy(ScopedHT);
00169 }
00170 
00171 void MBBInfo::postVisit() {
00172   delete HTScope;
00173 }
00174 
00175 // OptimizePICCall methods.
00176 bool OptimizePICCall::runOnMachineFunction(MachineFunction &F) {
00177   if (F.getTarget().getSubtarget<MipsSubtarget>().inMips16Mode())
00178     return false;
00179 
00180   // Do a pre-order traversal of the dominator tree.
00181   MachineDominatorTree *MDT = &getAnalysis<MachineDominatorTree>();
00182   bool Changed = false;
00183 
00184   SmallVector<MBBInfo, 8> WorkList(1, MBBInfo(MDT->getRootNode()));
00185 
00186   while (!WorkList.empty()) {
00187     MBBInfo &MBBI = WorkList.back();
00188 
00189     // If this MBB has already been visited, destroy the scope for the MBB and
00190     // pop it from the work list.
00191     if (MBBI.isVisited()) {
00192       MBBI.postVisit();
00193       WorkList.pop_back();
00194       continue;
00195     }
00196 
00197     // Visit the MBB and add its children to the work list.
00198     MBBI.preVisit(ScopedHT);
00199     Changed |= visitNode(MBBI);
00200     const MachineDomTreeNode *Node = MBBI.getNode();
00201     const std::vector<MachineDomTreeNode *> &Children = Node->getChildren();
00202     WorkList.append(Children.begin(), Children.end());
00203   }
00204 
00205   return Changed;
00206 }
00207 
00208 bool OptimizePICCall::visitNode(MBBInfo &MBBI) {
00209   bool Changed = false;
00210   MachineBasicBlock *MBB = MBBI.getNode()->getBlock();
00211 
00212   for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;
00213        ++I) {
00214     unsigned Reg;
00215     ValueType Entry;
00216 
00217     // Skip instructions that are not call instructions via registers.
00218     if (!isCallViaRegister(*I, Reg, Entry))
00219       continue;
00220 
00221     Changed = true;
00222     unsigned N = getCount(Entry);
00223 
00224     if (N != 0) {
00225       // If a function has been called more than twice, we do not have to emit a
00226       // load instruction to get the function address from the GOT, but can
00227       // instead reuse the address that has been loaded before.
00228       if (N >= 2 && !LoadTargetFromGOT)
00229         getCallTargetRegOpnd(*I)->setReg(getReg(Entry));
00230 
00231       // Erase the $gp operand if this isn't the first time a function has
00232       // been called. $gp needs to be set up only if the function call can go
00233       // through a lazy binding stub.
00234       eraseGPOpnd(*I);
00235     }
00236 
00237     if (Entry)
00238       incCntAndSetReg(Entry, Reg);
00239 
00240     setCallTargetReg(MBB, I);
00241   }
00242 
00243   return Changed;
00244 }
00245 
00246 bool OptimizePICCall::isCallViaRegister(MachineInstr &MI, unsigned &Reg,
00247                                         ValueType &Val) const {
00248   if (!MI.isCall())
00249     return false;
00250 
00251   MachineOperand *MO = getCallTargetRegOpnd(MI);
00252 
00253   // Return if MI is not a function call via a register.
00254   if (!MO)
00255     return false;
00256 
00257   // Get the instruction that loads the function address from the GOT.
00258   Reg = MO->getReg();
00259   Val = (Value*)nullptr;
00260   MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
00261   MachineInstr *DefMI = MRI.getVRegDef(Reg);
00262 
00263   assert(DefMI);
00264 
00265   // See if DefMI is an instruction that loads from a GOT entry that holds the
00266   // address of a lazy binding stub.
00267   if (!DefMI->mayLoad() || DefMI->getNumOperands() < 3)
00268     return true;
00269 
00270   unsigned Flags = DefMI->getOperand(2).getTargetFlags();
00271 
00272   if (Flags != MipsII::MO_GOT_CALL && Flags != MipsII::MO_CALL_LO16)
00273     return true;
00274 
00275   // Return the underlying object for the GOT entry in Val.
00276   assert(DefMI->hasOneMemOperand());
00277   Val = (*DefMI->memoperands_begin())->getValue();
00278   if (!Val)
00279     Val = (*DefMI->memoperands_begin())->getPseudoValue();
00280   return true;
00281 }
00282 
00283 unsigned OptimizePICCall::getCount(ValueType Entry) {
00284   return ScopedHT.lookup(Entry).first;
00285 }
00286 
00287 unsigned OptimizePICCall::getReg(ValueType Entry) {
00288   unsigned Reg = ScopedHT.lookup(Entry).second;
00289   assert(Reg);
00290   return Reg;
00291 }
00292 
00293 void OptimizePICCall::incCntAndSetReg(ValueType Entry, unsigned Reg) {
00294   CntRegP P = ScopedHT.lookup(Entry);
00295   ScopedHT.insert(Entry, std::make_pair(P.first + 1, Reg));
00296 }
00297 
00298 /// Return an OptimizeCall object.
00299 FunctionPass *llvm::createMipsOptimizePICCallPass(MipsTargetMachine &TM) {
00300   return new OptimizePICCall(TM);
00301 }