xref: /aosp_15_r20/external/llvm/lib/Target/Mips/MipsOptimizePICCall.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===--------- MipsOptimizePICCall.cpp - Optimize PIC Calls ---------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This pass eliminates unnecessary instructions that set up $gp and replace
11*9880d681SAndroid Build Coastguard Worker // instructions that load target function addresses with copy instructions.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #include "Mips.h"
16*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/MipsBaseInfo.h"
17*9880d681SAndroid Build Coastguard Worker #include "MipsMachineFunction.h"
18*9880d681SAndroid Build Coastguard Worker #include "MipsTargetMachine.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/ScopedHashTable.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineDominators.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
23*9880d681SAndroid Build Coastguard Worker 
24*9880d681SAndroid Build Coastguard Worker using namespace llvm;
25*9880d681SAndroid Build Coastguard Worker 
26*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "optimize-mips-pic-call"
27*9880d681SAndroid Build Coastguard Worker 
28*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> LoadTargetFromGOT("mips-load-target-from-got",
29*9880d681SAndroid Build Coastguard Worker                                        cl::init(true),
30*9880d681SAndroid Build Coastguard Worker                                        cl::desc("Load target address from GOT"),
31*9880d681SAndroid Build Coastguard Worker                                        cl::Hidden);
32*9880d681SAndroid Build Coastguard Worker 
33*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> EraseGPOpnd("mips-erase-gp-opnd",
34*9880d681SAndroid Build Coastguard Worker                                  cl::init(true), cl::desc("Erase GP Operand"),
35*9880d681SAndroid Build Coastguard Worker                                  cl::Hidden);
36*9880d681SAndroid Build Coastguard Worker 
37*9880d681SAndroid Build Coastguard Worker namespace {
38*9880d681SAndroid Build Coastguard Worker typedef PointerUnion<const Value *, const PseudoSourceValue *> ValueType;
39*9880d681SAndroid Build Coastguard Worker 
40*9880d681SAndroid Build Coastguard Worker typedef std::pair<unsigned, unsigned> CntRegP;
41*9880d681SAndroid Build Coastguard Worker typedef RecyclingAllocator<BumpPtrAllocator,
42*9880d681SAndroid Build Coastguard Worker                            ScopedHashTableVal<ValueType, CntRegP> >
43*9880d681SAndroid Build Coastguard Worker AllocatorTy;
44*9880d681SAndroid Build Coastguard Worker typedef ScopedHashTable<ValueType, CntRegP, DenseMapInfo<ValueType>,
45*9880d681SAndroid Build Coastguard Worker                         AllocatorTy> ScopedHTType;
46*9880d681SAndroid Build Coastguard Worker 
47*9880d681SAndroid Build Coastguard Worker class MBBInfo {
48*9880d681SAndroid Build Coastguard Worker public:
49*9880d681SAndroid Build Coastguard Worker   MBBInfo(MachineDomTreeNode *N);
50*9880d681SAndroid Build Coastguard Worker   const MachineDomTreeNode *getNode() const;
51*9880d681SAndroid Build Coastguard Worker   bool isVisited() const;
52*9880d681SAndroid Build Coastguard Worker   void preVisit(ScopedHTType &ScopedHT);
53*9880d681SAndroid Build Coastguard Worker   void postVisit();
54*9880d681SAndroid Build Coastguard Worker 
55*9880d681SAndroid Build Coastguard Worker private:
56*9880d681SAndroid Build Coastguard Worker   MachineDomTreeNode *Node;
57*9880d681SAndroid Build Coastguard Worker   ScopedHTType::ScopeTy *HTScope;
58*9880d681SAndroid Build Coastguard Worker };
59*9880d681SAndroid Build Coastguard Worker 
60*9880d681SAndroid Build Coastguard Worker class OptimizePICCall : public MachineFunctionPass {
61*9880d681SAndroid Build Coastguard Worker public:
OptimizePICCall(TargetMachine & tm)62*9880d681SAndroid Build Coastguard Worker   OptimizePICCall(TargetMachine &tm) : MachineFunctionPass(ID) {}
63*9880d681SAndroid Build Coastguard Worker 
getPassName() const64*9880d681SAndroid Build Coastguard Worker   const char *getPassName() const override { return "Mips OptimizePICCall"; }
65*9880d681SAndroid Build Coastguard Worker 
66*9880d681SAndroid Build Coastguard Worker   bool runOnMachineFunction(MachineFunction &F) override;
67*9880d681SAndroid Build Coastguard Worker 
getAnalysisUsage(AnalysisUsage & AU) const68*9880d681SAndroid Build Coastguard Worker   void getAnalysisUsage(AnalysisUsage &AU) const override {
69*9880d681SAndroid Build Coastguard Worker     AU.addRequired<MachineDominatorTree>();
70*9880d681SAndroid Build Coastguard Worker     MachineFunctionPass::getAnalysisUsage(AU);
71*9880d681SAndroid Build Coastguard Worker   }
72*9880d681SAndroid Build Coastguard Worker 
73*9880d681SAndroid Build Coastguard Worker private:
74*9880d681SAndroid Build Coastguard Worker   /// \brief Visit MBB.
75*9880d681SAndroid Build Coastguard Worker   bool visitNode(MBBInfo &MBBI);
76*9880d681SAndroid Build Coastguard Worker 
77*9880d681SAndroid Build Coastguard Worker   /// \brief Test if MI jumps to a function via a register.
78*9880d681SAndroid Build Coastguard Worker   ///
79*9880d681SAndroid Build Coastguard Worker   /// Also, return the virtual register containing the target function's address
80*9880d681SAndroid Build Coastguard Worker   /// and the underlying object in Reg and Val respectively, if the function's
81*9880d681SAndroid Build Coastguard Worker   /// address can be resolved lazily.
82*9880d681SAndroid Build Coastguard Worker   bool isCallViaRegister(MachineInstr &MI, unsigned &Reg,
83*9880d681SAndroid Build Coastguard Worker                          ValueType &Val) const;
84*9880d681SAndroid Build Coastguard Worker 
85*9880d681SAndroid Build Coastguard Worker   /// \brief Return the number of instructions that dominate the current
86*9880d681SAndroid Build Coastguard Worker   /// instruction and load the function address from object Entry.
87*9880d681SAndroid Build Coastguard Worker   unsigned getCount(ValueType Entry);
88*9880d681SAndroid Build Coastguard Worker 
89*9880d681SAndroid Build Coastguard Worker   /// \brief Return the destination virtual register of the last instruction
90*9880d681SAndroid Build Coastguard Worker   /// that loads from object Entry.
91*9880d681SAndroid Build Coastguard Worker   unsigned getReg(ValueType Entry);
92*9880d681SAndroid Build Coastguard Worker 
93*9880d681SAndroid Build Coastguard Worker   /// \brief Update ScopedHT.
94*9880d681SAndroid Build Coastguard Worker   void incCntAndSetReg(ValueType Entry, unsigned Reg);
95*9880d681SAndroid Build Coastguard Worker 
96*9880d681SAndroid Build Coastguard Worker   ScopedHTType ScopedHT;
97*9880d681SAndroid Build Coastguard Worker   static char ID;
98*9880d681SAndroid Build Coastguard Worker };
99*9880d681SAndroid Build Coastguard Worker 
100*9880d681SAndroid Build Coastguard Worker char OptimizePICCall::ID = 0;
101*9880d681SAndroid Build Coastguard Worker } // end of anonymous namespace
102*9880d681SAndroid Build Coastguard Worker 
103*9880d681SAndroid Build Coastguard Worker /// Return the first MachineOperand of MI if it is a used virtual register.
getCallTargetRegOpnd(MachineInstr & MI)104*9880d681SAndroid Build Coastguard Worker static MachineOperand *getCallTargetRegOpnd(MachineInstr &MI) {
105*9880d681SAndroid Build Coastguard Worker   if (MI.getNumOperands() == 0)
106*9880d681SAndroid Build Coastguard Worker     return nullptr;
107*9880d681SAndroid Build Coastguard Worker 
108*9880d681SAndroid Build Coastguard Worker   MachineOperand &MO = MI.getOperand(0);
109*9880d681SAndroid Build Coastguard Worker 
110*9880d681SAndroid Build Coastguard Worker   if (!MO.isReg() || !MO.isUse() ||
111*9880d681SAndroid Build Coastguard Worker       !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
112*9880d681SAndroid Build Coastguard Worker     return nullptr;
113*9880d681SAndroid Build Coastguard Worker 
114*9880d681SAndroid Build Coastguard Worker   return &MO;
115*9880d681SAndroid Build Coastguard Worker }
116*9880d681SAndroid Build Coastguard Worker 
117*9880d681SAndroid Build Coastguard Worker /// Return type of register Reg.
getRegTy(unsigned Reg,MachineFunction & MF)118*9880d681SAndroid Build Coastguard Worker static MVT::SimpleValueType getRegTy(unsigned Reg, MachineFunction &MF) {
119*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *RC = MF.getRegInfo().getRegClass(Reg);
120*9880d681SAndroid Build Coastguard Worker   assert(RC->vt_end() - RC->vt_begin() == 1);
121*9880d681SAndroid Build Coastguard Worker   return *RC->vt_begin();
122*9880d681SAndroid Build Coastguard Worker }
123*9880d681SAndroid Build Coastguard Worker 
124*9880d681SAndroid Build Coastguard Worker /// Do the following transformation:
125*9880d681SAndroid Build Coastguard Worker ///
126*9880d681SAndroid Build Coastguard Worker /// jalr $vreg
127*9880d681SAndroid Build Coastguard Worker /// =>
128*9880d681SAndroid Build Coastguard Worker /// copy $t9, $vreg
129*9880d681SAndroid Build Coastguard Worker /// jalr $t9
setCallTargetReg(MachineBasicBlock * MBB,MachineBasicBlock::iterator I)130*9880d681SAndroid Build Coastguard Worker static void setCallTargetReg(MachineBasicBlock *MBB,
131*9880d681SAndroid Build Coastguard Worker                              MachineBasicBlock::iterator I) {
132*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB->getParent();
133*9880d681SAndroid Build Coastguard Worker   const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
134*9880d681SAndroid Build Coastguard Worker   unsigned SrcReg = I->getOperand(0).getReg();
135*9880d681SAndroid Build Coastguard Worker   unsigned DstReg = getRegTy(SrcReg, MF) == MVT::i32 ? Mips::T9 : Mips::T9_64;
136*9880d681SAndroid Build Coastguard Worker   BuildMI(*MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), DstReg)
137*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg);
138*9880d681SAndroid Build Coastguard Worker   I->getOperand(0).setReg(DstReg);
139*9880d681SAndroid Build Coastguard Worker }
140*9880d681SAndroid Build Coastguard Worker 
141*9880d681SAndroid Build Coastguard Worker /// Search MI's operands for register GP and erase it.
eraseGPOpnd(MachineInstr & MI)142*9880d681SAndroid Build Coastguard Worker static void eraseGPOpnd(MachineInstr &MI) {
143*9880d681SAndroid Build Coastguard Worker   if (!EraseGPOpnd)
144*9880d681SAndroid Build Coastguard Worker     return;
145*9880d681SAndroid Build Coastguard Worker 
146*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MI.getParent()->getParent();
147*9880d681SAndroid Build Coastguard Worker   MVT::SimpleValueType Ty = getRegTy(MI.getOperand(0).getReg(), MF);
148*9880d681SAndroid Build Coastguard Worker   unsigned Reg = Ty == MVT::i32 ? Mips::GP : Mips::GP_64;
149*9880d681SAndroid Build Coastguard Worker 
150*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
151*9880d681SAndroid Build Coastguard Worker     MachineOperand &MO = MI.getOperand(I);
152*9880d681SAndroid Build Coastguard Worker     if (MO.isReg() && MO.getReg() == Reg) {
153*9880d681SAndroid Build Coastguard Worker       MI.RemoveOperand(I);
154*9880d681SAndroid Build Coastguard Worker       return;
155*9880d681SAndroid Build Coastguard Worker     }
156*9880d681SAndroid Build Coastguard Worker   }
157*9880d681SAndroid Build Coastguard Worker 
158*9880d681SAndroid Build Coastguard Worker   llvm_unreachable(nullptr);
159*9880d681SAndroid Build Coastguard Worker }
160*9880d681SAndroid Build Coastguard Worker 
MBBInfo(MachineDomTreeNode * N)161*9880d681SAndroid Build Coastguard Worker MBBInfo::MBBInfo(MachineDomTreeNode *N) : Node(N), HTScope(nullptr) {}
162*9880d681SAndroid Build Coastguard Worker 
getNode() const163*9880d681SAndroid Build Coastguard Worker const MachineDomTreeNode *MBBInfo::getNode() const { return Node; }
164*9880d681SAndroid Build Coastguard Worker 
isVisited() const165*9880d681SAndroid Build Coastguard Worker bool MBBInfo::isVisited() const { return HTScope; }
166*9880d681SAndroid Build Coastguard Worker 
preVisit(ScopedHTType & ScopedHT)167*9880d681SAndroid Build Coastguard Worker void MBBInfo::preVisit(ScopedHTType &ScopedHT) {
168*9880d681SAndroid Build Coastguard Worker   HTScope = new ScopedHTType::ScopeTy(ScopedHT);
169*9880d681SAndroid Build Coastguard Worker }
170*9880d681SAndroid Build Coastguard Worker 
postVisit()171*9880d681SAndroid Build Coastguard Worker void MBBInfo::postVisit() {
172*9880d681SAndroid Build Coastguard Worker   delete HTScope;
173*9880d681SAndroid Build Coastguard Worker }
174*9880d681SAndroid Build Coastguard Worker 
175*9880d681SAndroid Build Coastguard Worker // OptimizePICCall methods.
runOnMachineFunction(MachineFunction & F)176*9880d681SAndroid Build Coastguard Worker bool OptimizePICCall::runOnMachineFunction(MachineFunction &F) {
177*9880d681SAndroid Build Coastguard Worker   if (static_cast<const MipsSubtarget &>(F.getSubtarget()).inMips16Mode())
178*9880d681SAndroid Build Coastguard Worker     return false;
179*9880d681SAndroid Build Coastguard Worker 
180*9880d681SAndroid Build Coastguard Worker   // Do a pre-order traversal of the dominator tree.
181*9880d681SAndroid Build Coastguard Worker   MachineDominatorTree *MDT = &getAnalysis<MachineDominatorTree>();
182*9880d681SAndroid Build Coastguard Worker   bool Changed = false;
183*9880d681SAndroid Build Coastguard Worker 
184*9880d681SAndroid Build Coastguard Worker   SmallVector<MBBInfo, 8> WorkList(1, MBBInfo(MDT->getRootNode()));
185*9880d681SAndroid Build Coastguard Worker 
186*9880d681SAndroid Build Coastguard Worker   while (!WorkList.empty()) {
187*9880d681SAndroid Build Coastguard Worker     MBBInfo &MBBI = WorkList.back();
188*9880d681SAndroid Build Coastguard Worker 
189*9880d681SAndroid Build Coastguard Worker     // If this MBB has already been visited, destroy the scope for the MBB and
190*9880d681SAndroid Build Coastguard Worker     // pop it from the work list.
191*9880d681SAndroid Build Coastguard Worker     if (MBBI.isVisited()) {
192*9880d681SAndroid Build Coastguard Worker       MBBI.postVisit();
193*9880d681SAndroid Build Coastguard Worker       WorkList.pop_back();
194*9880d681SAndroid Build Coastguard Worker       continue;
195*9880d681SAndroid Build Coastguard Worker     }
196*9880d681SAndroid Build Coastguard Worker 
197*9880d681SAndroid Build Coastguard Worker     // Visit the MBB and add its children to the work list.
198*9880d681SAndroid Build Coastguard Worker     MBBI.preVisit(ScopedHT);
199*9880d681SAndroid Build Coastguard Worker     Changed |= visitNode(MBBI);
200*9880d681SAndroid Build Coastguard Worker     const MachineDomTreeNode *Node = MBBI.getNode();
201*9880d681SAndroid Build Coastguard Worker     const std::vector<MachineDomTreeNode *> &Children = Node->getChildren();
202*9880d681SAndroid Build Coastguard Worker     WorkList.append(Children.begin(), Children.end());
203*9880d681SAndroid Build Coastguard Worker   }
204*9880d681SAndroid Build Coastguard Worker 
205*9880d681SAndroid Build Coastguard Worker   return Changed;
206*9880d681SAndroid Build Coastguard Worker }
207*9880d681SAndroid Build Coastguard Worker 
visitNode(MBBInfo & MBBI)208*9880d681SAndroid Build Coastguard Worker bool OptimizePICCall::visitNode(MBBInfo &MBBI) {
209*9880d681SAndroid Build Coastguard Worker   bool Changed = false;
210*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *MBB = MBBI.getNode()->getBlock();
211*9880d681SAndroid Build Coastguard Worker 
212*9880d681SAndroid Build Coastguard Worker   for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;
213*9880d681SAndroid Build Coastguard Worker        ++I) {
214*9880d681SAndroid Build Coastguard Worker     unsigned Reg;
215*9880d681SAndroid Build Coastguard Worker     ValueType Entry;
216*9880d681SAndroid Build Coastguard Worker 
217*9880d681SAndroid Build Coastguard Worker     // Skip instructions that are not call instructions via registers.
218*9880d681SAndroid Build Coastguard Worker     if (!isCallViaRegister(*I, Reg, Entry))
219*9880d681SAndroid Build Coastguard Worker       continue;
220*9880d681SAndroid Build Coastguard Worker 
221*9880d681SAndroid Build Coastguard Worker     Changed = true;
222*9880d681SAndroid Build Coastguard Worker     unsigned N = getCount(Entry);
223*9880d681SAndroid Build Coastguard Worker 
224*9880d681SAndroid Build Coastguard Worker     if (N != 0) {
225*9880d681SAndroid Build Coastguard Worker       // If a function has been called more than twice, we do not have to emit a
226*9880d681SAndroid Build Coastguard Worker       // load instruction to get the function address from the GOT, but can
227*9880d681SAndroid Build Coastguard Worker       // instead reuse the address that has been loaded before.
228*9880d681SAndroid Build Coastguard Worker       if (N >= 2 && !LoadTargetFromGOT)
229*9880d681SAndroid Build Coastguard Worker         getCallTargetRegOpnd(*I)->setReg(getReg(Entry));
230*9880d681SAndroid Build Coastguard Worker 
231*9880d681SAndroid Build Coastguard Worker       // Erase the $gp operand if this isn't the first time a function has
232*9880d681SAndroid Build Coastguard Worker       // been called. $gp needs to be set up only if the function call can go
233*9880d681SAndroid Build Coastguard Worker       // through a lazy binding stub.
234*9880d681SAndroid Build Coastguard Worker       eraseGPOpnd(*I);
235*9880d681SAndroid Build Coastguard Worker     }
236*9880d681SAndroid Build Coastguard Worker 
237*9880d681SAndroid Build Coastguard Worker     if (Entry)
238*9880d681SAndroid Build Coastguard Worker       incCntAndSetReg(Entry, Reg);
239*9880d681SAndroid Build Coastguard Worker 
240*9880d681SAndroid Build Coastguard Worker     setCallTargetReg(MBB, I);
241*9880d681SAndroid Build Coastguard Worker   }
242*9880d681SAndroid Build Coastguard Worker 
243*9880d681SAndroid Build Coastguard Worker   return Changed;
244*9880d681SAndroid Build Coastguard Worker }
245*9880d681SAndroid Build Coastguard Worker 
isCallViaRegister(MachineInstr & MI,unsigned & Reg,ValueType & Val) const246*9880d681SAndroid Build Coastguard Worker bool OptimizePICCall::isCallViaRegister(MachineInstr &MI, unsigned &Reg,
247*9880d681SAndroid Build Coastguard Worker                                         ValueType &Val) const {
248*9880d681SAndroid Build Coastguard Worker   if (!MI.isCall())
249*9880d681SAndroid Build Coastguard Worker     return false;
250*9880d681SAndroid Build Coastguard Worker 
251*9880d681SAndroid Build Coastguard Worker   MachineOperand *MO = getCallTargetRegOpnd(MI);
252*9880d681SAndroid Build Coastguard Worker 
253*9880d681SAndroid Build Coastguard Worker   // Return if MI is not a function call via a register.
254*9880d681SAndroid Build Coastguard Worker   if (!MO)
255*9880d681SAndroid Build Coastguard Worker     return false;
256*9880d681SAndroid Build Coastguard Worker 
257*9880d681SAndroid Build Coastguard Worker   // Get the instruction that loads the function address from the GOT.
258*9880d681SAndroid Build Coastguard Worker   Reg = MO->getReg();
259*9880d681SAndroid Build Coastguard Worker   Val = (Value*)nullptr;
260*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
261*9880d681SAndroid Build Coastguard Worker   MachineInstr *DefMI = MRI.getVRegDef(Reg);
262*9880d681SAndroid Build Coastguard Worker 
263*9880d681SAndroid Build Coastguard Worker   assert(DefMI);
264*9880d681SAndroid Build Coastguard Worker 
265*9880d681SAndroid Build Coastguard Worker   // See if DefMI is an instruction that loads from a GOT entry that holds the
266*9880d681SAndroid Build Coastguard Worker   // address of a lazy binding stub.
267*9880d681SAndroid Build Coastguard Worker   if (!DefMI->mayLoad() || DefMI->getNumOperands() < 3)
268*9880d681SAndroid Build Coastguard Worker     return true;
269*9880d681SAndroid Build Coastguard Worker 
270*9880d681SAndroid Build Coastguard Worker   unsigned Flags = DefMI->getOperand(2).getTargetFlags();
271*9880d681SAndroid Build Coastguard Worker 
272*9880d681SAndroid Build Coastguard Worker   if (Flags != MipsII::MO_GOT_CALL && Flags != MipsII::MO_CALL_LO16)
273*9880d681SAndroid Build Coastguard Worker     return true;
274*9880d681SAndroid Build Coastguard Worker 
275*9880d681SAndroid Build Coastguard Worker   // Return the underlying object for the GOT entry in Val.
276*9880d681SAndroid Build Coastguard Worker   assert(DefMI->hasOneMemOperand());
277*9880d681SAndroid Build Coastguard Worker   Val = (*DefMI->memoperands_begin())->getValue();
278*9880d681SAndroid Build Coastguard Worker   if (!Val)
279*9880d681SAndroid Build Coastguard Worker     Val = (*DefMI->memoperands_begin())->getPseudoValue();
280*9880d681SAndroid Build Coastguard Worker   return true;
281*9880d681SAndroid Build Coastguard Worker }
282*9880d681SAndroid Build Coastguard Worker 
getCount(ValueType Entry)283*9880d681SAndroid Build Coastguard Worker unsigned OptimizePICCall::getCount(ValueType Entry) {
284*9880d681SAndroid Build Coastguard Worker   return ScopedHT.lookup(Entry).first;
285*9880d681SAndroid Build Coastguard Worker }
286*9880d681SAndroid Build Coastguard Worker 
getReg(ValueType Entry)287*9880d681SAndroid Build Coastguard Worker unsigned OptimizePICCall::getReg(ValueType Entry) {
288*9880d681SAndroid Build Coastguard Worker   unsigned Reg = ScopedHT.lookup(Entry).second;
289*9880d681SAndroid Build Coastguard Worker   assert(Reg);
290*9880d681SAndroid Build Coastguard Worker   return Reg;
291*9880d681SAndroid Build Coastguard Worker }
292*9880d681SAndroid Build Coastguard Worker 
incCntAndSetReg(ValueType Entry,unsigned Reg)293*9880d681SAndroid Build Coastguard Worker void OptimizePICCall::incCntAndSetReg(ValueType Entry, unsigned Reg) {
294*9880d681SAndroid Build Coastguard Worker   CntRegP P = ScopedHT.lookup(Entry);
295*9880d681SAndroid Build Coastguard Worker   ScopedHT.insert(Entry, std::make_pair(P.first + 1, Reg));
296*9880d681SAndroid Build Coastguard Worker }
297*9880d681SAndroid Build Coastguard Worker 
298*9880d681SAndroid Build Coastguard Worker /// Return an OptimizeCall object.
createMipsOptimizePICCallPass(MipsTargetMachine & TM)299*9880d681SAndroid Build Coastguard Worker FunctionPass *llvm::createMipsOptimizePICCallPass(MipsTargetMachine &TM) {
300*9880d681SAndroid Build Coastguard Worker   return new OptimizePICCall(TM);
301*9880d681SAndroid Build Coastguard Worker }
302