comparison lib/Target/Mips/MipsOptimizePICCall.cpp @ 77:54457678186b LLVM3.6

LLVM 3.6
author Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
date Mon, 08 Sep 2014 22:06:00 +0900
parents e4204d083e25
children 60c9769439b8
comparison
equal deleted inserted replaced
34:e874dbf0ad9d 77:54457678186b
10 // This pass eliminates unnecessary instructions that set up $gp and replace 10 // This pass eliminates unnecessary instructions that set up $gp and replace
11 // instructions that load target function addresses with copy instructions. 11 // instructions that load target function addresses with copy instructions.
12 // 12 //
13 //===----------------------------------------------------------------------===// 13 //===----------------------------------------------------------------------===//
14 14
15 #define DEBUG_TYPE "optimize-mips-pic-call"
16
17 #include "Mips.h" 15 #include "Mips.h"
16 #include "MCTargetDesc/MipsBaseInfo.h"
17 #include "MipsMachineFunction.h"
18 #include "MipsTargetMachine.h" 18 #include "MipsTargetMachine.h"
19 #include "MipsMachineFunction.h"
20 #include "MCTargetDesc/MipsBaseInfo.h"
21 #include "llvm/ADT/ScopedHashTable.h" 19 #include "llvm/ADT/ScopedHashTable.h"
22 #include "llvm/CodeGen/MachineDominators.h" 20 #include "llvm/CodeGen/MachineDominators.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h" 21 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 #include "llvm/Support/CommandLine.h" 22 #include "llvm/Support/CommandLine.h"
25 23
26 using namespace llvm; 24 using namespace llvm;
27 25
26 #define DEBUG_TYPE "optimize-mips-pic-call"
27
28 static cl::opt<bool> LoadTargetFromGOT("mips-load-target-from-got", 28 static cl::opt<bool> LoadTargetFromGOT("mips-load-target-from-got",
29 cl::init(true), 29 cl::init(true),
30 cl::desc("Load target address from GOT"), 30 cl::desc("Load target address from GOT"),
31 cl::Hidden); 31 cl::Hidden);
32 32
33 static cl::opt<bool> EraseGPOpnd("mips-erase-gp-opnd", 33 static cl::opt<bool> EraseGPOpnd("mips-erase-gp-opnd",
34 cl::init(true), cl::desc("Erase GP Operand"), 34 cl::init(true), cl::desc("Erase GP Operand"),
35 cl::Hidden); 35 cl::Hidden);
36 36
37 namespace { 37 namespace {
38 typedef PointerUnion<const Value *, const PseudoSourceValue *> ValueType;
39
38 typedef std::pair<unsigned, unsigned> CntRegP; 40 typedef std::pair<unsigned, unsigned> CntRegP;
39 typedef RecyclingAllocator<BumpPtrAllocator, 41 typedef RecyclingAllocator<BumpPtrAllocator,
40 ScopedHashTableVal<const Value *, CntRegP> > 42 ScopedHashTableVal<ValueType, CntRegP> >
41 AllocatorTy; 43 AllocatorTy;
42 typedef ScopedHashTable<const Value *, CntRegP, DenseMapInfo<const Value *>, 44 typedef ScopedHashTable<ValueType, CntRegP, DenseMapInfo<ValueType>,
43 AllocatorTy> ScopedHTType; 45 AllocatorTy> ScopedHTType;
44 46
45 class MBBInfo { 47 class MBBInfo {
46 public: 48 public:
47 MBBInfo(MachineDomTreeNode *N); 49 MBBInfo(MachineDomTreeNode *N);
57 59
58 class OptimizePICCall : public MachineFunctionPass { 60 class OptimizePICCall : public MachineFunctionPass {
59 public: 61 public:
60 OptimizePICCall(TargetMachine &tm) : MachineFunctionPass(ID) {} 62 OptimizePICCall(TargetMachine &tm) : MachineFunctionPass(ID) {}
61 63
62 virtual const char *getPassName() const { return "Mips OptimizePICCall"; } 64 const char *getPassName() const override { return "Mips OptimizePICCall"; }
63 65
64 bool runOnMachineFunction(MachineFunction &F); 66 bool runOnMachineFunction(MachineFunction &F) override;
65 67
66 void getAnalysisUsage(AnalysisUsage &AU) const { 68 void getAnalysisUsage(AnalysisUsage &AU) const override {
67 AU.addRequired<MachineDominatorTree>(); 69 AU.addRequired<MachineDominatorTree>();
68 MachineFunctionPass::getAnalysisUsage(AU); 70 MachineFunctionPass::getAnalysisUsage(AU);
69 } 71 }
70 72
71 private: 73 private:
76 /// 78 ///
77 /// Also, return the virtual register containing the target function's address 79 /// Also, return the virtual register containing the target function's address
78 /// and the underlying object in Reg and Val respectively, if the function's 80 /// and the underlying object in Reg and Val respectively, if the function's
79 /// address can be resolved lazily. 81 /// address can be resolved lazily.
80 bool isCallViaRegister(MachineInstr &MI, unsigned &Reg, 82 bool isCallViaRegister(MachineInstr &MI, unsigned &Reg,
81 const Value *&Val) const; 83 ValueType &Val) const;
82 84
83 /// \brief Return the number of instructions that dominate the current 85 /// \brief Return the number of instructions that dominate the current
84 /// instruction and load the function address from object Entry. 86 /// instruction and load the function address from object Entry.
85 unsigned getCount(const Value *Entry); 87 unsigned getCount(ValueType Entry);
86 88
87 /// \brief Return the destination virtual register of the last instruction 89 /// \brief Return the destination virtual register of the last instruction
88 /// that loads from object Entry. 90 /// that loads from object Entry.
89 unsigned getReg(const Value *Entry); 91 unsigned getReg(ValueType Entry);
90 92
91 /// \brief Update ScopedHT. 93 /// \brief Update ScopedHT.
92 void incCntAndSetReg(const Value *Entry, unsigned Reg); 94 void incCntAndSetReg(ValueType Entry, unsigned Reg);
93 95
94 ScopedHTType ScopedHT; 96 ScopedHTType ScopedHT;
95 static char ID; 97 static char ID;
96 }; 98 };
97 99
99 } // end of anonymous namespace 101 } // end of anonymous namespace
100 102
101 /// Return the first MachineOperand of MI if it is a used virtual register. 103 /// Return the first MachineOperand of MI if it is a used virtual register.
102 static MachineOperand *getCallTargetRegOpnd(MachineInstr &MI) { 104 static MachineOperand *getCallTargetRegOpnd(MachineInstr &MI) {
103 if (MI.getNumOperands() == 0) 105 if (MI.getNumOperands() == 0)
104 return 0; 106 return nullptr;
105 107
106 MachineOperand &MO = MI.getOperand(0); 108 MachineOperand &MO = MI.getOperand(0);
107 109
108 if (!MO.isReg() || !MO.isUse() || 110 if (!MO.isReg() || !MO.isUse() ||
109 !TargetRegisterInfo::isVirtualRegister(MO.getReg())) 111 !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
110 return 0; 112 return nullptr;
111 113
112 return &MO; 114 return &MO;
113 } 115 }
114 116
115 /// Return type of register Reg. 117 /// Return type of register Reg.
126 /// copy $t9, $vreg 128 /// copy $t9, $vreg
127 /// jalr $t9 129 /// jalr $t9
128 static void setCallTargetReg(MachineBasicBlock *MBB, 130 static void setCallTargetReg(MachineBasicBlock *MBB,
129 MachineBasicBlock::iterator I) { 131 MachineBasicBlock::iterator I) {
130 MachineFunction &MF = *MBB->getParent(); 132 MachineFunction &MF = *MBB->getParent();
131 const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 133 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
132 unsigned SrcReg = I->getOperand(0).getReg(); 134 unsigned SrcReg = I->getOperand(0).getReg();
133 unsigned DstReg = getRegTy(SrcReg, MF) == MVT::i32 ? Mips::T9 : Mips::T9_64; 135 unsigned DstReg = getRegTy(SrcReg, MF) == MVT::i32 ? Mips::T9 : Mips::T9_64;
134 BuildMI(*MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), DstReg) 136 BuildMI(*MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), DstReg)
135 .addReg(SrcReg); 137 .addReg(SrcReg);
136 I->getOperand(0).setReg(DstReg); 138 I->getOperand(0).setReg(DstReg);
151 MI.RemoveOperand(I); 153 MI.RemoveOperand(I);
152 return; 154 return;
153 } 155 }
154 } 156 }
155 157
156 llvm_unreachable(0); 158 llvm_unreachable(nullptr);
157 } 159 }
158 160
159 MBBInfo::MBBInfo(MachineDomTreeNode *N) : Node(N), HTScope(0) {} 161 MBBInfo::MBBInfo(MachineDomTreeNode *N) : Node(N), HTScope(nullptr) {}
160 162
161 const MachineDomTreeNode *MBBInfo::getNode() const { return Node; } 163 const MachineDomTreeNode *MBBInfo::getNode() const { return Node; }
162 164
163 bool MBBInfo::isVisited() const { return HTScope; } 165 bool MBBInfo::isVisited() const { return HTScope; }
164 166
208 MachineBasicBlock *MBB = MBBI.getNode()->getBlock(); 210 MachineBasicBlock *MBB = MBBI.getNode()->getBlock();
209 211
210 for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E; 212 for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;
211 ++I) { 213 ++I) {
212 unsigned Reg; 214 unsigned Reg;
213 const Value *Entry; 215 ValueType Entry;
214 216
215 // Skip instructions that are not call instructions via registers. 217 // Skip instructions that are not call instructions via registers.
216 if (!isCallViaRegister(*I, Reg, Entry)) 218 if (!isCallViaRegister(*I, Reg, Entry))
217 continue; 219 continue;
218 220
240 242
241 return Changed; 243 return Changed;
242 } 244 }
243 245
244 bool OptimizePICCall::isCallViaRegister(MachineInstr &MI, unsigned &Reg, 246 bool OptimizePICCall::isCallViaRegister(MachineInstr &MI, unsigned &Reg,
245 const Value *&Val) const { 247 ValueType &Val) const {
246 if (!MI.isCall()) 248 if (!MI.isCall())
247 return false; 249 return false;
248 250
249 MachineOperand *MO = getCallTargetRegOpnd(MI); 251 MachineOperand *MO = getCallTargetRegOpnd(MI);
250 252
252 if (!MO) 254 if (!MO)
253 return false; 255 return false;
254 256
255 // Get the instruction that loads the function address from the GOT. 257 // Get the instruction that loads the function address from the GOT.
256 Reg = MO->getReg(); 258 Reg = MO->getReg();
257 Val = 0; 259 Val = (Value*)nullptr;
258 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo(); 260 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
259 MachineInstr *DefMI = MRI.getVRegDef(Reg); 261 MachineInstr *DefMI = MRI.getVRegDef(Reg);
260 262
261 assert(DefMI); 263 assert(DefMI);
262 264
271 return true; 273 return true;
272 274
273 // Return the underlying object for the GOT entry in Val. 275 // Return the underlying object for the GOT entry in Val.
274 assert(DefMI->hasOneMemOperand()); 276 assert(DefMI->hasOneMemOperand());
275 Val = (*DefMI->memoperands_begin())->getValue(); 277 Val = (*DefMI->memoperands_begin())->getValue();
278 if (!Val)
279 Val = (*DefMI->memoperands_begin())->getPseudoValue();
276 return true; 280 return true;
277 } 281 }
278 282
279 unsigned OptimizePICCall::getCount(const Value *Entry) { 283 unsigned OptimizePICCall::getCount(ValueType Entry) {
280 return ScopedHT.lookup(Entry).first; 284 return ScopedHT.lookup(Entry).first;
281 } 285 }
282 286
283 unsigned OptimizePICCall::getReg(const Value *Entry) { 287 unsigned OptimizePICCall::getReg(ValueType Entry) {
284 unsigned Reg = ScopedHT.lookup(Entry).second; 288 unsigned Reg = ScopedHT.lookup(Entry).second;
285 assert(Reg); 289 assert(Reg);
286 return Reg; 290 return Reg;
287 } 291 }
288 292
289 void OptimizePICCall::incCntAndSetReg(const Value *Entry, unsigned Reg) { 293 void OptimizePICCall::incCntAndSetReg(ValueType Entry, unsigned Reg) {
290 CntRegP P = ScopedHT.lookup(Entry); 294 CntRegP P = ScopedHT.lookup(Entry);
291 ScopedHT.insert(Entry, std::make_pair(P.first + 1, Reg)); 295 ScopedHT.insert(Entry, std::make_pair(P.first + 1, Reg));
292 } 296 }
293 297
294 /// Return an OptimizeCall object. 298 /// Return an OptimizeCall object.