LLVM  12.0.0git
RISCVExpandPseudoInsts.cpp
Go to the documentation of this file.
1 //===-- RISCVExpandPseudoInsts.cpp - Expand pseudo instructions -----------===//
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 file contains a pass that expands pseudo instructions into target
10 // instructions. This pass should be run after register allocation but before
11 // the post-regalloc scheduling pass.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "RISCV.h"
16 #include "RISCVInstrInfo.h"
17 #include "RISCVTargetMachine.h"
18 
22 
23 using namespace llvm;
24 
25 #define RISCV_EXPAND_PSEUDO_NAME "RISCV pseudo instruction expansion pass"
26 
27 namespace {
28 
29 class RISCVExpandPseudo : public MachineFunctionPass {
30 public:
31  const RISCVInstrInfo *TII;
32  static char ID;
33 
34  RISCVExpandPseudo() : MachineFunctionPass(ID) {
36  }
37 
38  bool runOnMachineFunction(MachineFunction &MF) override;
39 
40  StringRef getPassName() const override { return RISCV_EXPAND_PSEUDO_NAME; }
41 
42 private:
43  bool expandMBB(MachineBasicBlock &MBB);
45  MachineBasicBlock::iterator &NextMBBI);
46  bool expandAuipcInstPair(MachineBasicBlock &MBB,
49  unsigned FlagsHi, unsigned SecondOpcode);
50  bool expandLoadLocalAddress(MachineBasicBlock &MBB,
52  MachineBasicBlock::iterator &NextMBBI);
53  bool expandLoadAddress(MachineBasicBlock &MBB,
55  MachineBasicBlock::iterator &NextMBBI);
56  bool expandLoadTLSIEAddress(MachineBasicBlock &MBB,
58  MachineBasicBlock::iterator &NextMBBI);
59  bool expandLoadTLSGDAddress(MachineBasicBlock &MBB,
61  MachineBasicBlock::iterator &NextMBBI);
62 };
63 
64 char RISCVExpandPseudo::ID = 0;
65 
66 bool RISCVExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
67  TII = static_cast<const RISCVInstrInfo *>(MF.getSubtarget().getInstrInfo());
68  bool Modified = false;
69  for (auto &MBB : MF)
70  Modified |= expandMBB(MBB);
71  return Modified;
72 }
73 
74 bool RISCVExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
75  bool Modified = false;
76 
77  MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
78  while (MBBI != E) {
79  MachineBasicBlock::iterator NMBBI = std::next(MBBI);
80  Modified |= expandMI(MBB, MBBI, NMBBI);
81  MBBI = NMBBI;
82  }
83 
84  return Modified;
85 }
86 
87 bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB,
89  MachineBasicBlock::iterator &NextMBBI) {
90  // RISCVInstrInfo::getInstSizeInBytes hard-codes the number of expanded
91  // instructions for each pseudo, and must be updated when adding new pseudos
92  // or changing existing ones.
93  switch (MBBI->getOpcode()) {
94  case RISCV::PseudoLLA:
95  return expandLoadLocalAddress(MBB, MBBI, NextMBBI);
96  case RISCV::PseudoLA:
97  return expandLoadAddress(MBB, MBBI, NextMBBI);
98  case RISCV::PseudoLA_TLS_IE:
99  return expandLoadTLSIEAddress(MBB, MBBI, NextMBBI);
100  case RISCV::PseudoLA_TLS_GD:
101  return expandLoadTLSGDAddress(MBB, MBBI, NextMBBI);
102  }
103 
104  return false;
105 }
106 
107 bool RISCVExpandPseudo::expandAuipcInstPair(
109  MachineBasicBlock::iterator &NextMBBI, unsigned FlagsHi,
110  unsigned SecondOpcode) {
111  MachineFunction *MF = MBB.getParent();
112  MachineInstr &MI = *MBBI;
113  DebugLoc DL = MI.getDebugLoc();
114 
115  Register DestReg = MI.getOperand(0).getReg();
116  const MachineOperand &Symbol = MI.getOperand(1);
117 
119 
120  // Tell AsmPrinter that we unconditionally want the symbol of this label to be
121  // emitted.
122  NewMBB->setLabelMustBeEmitted();
123 
124  MF->insert(++MBB.getIterator(), NewMBB);
125 
126  BuildMI(NewMBB, DL, TII->get(RISCV::AUIPC), DestReg)
127  .addDisp(Symbol, 0, FlagsHi);
128  BuildMI(NewMBB, DL, TII->get(SecondOpcode), DestReg)
129  .addReg(DestReg)
130  .addMBB(NewMBB, RISCVII::MO_PCREL_LO);
131 
132  // Move all the rest of the instructions to NewMBB.
133  NewMBB->splice(NewMBB->end(), &MBB, std::next(MBBI), MBB.end());
134  // Update machine-CFG edges.
135  NewMBB->transferSuccessorsAndUpdatePHIs(&MBB);
136  // Make the original basic block fall-through to the new.
137  MBB.addSuccessor(NewMBB);
138 
139  // Make sure live-ins are correctly attached to this new basic block.
140  LivePhysRegs LiveRegs;
141  computeAndAddLiveIns(LiveRegs, *NewMBB);
142 
143  NextMBBI = MBB.end();
144  MI.eraseFromParent();
145  return true;
146 }
147 
148 bool RISCVExpandPseudo::expandLoadLocalAddress(
150  MachineBasicBlock::iterator &NextMBBI) {
151  return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_PCREL_HI,
152  RISCV::ADDI);
153 }
154 
155 bool RISCVExpandPseudo::expandLoadAddress(
157  MachineBasicBlock::iterator &NextMBBI) {
158  MachineFunction *MF = MBB.getParent();
159 
160  unsigned SecondOpcode;
161  unsigned FlagsHi;
162  if (MF->getTarget().isPositionIndependent()) {
163  const auto &STI = MF->getSubtarget<RISCVSubtarget>();
164  SecondOpcode = STI.is64Bit() ? RISCV::LD : RISCV::LW;
165  FlagsHi = RISCVII::MO_GOT_HI;
166  } else {
167  SecondOpcode = RISCV::ADDI;
168  FlagsHi = RISCVII::MO_PCREL_HI;
169  }
170  return expandAuipcInstPair(MBB, MBBI, NextMBBI, FlagsHi, SecondOpcode);
171 }
172 
173 bool RISCVExpandPseudo::expandLoadTLSIEAddress(
175  MachineBasicBlock::iterator &NextMBBI) {
176  MachineFunction *MF = MBB.getParent();
177 
178  const auto &STI = MF->getSubtarget<RISCVSubtarget>();
179  unsigned SecondOpcode = STI.is64Bit() ? RISCV::LD : RISCV::LW;
180  return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_TLS_GOT_HI,
181  SecondOpcode);
182 }
183 
184 bool RISCVExpandPseudo::expandLoadTLSGDAddress(
186  MachineBasicBlock::iterator &NextMBBI) {
187  return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_TLS_GD_HI,
188  RISCV::ADDI);
189 }
190 
191 } // end of anonymous namespace
192 
193 INITIALIZE_PASS(RISCVExpandPseudo, "riscv-expand-pseudo",
194  RISCV_EXPAND_PSEUDO_NAME, false, false)
195 namespace llvm {
196 
197 FunctionPass *createRISCVExpandPseudoPass() { return new RISCVExpandPseudo(); }
198 
199 } // end of namespace llvm
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents lattice values for constants.
Definition: AllocatorList.h:23
void initializeRISCVExpandPseudoPass(PassRegistry &)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:409
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
A debug info location.
Definition: DebugLoc.h:33
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
MachineBasicBlock & MBB
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
void eraseFromParent()
Unlink &#39;this&#39; from the containing basic block and delete it.
virtual const TargetInstrInfo * getInstrInfo() const
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
self_iterator getIterator()
Definition: ilist_node.h:81
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void setLabelMustBeEmitted()
Set this block to reflect that, regardless how we flow to it, we need its label be emitted...
MachineOperand class - Representation of each machine instruction operand.
void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().
INITIALIZE_PASS(RISCVExpandPseudo, "riscv-expand-pseudo", RISCV_EXPAND_PSEUDO_NAME, false, false) namespace llvm
Representation of each machine instruction.
Definition: MachineInstr.h:62
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB &#39;Other&#39; at the position From, and insert it into this MBB right before &#39;...
A set of physical registers with utility functions to track liveness when walking backward/forward th...
Definition: LivePhysRegs.h:48
bool isPositionIndependent() const
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
#define RISCV_EXPAND_PSEUDO_NAME
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
FunctionPass * createRISCVExpandPseudoPass()
void insert(iterator MBBI, MachineBasicBlock *MBB)
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
Register getReg() const
getReg - Returns the register number.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:466
MachineBasicBlock MachineBasicBlock::iterator MBBI
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL