blob: 5ef07a2d283e63b669a71136f579184445c70436 [file] [log] [blame]
Eugene Zelenko79220eae2017-08-03 22:12:30 +00001//===- MipsOptimizePICCall.cpp - Optimize PIC Calls -----------------------===//
Akira Hatanaka168d4e52013-11-27 23:38:42 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Akira Hatanaka168d4e52013-11-27 23:38:42 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This pass eliminates unnecessary instructions that set up $gp and replace
10// instructions that load target function addresses with copy instructions.
11//
12//===----------------------------------------------------------------------===//
13
Akira Hatanaka168d4e52013-11-27 23:38:42 +000014#include "MCTargetDesc/MipsBaseInfo.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000015#include "Mips.h"
Eugene Zelenko79220eae2017-08-03 22:12:30 +000016#include "MipsRegisterInfo.h"
17#include "MipsSubtarget.h"
18#include "llvm/ADT/PointerUnion.h"
Akira Hatanaka168d4e52013-11-27 23:38:42 +000019#include "llvm/ADT/ScopedHashTable.h"
Eugene Zelenko79220eae2017-08-03 22:12:30 +000020#include "llvm/ADT/SmallVector.h"
21#include "llvm/CodeGen/MachineBasicBlock.h"
Akira Hatanaka168d4e52013-11-27 23:38:42 +000022#include "llvm/CodeGen/MachineDominators.h"
Eugene Zelenko79220eae2017-08-03 22:12:30 +000023#include "llvm/CodeGen/MachineFunction.h"
24#include "llvm/CodeGen/MachineFunctionPass.h"
25#include "llvm/CodeGen/MachineInstr.h"
26#include "llvm/CodeGen/MachineInstrBuilder.h"
27#include "llvm/CodeGen/MachineOperand.h"
Akira Hatanaka168d4e52013-11-27 23:38:42 +000028#include "llvm/CodeGen/MachineRegisterInfo.h"
David Blaikie3f833ed2017-11-08 01:01:31 +000029#include "llvm/CodeGen/TargetInstrInfo.h"
David Blaikieb3bde2e2017-11-17 01:07:10 +000030#include "llvm/CodeGen/TargetOpcodes.h"
31#include "llvm/CodeGen/TargetRegisterInfo.h"
32#include "llvm/CodeGen/TargetSubtargetInfo.h"
Eugene Zelenko79220eae2017-08-03 22:12:30 +000033#include "llvm/Support/Allocator.h"
Akira Hatanaka168d4e52013-11-27 23:38:42 +000034#include "llvm/Support/CommandLine.h"
Eugene Zelenko79220eae2017-08-03 22:12:30 +000035#include "llvm/Support/ErrorHandling.h"
David Blaikie13e77db2018-03-23 23:58:25 +000036#include "llvm/Support/MachineValueType.h"
Eugene Zelenko79220eae2017-08-03 22:12:30 +000037#include "llvm/Support/RecyclingAllocator.h"
Eugene Zelenko79220eae2017-08-03 22:12:30 +000038#include <cassert>
39#include <utility>
40#include <vector>
Akira Hatanaka168d4e52013-11-27 23:38:42 +000041
42using namespace llvm;
43
Chandler Carruth84e68b22014-04-22 02:41:26 +000044#define DEBUG_TYPE "optimize-mips-pic-call"
45
Akira Hatanaka168d4e52013-11-27 23:38:42 +000046static cl::opt<bool> LoadTargetFromGOT("mips-load-target-from-got",
47 cl::init(true),
48 cl::desc("Load target address from GOT"),
49 cl::Hidden);
50
51static cl::opt<bool> EraseGPOpnd("mips-erase-gp-opnd",
52 cl::init(true), cl::desc("Erase GP Operand"),
53 cl::Hidden);
54
55namespace {
Nick Lewyckyaad475b2014-04-15 07:22:52 +000056
Eugene Zelenko79220eae2017-08-03 22:12:30 +000057using ValueType = PointerUnion<const Value *, const PseudoSourceValue *>;
58using CntRegP = std::pair<unsigned, unsigned>;
59using AllocatorTy = RecyclingAllocator<BumpPtrAllocator,
60 ScopedHashTableVal<ValueType, CntRegP>>;
61using ScopedHTType = ScopedHashTable<ValueType, CntRegP,
62 DenseMapInfo<ValueType>, AllocatorTy>;
Akira Hatanaka168d4e52013-11-27 23:38:42 +000063
64class MBBInfo {
65public:
66 MBBInfo(MachineDomTreeNode *N);
Eugene Zelenko79220eae2017-08-03 22:12:30 +000067
Akira Hatanaka168d4e52013-11-27 23:38:42 +000068 const MachineDomTreeNode *getNode() const;
69 bool isVisited() const;
70 void preVisit(ScopedHTType &ScopedHT);
71 void postVisit();
72
73private:
74 MachineDomTreeNode *Node;
75 ScopedHTType::ScopeTy *HTScope;
76};
77
78class OptimizePICCall : public MachineFunctionPass {
79public:
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +000080 OptimizePICCall() : MachineFunctionPass(ID) {}
Akira Hatanaka168d4e52013-11-27 23:38:42 +000081
Mehdi Amini117296c2016-10-01 02:56:57 +000082 StringRef getPassName() const override { return "Mips OptimizePICCall"; }
Akira Hatanaka168d4e52013-11-27 23:38:42 +000083
Craig Topper56c590a2014-04-29 07:58:02 +000084 bool runOnMachineFunction(MachineFunction &F) override;
Akira Hatanaka168d4e52013-11-27 23:38:42 +000085
Craig Topper56c590a2014-04-29 07:58:02 +000086 void getAnalysisUsage(AnalysisUsage &AU) const override {
Akira Hatanaka168d4e52013-11-27 23:38:42 +000087 AU.addRequired<MachineDominatorTree>();
88 MachineFunctionPass::getAnalysisUsage(AU);
89 }
90
91private:
Adrian Prantl5f8f34e42018-05-01 15:54:18 +000092 /// Visit MBB.
Akira Hatanaka168d4e52013-11-27 23:38:42 +000093 bool visitNode(MBBInfo &MBBI);
94
Adrian Prantl5f8f34e42018-05-01 15:54:18 +000095 /// Test if MI jumps to a function via a register.
Akira Hatanaka168d4e52013-11-27 23:38:42 +000096 ///
97 /// Also, return the virtual register containing the target function's address
98 /// and the underlying object in Reg and Val respectively, if the function's
99 /// address can be resolved lazily.
100 bool isCallViaRegister(MachineInstr &MI, unsigned &Reg,
Nick Lewyckyaad475b2014-04-15 07:22:52 +0000101 ValueType &Val) const;
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000102
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000103 /// Return the number of instructions that dominate the current
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000104 /// instruction and load the function address from object Entry.
Nick Lewyckyaad475b2014-04-15 07:22:52 +0000105 unsigned getCount(ValueType Entry);
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000106
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000107 /// Return the destination virtual register of the last instruction
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000108 /// that loads from object Entry.
Nick Lewyckyaad475b2014-04-15 07:22:52 +0000109 unsigned getReg(ValueType Entry);
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000110
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000111 /// Update ScopedHT.
Nick Lewyckyaad475b2014-04-15 07:22:52 +0000112 void incCntAndSetReg(ValueType Entry, unsigned Reg);
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000113
114 ScopedHTType ScopedHT;
Eugene Zelenko79220eae2017-08-03 22:12:30 +0000115
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000116 static char ID;
117};
118
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000119} // end of anonymous namespace
120
Eugene Zelenko79220eae2017-08-03 22:12:30 +0000121char OptimizePICCall::ID = 0;
122
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000123/// Return the first MachineOperand of MI if it is a used virtual register.
124static MachineOperand *getCallTargetRegOpnd(MachineInstr &MI) {
125 if (MI.getNumOperands() == 0)
Craig Topper062a2ba2014-04-25 05:30:21 +0000126 return nullptr;
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000127
128 MachineOperand &MO = MI.getOperand(0);
129
130 if (!MO.isReg() || !MO.isUse() ||
131 !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
Craig Topper062a2ba2014-04-25 05:30:21 +0000132 return nullptr;
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000133
134 return &MO;
135}
136
137/// Return type of register Reg.
138static MVT::SimpleValueType getRegTy(unsigned Reg, MachineFunction &MF) {
Krzysztof Parzyszekc8e8e2a2017-04-24 19:51:12 +0000139 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000140 const TargetRegisterClass *RC = MF.getRegInfo().getRegClass(Reg);
Krzysztof Parzyszekc8e8e2a2017-04-24 19:51:12 +0000141 assert(TRI.legalclasstypes_end(*RC) - TRI.legalclasstypes_begin(*RC) == 1);
142 return *TRI.legalclasstypes_begin(*RC);
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000143}
144
145/// Do the following transformation:
146///
147/// jalr $vreg
148/// =>
149/// copy $t9, $vreg
150/// jalr $t9
151static void setCallTargetReg(MachineBasicBlock *MBB,
152 MachineBasicBlock::iterator I) {
153 MachineFunction &MF = *MBB->getParent();
Eric Christopherfc6de422014-08-05 02:39:49 +0000154 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000155 unsigned SrcReg = I->getOperand(0).getReg();
156 unsigned DstReg = getRegTy(SrcReg, MF) == MVT::i32 ? Mips::T9 : Mips::T9_64;
157 BuildMI(*MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), DstReg)
158 .addReg(SrcReg);
159 I->getOperand(0).setReg(DstReg);
160}
161
162/// Search MI's operands for register GP and erase it.
163static void eraseGPOpnd(MachineInstr &MI) {
164 if (!EraseGPOpnd)
165 return;
166
167 MachineFunction &MF = *MI.getParent()->getParent();
168 MVT::SimpleValueType Ty = getRegTy(MI.getOperand(0).getReg(), MF);
169 unsigned Reg = Ty == MVT::i32 ? Mips::GP : Mips::GP_64;
170
171 for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
172 MachineOperand &MO = MI.getOperand(I);
173 if (MO.isReg() && MO.getReg() == Reg) {
174 MI.RemoveOperand(I);
175 return;
176 }
177 }
178
Craig Toppere73658d2014-04-28 04:05:08 +0000179 llvm_unreachable(nullptr);
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000180}
181
Craig Topper062a2ba2014-04-25 05:30:21 +0000182MBBInfo::MBBInfo(MachineDomTreeNode *N) : Node(N), HTScope(nullptr) {}
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000183
184const MachineDomTreeNode *MBBInfo::getNode() const { return Node; }
185
186bool MBBInfo::isVisited() const { return HTScope; }
187
188void MBBInfo::preVisit(ScopedHTType &ScopedHT) {
189 HTScope = new ScopedHTType::ScopeTy(ScopedHT);
190}
191
192void MBBInfo::postVisit() {
193 delete HTScope;
194}
195
196// OptimizePICCall methods.
197bool OptimizePICCall::runOnMachineFunction(MachineFunction &F) {
Eric Christopher96e72c62015-01-29 23:27:36 +0000198 if (static_cast<const MipsSubtarget &>(F.getSubtarget()).inMips16Mode())
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000199 return false;
200
201 // Do a pre-order traversal of the dominator tree.
202 MachineDominatorTree *MDT = &getAnalysis<MachineDominatorTree>();
203 bool Changed = false;
204
205 SmallVector<MBBInfo, 8> WorkList(1, MBBInfo(MDT->getRootNode()));
206
207 while (!WorkList.empty()) {
208 MBBInfo &MBBI = WorkList.back();
209
210 // If this MBB has already been visited, destroy the scope for the MBB and
211 // pop it from the work list.
212 if (MBBI.isVisited()) {
213 MBBI.postVisit();
214 WorkList.pop_back();
215 continue;
216 }
217
218 // Visit the MBB and add its children to the work list.
219 MBBI.preVisit(ScopedHT);
220 Changed |= visitNode(MBBI);
221 const MachineDomTreeNode *Node = MBBI.getNode();
222 const std::vector<MachineDomTreeNode *> &Children = Node->getChildren();
223 WorkList.append(Children.begin(), Children.end());
224 }
225
226 return Changed;
227}
228
229bool OptimizePICCall::visitNode(MBBInfo &MBBI) {
230 bool Changed = false;
231 MachineBasicBlock *MBB = MBBI.getNode()->getBlock();
232
233 for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;
234 ++I) {
235 unsigned Reg;
Nick Lewyckyaad475b2014-04-15 07:22:52 +0000236 ValueType Entry;
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000237
238 // Skip instructions that are not call instructions via registers.
239 if (!isCallViaRegister(*I, Reg, Entry))
240 continue;
241
242 Changed = true;
243 unsigned N = getCount(Entry);
244
245 if (N != 0) {
246 // If a function has been called more than twice, we do not have to emit a
247 // load instruction to get the function address from the GOT, but can
248 // instead reuse the address that has been loaded before.
249 if (N >= 2 && !LoadTargetFromGOT)
250 getCallTargetRegOpnd(*I)->setReg(getReg(Entry));
251
252 // Erase the $gp operand if this isn't the first time a function has
253 // been called. $gp needs to be set up only if the function call can go
254 // through a lazy binding stub.
255 eraseGPOpnd(*I);
256 }
257
258 if (Entry)
259 incCntAndSetReg(Entry, Reg);
260
261 setCallTargetReg(MBB, I);
262 }
263
264 return Changed;
265}
266
267bool OptimizePICCall::isCallViaRegister(MachineInstr &MI, unsigned &Reg,
Nick Lewyckyaad475b2014-04-15 07:22:52 +0000268 ValueType &Val) const {
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000269 if (!MI.isCall())
270 return false;
271
272 MachineOperand *MO = getCallTargetRegOpnd(MI);
273
274 // Return if MI is not a function call via a register.
275 if (!MO)
276 return false;
277
278 // Get the instruction that loads the function address from the GOT.
279 Reg = MO->getReg();
Serge Gueltonf4dc59b2017-05-11 08:53:00 +0000280 Val = nullptr;
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000281 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
282 MachineInstr *DefMI = MRI.getVRegDef(Reg);
283
284 assert(DefMI);
285
286 // See if DefMI is an instruction that loads from a GOT entry that holds the
287 // address of a lazy binding stub.
288 if (!DefMI->mayLoad() || DefMI->getNumOperands() < 3)
289 return true;
290
291 unsigned Flags = DefMI->getOperand(2).getTargetFlags();
292
293 if (Flags != MipsII::MO_GOT_CALL && Flags != MipsII::MO_CALL_LO16)
294 return true;
295
296 // Return the underlying object for the GOT entry in Val.
297 assert(DefMI->hasOneMemOperand());
298 Val = (*DefMI->memoperands_begin())->getValue();
Nick Lewyckyaad475b2014-04-15 07:22:52 +0000299 if (!Val)
300 Val = (*DefMI->memoperands_begin())->getPseudoValue();
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000301 return true;
302}
303
Nick Lewyckyaad475b2014-04-15 07:22:52 +0000304unsigned OptimizePICCall::getCount(ValueType Entry) {
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000305 return ScopedHT.lookup(Entry).first;
306}
307
Nick Lewyckyaad475b2014-04-15 07:22:52 +0000308unsigned OptimizePICCall::getReg(ValueType Entry) {
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000309 unsigned Reg = ScopedHT.lookup(Entry).second;
310 assert(Reg);
311 return Reg;
312}
313
Nick Lewyckyaad475b2014-04-15 07:22:52 +0000314void OptimizePICCall::incCntAndSetReg(ValueType Entry, unsigned Reg) {
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000315 CntRegP P = ScopedHT.lookup(Entry);
316 ScopedHT.insert(Entry, std::make_pair(P.first + 1, Reg));
317}
318
319/// Return an OptimizeCall object.
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +0000320FunctionPass *llvm::createMipsOptimizePICCallPass() {
321 return new OptimizePICCall();
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000322}