Mercurial > hg > CbC > CbC_llvm
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. |