LLVM 24.0.0git
RISCVPostRAExpandPseudoInsts.cpp
Go to the documentation of this file.
1//===-- RISCVPostRAExpandPseudoInsts.cpp - Expand pseudo instrs ----===//
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 one of the several passes that expand pseudo instructions
10// into target instructions. This pass is run after register allocation and
11// before post RA scheduling.
12//
13//===----------------------------------------------------------------------===//
14
15#include "RISCV.h"
17#include "RISCVInstrInfo.h"
18#include "RISCVSubtarget.h"
21
22using namespace llvm;
23
24#define RISCV_POST_RA_EXPAND_PSEUDO_NAME \
25 "RISC-V post-regalloc pseudo instruction expansion pass"
26
27namespace {
28
29class RISCVPostRAExpandPseudoImpl final : public RISCVExpandPseudoImplBase {
31 MachineBasicBlock::iterator &NextMBBI) const override;
32
33 bool expandMovImm(MachineBasicBlock &MBB,
35
36 bool expandMovAddr(MachineBasicBlock &MBB,
38
39 bool expandMERGE(MachineBasicBlock &MBB,
41
42 bool expandAddUpperImm(MachineBasicBlock &MBB,
44};
45
46class RISCVPostRAExpandPseudoLegacy : public MachineFunctionPass {
47public:
48 static char ID;
49
50 RISCVPostRAExpandPseudoLegacy() : MachineFunctionPass(ID) {}
51
52 bool runOnMachineFunction(MachineFunction &MF) override {
53 return RISCVPostRAExpandPseudoImpl().run(MF);
54 }
55
56 void getAnalysisUsage(AnalysisUsage &AU) const override {
57 AU.setPreservesCFG();
59 }
60
61 StringRef getPassName() const override {
63 }
64};
65
66} // anonymous namespace
67
68bool RISCVPostRAExpandPseudoImpl::expandMI(
70 MachineBasicBlock::iterator &NextMBBI) const {
71 switch (MBBI->getOpcode()) {
72 case RISCV::PseudoMovImm:
73 return expandMovImm(MBB, MBBI);
74 case RISCV::PseudoMovAddr:
75 return expandMovAddr(MBB, MBBI);
76 case RISCV::PseudoAddUpperImm:
77 return expandAddUpperImm(MBB, MBBI);
78 case RISCV::PseudoMERGE:
79 return expandMERGE(MBB, MBBI);
80 }
81
82 return false;
83}
84
85bool RISCVPostRAExpandPseudoImpl::expandMovImm(
86 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const {
87 DebugLoc DL = MBBI->getDebugLoc();
88
89 int64_t Val = MBBI->getOperand(1).getImm();
90
91 Register DstReg = MBBI->getOperand(0).getReg();
92 bool DstIsDead = MBBI->getOperand(0).isDead();
93 bool Renamable = MBBI->getOperand(0).isRenamable();
94
95 TII->movImm(MBB, MBBI, DL, DstReg, Val, MachineInstr::NoFlags, Renamable,
96 DstIsDead);
97
99 return true;
100}
101
102bool RISCVPostRAExpandPseudoImpl::expandMovAddr(
103 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const {
104 DebugLoc DL = MBBI->getDebugLoc();
105
106 Register DstReg = MBBI->getOperand(0).getReg();
107 bool DstIsDead = MBBI->getOperand(0).isDead();
108 bool Renamable = MBBI->getOperand(0).isRenamable();
109
110 BuildMI(MBB, MBBI, DL, TII->get(RISCV::LUI))
111 .addReg(DstReg, RegState::Define | getRenamableRegState(Renamable))
112 .add(MBBI->getOperand(1));
113 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI))
114 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead) |
116 .addReg(DstReg, RegState::Kill | getRenamableRegState(Renamable))
117 .add(MBBI->getOperand(2));
119 return true;
120}
121
122bool RISCVPostRAExpandPseudoImpl::expandAddUpperImm(
123 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const {
124 DebugLoc DL = MBBI->getDebugLoc();
125
126 Register DstReg = MBBI->getOperand(0).getReg();
127 bool DstIsDead = MBBI->getOperand(0).isDead();
128 bool Renamable = MBBI->getOperand(0).isRenamable();
129 Register BaseReg = MBBI->getOperand(1).getReg();
130 int64_t Hi = MBBI->getOperand(2).getImm();
131
132 // Expand to LUI+ADD: the immediate is already the upper 20-bit value.
133 BuildMI(MBB, MBBI, DL, TII->get(RISCV::LUI))
134 .addReg(DstReg, RegState::Define | getRenamableRegState(Renamable))
135 .addImm(Hi);
136 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADD))
137 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead) |
139 .addReg(BaseReg)
140 .addReg(DstReg, RegState::Kill | getRenamableRegState(Renamable));
141
143 return true;
144}
145
146/// Transfer implicit operands on the pseudo instruction to the
147/// instructions created from the expansion.
149 const MCInstrDesc &Desc = OldMI.getDesc();
150 for (const MachineOperand &MO :
151 llvm::drop_begin(OldMI.operands(), Desc.getNumOperands())) {
152 assert(MO.isReg() && MO.getReg());
153 MI.add(MO);
154 }
155}
156
157// Expand PseudoMERGE to MERGE, MVM, or MVMN.
158bool RISCVPostRAExpandPseudoImpl::expandMERGE(
159 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const {
160 MachineInstr &MI = *MBBI;
161 DebugLoc DL = MI.getDebugLoc();
162
163 Register DstReg = MI.getOperand(0).getReg();
164 if (DstReg == MI.getOperand(3).getReg()) {
165 // Expand to MVMN
166 auto I = BuildMI(MBB, MBBI, DL, TII->get(RISCV::MVMN))
167 .add(MI.getOperand(0))
168 .add(MI.getOperand(3))
169 .add(MI.getOperand(2))
170 .add(MI.getOperand(1));
172 } else if (DstReg == MBBI->getOperand(2).getReg()) {
173 // Expand to MVM
174 auto I = BuildMI(MBB, MBBI, DL, TII->get(RISCV::MVM))
175 .add(MI.getOperand(0))
176 .add(MI.getOperand(2))
177 .add(MI.getOperand(3))
178 .add(MI.getOperand(1));
180 } else if (DstReg == MI.getOperand(1).getReg()) {
181 // Expand to MERGE
182 auto I = BuildMI(MBB, MBBI, DL, TII->get(RISCV::MERGE))
183 .add(MI.getOperand(0))
184 .add(MI.getOperand(1))
185 .add(MI.getOperand(2))
186 .add(MI.getOperand(3));
188 } else {
189 // Use an additional move.
191 getRenamableRegState(MI.getOperand(1).isRenamable()) |
192 getKillRegState(MI.getOperand(1).isKill() &&
193 MI.getOperand(1).getReg() !=
194 MI.getOperand(2).getReg() &&
195 MI.getOperand(1).getReg() != MI.getOperand(3).getReg());
196 BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(RISCV::ADDI))
197 .addDef(DstReg, getRenamableRegState(MI.getOperand(0).isRenamable()))
198 .addReg(MI.getOperand(1).getReg(), RegState)
199 .addImm(0);
200 auto I = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(RISCV::MERGE))
201 .add(MI.getOperand(0))
202 .addReg(DstReg,
203 RegState::Kill | getRenamableRegState(
204 MI.getOperand(0).isRenamable()))
205 .add(MI.getOperand(2))
206 .add(MI.getOperand(3));
208 }
209 MI.eraseFromParent();
210 return true;
211}
212
213char RISCVPostRAExpandPseudoLegacy::ID = 0;
214
215INITIALIZE_PASS(RISCVPostRAExpandPseudoLegacy, "riscv-post-ra-expand-pseudo",
217
219 return new RISCVPostRAExpandPseudoLegacy();
220}
221
222PreservedAnalyses
225 bool Changed = RISCVPostRAExpandPseudoImpl().run(MF);
226 if (!Changed)
227 return PreservedAnalyses::all();
228
231 return PA;
232}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
#define RISCV_POST_RA_EXPAND_PSEUDO_NAME
static void transferImpOps(const MachineInstr &OldMI, MachineInstrBuilder &MI)
Transfer implicit operands on the pseudo instruction to the instructions created from the expansion.
Represent the analysis usage information of a pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:275
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
Describe properties that are true of each instruction in the target description file.
LLVM_ABI void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
mop_range operands()
MachineOperand class - Representation of each machine instruction operand.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Changed
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
Definition SFrame.h:77
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:315
FunctionPass * createRISCVPostRAExpandPseudoLegacyPass()
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
RegState
Flags to represent properties of register accesses.
@ Renamable
Register that may be renamed.
constexpr RegState getKillRegState(bool B)
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
constexpr RegState getDeadRegState(bool B)
Op::Description Desc
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
constexpr RegState getRenamableRegState(bool B)