blob: 8bd64ff6cb271ade52f78115b0bfa8c1774ad722 [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
Daniel Sanders2bea69b2019-08-01 23:27:28 +0000130 if (!MO.isReg() || !MO.isUse() || !Register::isVirtualRegister(MO.getReg()))
Craig Topper062a2ba2014-04-25 05:30:21 +0000131 return nullptr;
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000132
133 return &MO;
134}
135
136/// Return type of register Reg.
137static MVT::SimpleValueType getRegTy(unsigned Reg, MachineFunction &MF) {
Krzysztof Parzyszekc8e8e2a2017-04-24 19:51:12 +0000138 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000139 const TargetRegisterClass *RC = MF.getRegInfo().getRegClass(Reg);
Krzysztof Parzyszekc8e8e2a2017-04-24 19:51:12 +0000140 assert(TRI.legalclasstypes_end(*RC) - TRI.legalclasstypes_begin(*RC) == 1);
141 return *TRI.legalclasstypes_begin(*RC);
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000142}
143
144/// Do the following transformation:
145///
146/// jalr $vreg
147/// =>
148/// copy $t9, $vreg
149/// jalr $t9
150static void setCallTargetReg(MachineBasicBlock *MBB,
151 MachineBasicBlock::iterator I) {
152 MachineFunction &MF = *MBB->getParent();
Eric Christopherfc6de422014-08-05 02:39:49 +0000153 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
Daniel Sanders0c476112019-08-15 19:22:08 +0000154 Register SrcReg = I->getOperand(0).getReg();
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000155 unsigned DstReg = getRegTy(SrcReg, MF) == MVT::i32 ? Mips::T9 : Mips::T9_64;
156 BuildMI(*MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), DstReg)
157 .addReg(SrcReg);
158 I->getOperand(0).setReg(DstReg);
159}
160
161/// Search MI's operands for register GP and erase it.
162static void eraseGPOpnd(MachineInstr &MI) {
163 if (!EraseGPOpnd)
164 return;
165
166 MachineFunction &MF = *MI.getParent()->getParent();
167 MVT::SimpleValueType Ty = getRegTy(MI.getOperand(0).getReg(), MF);
168 unsigned Reg = Ty == MVT::i32 ? Mips::GP : Mips::GP_64;
169
170 for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
171 MachineOperand &MO = MI.getOperand(I);
172 if (MO.isReg() && MO.getReg() == Reg) {
173 MI.RemoveOperand(I);
174 return;
175 }
176 }
177
Craig Toppere73658d2014-04-28 04:05:08 +0000178 llvm_unreachable(nullptr);
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000179}
180
Craig Topper062a2ba2014-04-25 05:30:21 +0000181MBBInfo::MBBInfo(MachineDomTreeNode *N) : Node(N), HTScope(nullptr) {}
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000182
183const MachineDomTreeNode *MBBInfo::getNode() const { return Node; }
184
185bool MBBInfo::isVisited() const { return HTScope; }
186
187void MBBInfo::preVisit(ScopedHTType &ScopedHT) {
188 HTScope = new ScopedHTType::ScopeTy(ScopedHT);
189}
190
191void MBBInfo::postVisit() {
192 delete HTScope;
193}
194
195// OptimizePICCall methods.
196bool OptimizePICCall::runOnMachineFunction(MachineFunction &F) {
Eric Christopher96e72c62015-01-29 23:27:36 +0000197 if (static_cast<const MipsSubtarget &>(F.getSubtarget()).inMips16Mode())
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000198 return false;
199
200 // Do a pre-order traversal of the dominator tree.
201 MachineDominatorTree *MDT = &getAnalysis<MachineDominatorTree>();
202 bool Changed = false;
203
204 SmallVector<MBBInfo, 8> WorkList(1, MBBInfo(MDT->getRootNode()));
205
206 while (!WorkList.empty()) {
207 MBBInfo &MBBI = WorkList.back();
208
209 // If this MBB has already been visited, destroy the scope for the MBB and
210 // pop it from the work list.
211 if (MBBI.isVisited()) {
212 MBBI.postVisit();
213 WorkList.pop_back();
214 continue;
215 }
216
217 // Visit the MBB and add its children to the work list.
218 MBBI.preVisit(ScopedHT);
219 Changed |= visitNode(MBBI);
220 const MachineDomTreeNode *Node = MBBI.getNode();
221 const std::vector<MachineDomTreeNode *> &Children = Node->getChildren();
222 WorkList.append(Children.begin(), Children.end());
223 }
224
225 return Changed;
226}
227
228bool OptimizePICCall::visitNode(MBBInfo &MBBI) {
229 bool Changed = false;
230 MachineBasicBlock *MBB = MBBI.getNode()->getBlock();
231
232 for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;
233 ++I) {
234 unsigned Reg;
Nick Lewyckyaad475b2014-04-15 07:22:52 +0000235 ValueType Entry;
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000236
237 // Skip instructions that are not call instructions via registers.
238 if (!isCallViaRegister(*I, Reg, Entry))
239 continue;
240
241 Changed = true;
242 unsigned N = getCount(Entry);
243
244 if (N != 0) {
245 // If a function has been called more than twice, we do not have to emit a
246 // load instruction to get the function address from the GOT, but can
247 // instead reuse the address that has been loaded before.
248 if (N >= 2 && !LoadTargetFromGOT)
249 getCallTargetRegOpnd(*I)->setReg(getReg(Entry));
250
251 // Erase the $gp operand if this isn't the first time a function has
252 // been called. $gp needs to be set up only if the function call can go
253 // through a lazy binding stub.
254 eraseGPOpnd(*I);
255 }
256
257 if (Entry)
258 incCntAndSetReg(Entry, Reg);
259
260 setCallTargetReg(MBB, I);
261 }
262
263 return Changed;
264}
265
266bool OptimizePICCall::isCallViaRegister(MachineInstr &MI, unsigned &Reg,
Nick Lewyckyaad475b2014-04-15 07:22:52 +0000267 ValueType &Val) const {
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000268 if (!MI.isCall())
269 return false;
270
271 MachineOperand *MO = getCallTargetRegOpnd(MI);
272
273 // Return if MI is not a function call via a register.
274 if (!MO)
275 return false;
276
277 // Get the instruction that loads the function address from the GOT.
278 Reg = MO->getReg();
Serge Gueltonf4dc59b2017-05-11 08:53:00 +0000279 Val = nullptr;
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000280 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
281 MachineInstr *DefMI = MRI.getVRegDef(Reg);
282
283 assert(DefMI);
284
285 // See if DefMI is an instruction that loads from a GOT entry that holds the
286 // address of a lazy binding stub.
287 if (!DefMI->mayLoad() || DefMI->getNumOperands() < 3)
288 return true;
289
290 unsigned Flags = DefMI->getOperand(2).getTargetFlags();
291
292 if (Flags != MipsII::MO_GOT_CALL && Flags != MipsII::MO_CALL_LO16)
293 return true;
294
295 // Return the underlying object for the GOT entry in Val.
296 assert(DefMI->hasOneMemOperand());
297 Val = (*DefMI->memoperands_begin())->getValue();
Nick Lewyckyaad475b2014-04-15 07:22:52 +0000298 if (!Val)
299 Val = (*DefMI->memoperands_begin())->getPseudoValue();
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000300 return true;
301}
302
Nick Lewyckyaad475b2014-04-15 07:22:52 +0000303unsigned OptimizePICCall::getCount(ValueType Entry) {
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000304 return ScopedHT.lookup(Entry).first;
305}
306
Nick Lewyckyaad475b2014-04-15 07:22:52 +0000307unsigned OptimizePICCall::getReg(ValueType Entry) {
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000308 unsigned Reg = ScopedHT.lookup(Entry).second;
309 assert(Reg);
310 return Reg;
311}
312
Nick Lewyckyaad475b2014-04-15 07:22:52 +0000313void OptimizePICCall::incCntAndSetReg(ValueType Entry, unsigned Reg) {
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000314 CntRegP P = ScopedHT.lookup(Entry);
315 ScopedHT.insert(Entry, std::make_pair(P.first + 1, Reg));
316}
317
318/// Return an OptimizeCall object.
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +0000319FunctionPass *llvm::createMipsOptimizePICCallPass() {
320 return new OptimizePICCall();
Akira Hatanaka168d4e52013-11-27 23:38:42 +0000321}