LLVM  12.0.0git
MipsOptimizePICCall.cpp
Go to the documentation of this file.
1 //===- MipsOptimizePICCall.cpp - Optimize PIC Calls -----------------------===//
2 //
3 // 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
6 //
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 
15 #include "Mips.h"
16 #include "MipsRegisterInfo.h"
17 #include "MipsSubtarget.h"
18 #include "llvm/ADT/PointerUnion.h"
20 #include "llvm/ADT/SmallVector.h"
33 #include "llvm/Support/Allocator.h"
38 #include <cassert>
39 #include <utility>
40 #include <vector>
41 
42 using namespace llvm;
43 
44 #define DEBUG_TYPE "optimize-mips-pic-call"
45 
46 static 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 
51 static cl::opt<bool> EraseGPOpnd("mips-erase-gp-opnd",
52  cl::init(true), cl::desc("Erase GP Operand"),
53  cl::Hidden);
54 
55 namespace {
56 
58 using CntRegP = std::pair<unsigned, unsigned>;
59 using AllocatorTy = RecyclingAllocator<BumpPtrAllocator,
61 using ScopedHTType = ScopedHashTable<ValueType, CntRegP,
62  DenseMapInfo<ValueType>, AllocatorTy>;
63 
64 class MBBInfo {
65 public:
66  MBBInfo(MachineDomTreeNode *N);
67 
68  const MachineDomTreeNode *getNode() const;
69  bool isVisited() const;
70  void preVisit(ScopedHTType &ScopedHT);
71  void postVisit();
72 
73 private:
74  MachineDomTreeNode *Node;
75  ScopedHTType::ScopeTy *HTScope;
76 };
77 
78 class OptimizePICCall : public MachineFunctionPass {
79 public:
80  OptimizePICCall() : MachineFunctionPass(ID) {}
81 
82  StringRef getPassName() const override { return "Mips OptimizePICCall"; }
83 
84  bool runOnMachineFunction(MachineFunction &F) override;
85 
86  void getAnalysisUsage(AnalysisUsage &AU) const override {
89  }
90 
91 private:
92  /// Visit MBB.
93  bool visitNode(MBBInfo &MBBI);
94 
95  /// Test if MI jumps to a function via a register.
96  ///
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,
101  ValueType &Val) const;
102 
103  /// Return the number of instructions that dominate the current
104  /// instruction and load the function address from object Entry.
105  unsigned getCount(ValueType Entry);
106 
107  /// Return the destination virtual register of the last instruction
108  /// that loads from object Entry.
109  unsigned getReg(ValueType Entry);
110 
111  /// Update ScopedHT.
112  void incCntAndSetReg(ValueType Entry, unsigned Reg);
113 
114  ScopedHTType ScopedHT;
115 
116  static char ID;
117 };
118 
119 } // end of anonymous namespace
120 
121 char OptimizePICCall::ID = 0;
122 
123 /// Return the first MachineOperand of MI if it is a used virtual register.
125  if (MI.getNumOperands() == 0)
126  return nullptr;
127 
128  MachineOperand &MO = MI.getOperand(0);
129 
130  if (!MO.isReg() || !MO.isUse() || !Register::isVirtualRegister(MO.getReg()))
131  return nullptr;
132 
133  return &MO;
134 }
135 
136 /// Return type of register Reg.
139  const TargetRegisterClass *RC = MF.getRegInfo().getRegClass(Reg);
140  assert(TRI.legalclasstypes_end(*RC) - TRI.legalclasstypes_begin(*RC) == 1);
141  return *TRI.legalclasstypes_begin(*RC);
142 }
143 
144 /// Do the following transformation:
145 ///
146 /// jalr $vreg
147 /// =>
148 /// copy $t9, $vreg
149 /// jalr $t9
152  MachineFunction &MF = *MBB->getParent();
153  const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
154  Register SrcReg = I->getOperand(0).getReg();
155  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.
162 static void eraseGPOpnd(MachineInstr &MI) {
163  if (!EraseGPOpnd)
164  return;
165 
166  MachineFunction &MF = *MI.getParent()->getParent();
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 
178  llvm_unreachable(nullptr);
179 }
180 
181 MBBInfo::MBBInfo(MachineDomTreeNode *N) : Node(N), HTScope(nullptr) {}
182 
183 const MachineDomTreeNode *MBBInfo::getNode() const { return Node; }
184 
185 bool MBBInfo::isVisited() const { return HTScope; }
186 
187 void MBBInfo::preVisit(ScopedHTType &ScopedHT) {
188  HTScope = new ScopedHTType::ScopeTy(ScopedHT);
189 }
190 
191 void MBBInfo::postVisit() {
192  delete HTScope;
193 }
194 
195 // OptimizePICCall methods.
196 bool OptimizePICCall::runOnMachineFunction(MachineFunction &F) {
197  if (static_cast<const MipsSubtarget &>(F.getSubtarget()).inMips16Mode())
198  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  WorkList.append(Node->begin(), Node->end());
222  }
223 
224  return Changed;
225 }
226 
227 bool OptimizePICCall::visitNode(MBBInfo &MBBI) {
228  bool Changed = false;
229  MachineBasicBlock *MBB = MBBI.getNode()->getBlock();
230 
231  for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;
232  ++I) {
233  unsigned Reg;
234  ValueType Entry;
235 
236  // Skip instructions that are not call instructions via registers.
237  if (!isCallViaRegister(*I, Reg, Entry))
238  continue;
239 
240  Changed = true;
241  unsigned N = getCount(Entry);
242 
243  if (N != 0) {
244  // If a function has been called more than twice, we do not have to emit a
245  // load instruction to get the function address from the GOT, but can
246  // instead reuse the address that has been loaded before.
247  if (N >= 2 && !LoadTargetFromGOT)
248  getCallTargetRegOpnd(*I)->setReg(getReg(Entry));
249 
250  // Erase the $gp operand if this isn't the first time a function has
251  // been called. $gp needs to be set up only if the function call can go
252  // through a lazy binding stub.
253  eraseGPOpnd(*I);
254  }
255 
256  if (Entry)
257  incCntAndSetReg(Entry, Reg);
258 
259  setCallTargetReg(MBB, I);
260  }
261 
262  return Changed;
263 }
264 
265 bool OptimizePICCall::isCallViaRegister(MachineInstr &MI, unsigned &Reg,
266  ValueType &Val) const {
267  if (!MI.isCall())
268  return false;
269 
271 
272  // Return if MI is not a function call via a register.
273  if (!MO)
274  return false;
275 
276  // Get the instruction that loads the function address from the GOT.
277  Reg = MO->getReg();
278  Val = nullptr;
280  MachineInstr *DefMI = MRI.getVRegDef(Reg);
281 
282  assert(DefMI);
283 
284  // See if DefMI is an instruction that loads from a GOT entry that holds the
285  // address of a lazy binding stub.
286  if (!DefMI->mayLoad() || DefMI->getNumOperands() < 3)
287  return true;
288 
289  unsigned Flags = DefMI->getOperand(2).getTargetFlags();
290 
291  if (Flags != MipsII::MO_GOT_CALL && Flags != MipsII::MO_CALL_LO16)
292  return true;
293 
294  // Return the underlying object for the GOT entry in Val.
295  assert(DefMI->hasOneMemOperand());
296  Val = (*DefMI->memoperands_begin())->getValue();
297  if (!Val)
298  Val = (*DefMI->memoperands_begin())->getPseudoValue();
299  return true;
300 }
301 
302 unsigned OptimizePICCall::getCount(ValueType Entry) {
303  return ScopedHT.lookup(Entry).first;
304 }
305 
306 unsigned OptimizePICCall::getReg(ValueType Entry) {
307  unsigned Reg = ScopedHT.lookup(Entry).second;
308  assert(Reg);
309  return Reg;
310 }
311 
312 void OptimizePICCall::incCntAndSetReg(ValueType Entry, unsigned Reg) {
313  CntRegP P = ScopedHT.lookup(Entry);
314  ScopedHT.insert(Entry, std::make_pair(P.first + 1, Reg));
315 }
316 
317 /// Return an OptimizeCall object.
319  return new OptimizePICCall();
320 }
unsigned getTargetFlags() const
PointerUnion< const Value *, const PseudoSourceValue * > ValueType
bool isCall(QueryType Type=AnyInBundle) const
Definition: MachineInstr.h:760
This class represents lattice values for constants.
Definition: AllocatorList.h:23
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
unsigned Reg
static MachineOperand * getCallTargetRegOpnd(MachineInstr &MI)
Return the first MachineOperand of MI if it is a used virtual register.
unsigned const TargetRegisterInfo * TRI
F(f)
static void setCallTargetReg(MachineBasicBlock *MBB, MachineBasicBlock::iterator I)
Do the following transformation:
This file defines the BumpPtrAllocator interface.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
MachineBasicBlock & MBB
AnalysisUsage & addRequired()
vt_iterator legalclasstypes_end(const TargetRegisterClass &RC) const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:459
RecyclingAllocator - This class wraps an Allocator, adding the functionality of recycling deleted obj...
Base class for the actual dominator tree node.
void setReg(Register Reg)
Change the register this operand corresponds to.
virtual const TargetInstrInfo * getInstrInfo() const
TargetInstrInfo - Interface to description of machine instruction set.
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition: Allocator.h:370
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
#define P(N)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:434
MO_GOT_CALL - Represents the offset into the global offset table at which the address of a call site ...
Definition: MipsBaseInfo.h:44
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
FunctionPass * createMipsOptimizePICCallPass()
Return an OptimizeCall object.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Represent the analysis usage information of a pass.
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
Definition: MachineInstr.h:660
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
static cl::opt< bool > LoadTargetFromGOT("mips-load-target-from-got", cl::init(true), cl::desc("Load target address from GOT"), cl::Hidden)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:645
MachineDomTreeNode * getRootNode() const
MachineOperand class - Representation of each machine instruction operand.
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:883
MachineInstrBuilder MachineInstrBuilder & DefMI
static cl::opt< bool > EraseGPOpnd("mips-erase-gp-opnd", cl::init(true), cl::desc("Erase GP Operand"), cl::Hidden)
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:433
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:280
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:62
static void eraseGPOpnd(MachineInstr &MI)
Search MI&#39;s operands for register GP and erase it.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:62
#define I(x, y, z)
Definition: MD5.cpp:59
#define N
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
Definition: MachineInstr.h:942
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static MVT::SimpleValueType getRegTy(unsigned Reg, MachineFunction &MF)
Return type of register Reg.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:71
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
void RemoveOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
Register getReg() const
getReg - Returns the register number.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:466
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineBasicBlock MachineBasicBlock::iterator MBBI
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...
Definition: PointerUnion.h:156
vt_iterator legalclasstypes_begin(const TargetRegisterClass &RC) const
Loop over all of the value types that can be represented by values in the given register class...