LLVM  13.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);
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();
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 
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 
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;
279  MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
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.
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 }
MipsBaseInfo.h
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:100
MachineInstr.h
llvm
Definition: AllocatorList.h:23
Reg
unsigned Reg
Definition: MachineSink.cpp:1566
llvm::ScopedHashTableVal
Definition: ScopedHashTable.h:46
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::MachineInstr::memoperands_begin
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:697
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::TargetSubtargetInfo::getInstrInfo
virtual const TargetInstrInfo * getInstrInfo() const
Definition: TargetSubtargetInfo.h:92
llvm::MachineInstr::mayLoad
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
Definition: MachineInstr.h:994
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
ErrorHandling.h
Allocator.h
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
MachineBasicBlock.h
llvm::TargetSubtargetInfo::getRegisterInfo
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Definition: TargetSubtargetInfo.h:124
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:143
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:231
TargetInstrInfo.h
llvm::MachineDominatorTree::getRootNode
MachineDomTreeNode * getRootNode() const
Definition: MachineDominators.h:100
llvm::BumpPtrAllocator
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition: Allocator.h:369
llvm::MachineBasicBlock::back
MachineInstr & back()
Definition: MachineBasicBlock.h:248
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1567
llvm::TargetRegisterInfo::legalclasstypes_end
vt_iterator legalclasstypes_end(const TargetRegisterClass &RC) const
Definition: TargetRegisterInfo.h:317
llvm::MachineInstr::hasOneMemOperand
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
Definition: MachineInstr.h:712
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:102
F
#define F(x, y, z)
Definition: MD5.cpp:56
MachineRegisterInfo.h
llvm::MachineBasicBlock::pop_back
void pop_back()
Definition: MachineBasicBlock.h:755
MachineValueType.h
llvm::MVT::SimpleValueType
SimpleValueType
Definition: MachineValueType.h:32
CommandLine.h
llvm::DenseMapInfo
Definition: APInt.h:34
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:568
llvm::TargetInstrInfo
TargetInstrInfo - Interface to description of machine instruction set.
Definition: TargetInstrInfo.h:97
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::MipsSubtarget::inMips16Mode
bool inMips16Mode() const
Definition: MipsSubtarget.h:300
llvm::createMipsOptimizePICCallPass
FunctionPass * createMipsOptimizePICCallPass()
Return an OptimizeCall object.
Definition: MipsOptimizePICCall.cpp:318
llvm::MachineOperand::isUse
bool isUse() const
Definition: MachineOperand.h:370
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:488
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
Mips.h
TargetOpcodes.h
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
MipsRegisterInfo.h
llvm::MachineRegisterInfo::getVRegDef
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Definition: MachineRegisterInfo.cpp:400
ScopedHashTable.h
getRegTy
static MVT::SimpleValueType getRegTy(unsigned Reg, MachineFunction &MF)
Return type of register Reg.
Definition: MipsOptimizePICCall.cpp:137
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
llvm::ScopedHashTable
Definition: ScopedHashTable.h:43
eraseGPOpnd
static void eraseGPOpnd(MachineInstr &MI)
Search MI's operands for register GP and erase it.
Definition: MipsOptimizePICCall.cpp:162
llvm::MachineRegisterInfo::getRegClass
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
Definition: MachineRegisterInfo.h:634
llvm::MipsII::MO_GOT_CALL
@ MO_GOT_CALL
MO_GOT_CALL - Represents the offset into the global offset table at which the address of a call site ...
Definition: MipsBaseInfo.h:44
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:558
llvm::cl::opt< bool >
LoadTargetFromGOT
static cl::opt< bool > LoadTargetFromGOT("mips-load-target-from-got", cl::init(true), cl::desc("Load target address from GOT"), cl::Hidden)
llvm::MachineOperand::getTargetFlags
unsigned getTargetFlags() const
Definition: MachineOperand.h:221
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition: MachineOperand.h:321
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
MachineFunctionPass.h
llvm::Register::isVirtualRegister
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:71
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition: MachineBasicBlock.h:225
PointerUnion.h
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:97
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:360
llvm::MachineFunction
Definition: MachineFunction.h:230
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
MBBI
MachineBasicBlock MachineBasicBlock::iterator MBBI
Definition: AArch64SLSHardening.cpp:75
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
TargetSubtargetInfo.h
llvm::MipsSubtarget
Definition: MipsSubtarget.h:39
getCallTargetRegOpnd
static MachineOperand * getCallTargetRegOpnd(MachineInstr &MI)
Return the first MachineOperand of MI if it is a used virtual register.
Definition: MipsOptimizePICCall.cpp:124
llvm::DomTreeNodeBase
Base class for the actual dominator tree node.
Definition: LiveIntervalCalc.h:24
llvm::ValueType
PointerUnion< const Value *, const PseudoSourceValue * > ValueType
Definition: ScheduleDAGInstrs.h:106
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::PointerUnion< const Value *, const PseudoSourceValue * >
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::RecyclingAllocator
RecyclingAllocator - This class wraps an Allocator, adding the functionality of recycling deleted obj...
Definition: RecyclingAllocator.h:26
llvm::MVT::i32
@ i32
Definition: MachineValueType.h:43
RecyclingAllocator.h
SmallVector.h
setCallTargetReg
static void setCallTargetReg(MachineBasicBlock *MBB, MachineBasicBlock::iterator I)
Do the following transformation:
Definition: MipsOptimizePICCall.cpp:150
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:268
MachineInstrBuilder.h
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:328
N
#define N
llvm::MachineOperand::setReg
void setReg(Register Reg)
Change the register this operand corresponds to.
Definition: MachineOperand.cpp:55
DefMI
MachineInstrBuilder MachineInstrBuilder & DefMI
Definition: AArch64ExpandPseudoInsts.cpp:103
llvm::MachineInstr::getNumOperands
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:481
MipsSubtarget.h
MachineOperand.h
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
EraseGPOpnd
static cl::opt< bool > EraseGPOpnd("mips-erase-gp-opnd", cl::init(true), cl::desc("Erase GP Operand"), cl::Hidden)
llvm::cl::desc
Definition: CommandLine.h:414
llvm::MipsII::MO_CALL_LO16
@ MO_CALL_LO16
Definition: MipsBaseInfo.h:92
llvm::MachineDominatorTree
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
Definition: MachineDominators.h:45
MachineFunction.h
llvm::MachineInstrBundleIterator< MachineInstr >
TargetRegisterInfo.h
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:270
getReg
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
Definition: MipsDisassembler.cpp:580
MachineDominators.h
llvm::TargetRegisterInfo::legalclasstypes_begin
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.
Definition: TargetRegisterInfo.h:313
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38