26#define RISCV_EXPAND_PSEUDO_NAME "RISC-V pseudo instruction expansion pass"
27#define RISCV_PRERA_EXPAND_PSEUDO_NAME "RISC-V Pre-RA pseudo instruction expansion pass"
76char RISCVExpandPseudo::ID = 0;
92 assert(OldSize >= NewSize);
116 switch (
MBBI->getOpcode()) {
117 case RISCV::PseudoMV_FPR16INX:
118 return expandMV_FPR16INX(
MBB,
MBBI);
119 case RISCV::PseudoMV_FPR32INX:
120 return expandMV_FPR32INX(
MBB,
MBBI);
121 case RISCV::PseudoRV32ZdinxSD:
122 return expandRV32ZdinxStore(
MBB,
MBBI);
123 case RISCV::PseudoRV32ZdinxLD:
124 return expandRV32ZdinxLoad(
MBB,
MBBI);
125 case RISCV::PseudoCCMOVGPRNoX0:
126 case RISCV::PseudoCCMOVGPR:
127 case RISCV::PseudoCCADD:
128 case RISCV::PseudoCCSUB:
129 case RISCV::PseudoCCAND:
130 case RISCV::PseudoCCOR:
131 case RISCV::PseudoCCXOR:
132 case RISCV::PseudoCCMAX:
133 case RISCV::PseudoCCMAXU:
134 case RISCV::PseudoCCMIN:
135 case RISCV::PseudoCCMINU:
136 case RISCV::PseudoCCMUL:
137 case RISCV::PseudoCCLUI:
138 case RISCV::PseudoCCQC_E_LB:
139 case RISCV::PseudoCCQC_E_LH:
140 case RISCV::PseudoCCQC_E_LW:
141 case RISCV::PseudoCCQC_E_LHU:
142 case RISCV::PseudoCCQC_E_LBU:
143 case RISCV::PseudoCCLB:
144 case RISCV::PseudoCCLH:
145 case RISCV::PseudoCCLW:
146 case RISCV::PseudoCCLHU:
147 case RISCV::PseudoCCLBU:
148 case RISCV::PseudoCCLWU:
149 case RISCV::PseudoCCLD:
150 case RISCV::PseudoCCQC_LI:
151 case RISCV::PseudoCCQC_E_LI:
152 case RISCV::PseudoCCADDW:
153 case RISCV::PseudoCCSUBW:
154 case RISCV::PseudoCCSLL:
155 case RISCV::PseudoCCSRL:
156 case RISCV::PseudoCCSRA:
157 case RISCV::PseudoCCADDI:
158 case RISCV::PseudoCCSLLI:
159 case RISCV::PseudoCCSRLI:
160 case RISCV::PseudoCCSRAI:
161 case RISCV::PseudoCCANDI:
162 case RISCV::PseudoCCORI:
163 case RISCV::PseudoCCXORI:
164 case RISCV::PseudoCCSLLW:
165 case RISCV::PseudoCCSRLW:
166 case RISCV::PseudoCCSRAW:
167 case RISCV::PseudoCCADDIW:
168 case RISCV::PseudoCCSLLIW:
169 case RISCV::PseudoCCSRLIW:
170 case RISCV::PseudoCCSRAIW:
171 case RISCV::PseudoCCANDN:
172 case RISCV::PseudoCCORN:
173 case RISCV::PseudoCCXNOR:
174 case RISCV::PseudoCCNDS_BFOS:
175 case RISCV::PseudoCCNDS_BFOZ:
176 return expandCCOp(
MBB,
MBBI, NextMBBI);
177 case RISCV::PseudoVMCLR_M_B1:
178 case RISCV::PseudoVMCLR_M_B2:
179 case RISCV::PseudoVMCLR_M_B4:
180 case RISCV::PseudoVMCLR_M_B8:
181 case RISCV::PseudoVMCLR_M_B16:
182 case RISCV::PseudoVMCLR_M_B32:
183 case RISCV::PseudoVMCLR_M_B64:
185 return expandVMSET_VMCLR(
MBB,
MBBI, RISCV::VMXOR_MM);
186 case RISCV::PseudoVMSET_M_B1:
187 case RISCV::PseudoVMSET_M_B2:
188 case RISCV::PseudoVMSET_M_B4:
189 case RISCV::PseudoVMSET_M_B8:
190 case RISCV::PseudoVMSET_M_B16:
191 case RISCV::PseudoVMSET_M_B32:
192 case RISCV::PseudoVMSET_M_B64:
194 return expandVMSET_VMCLR(
MBB,
MBBI, RISCV::VMXNOR_MM);
195 case RISCV::PseudoReadVLENBViaVSETVLIX0:
196 return expandPseudoReadVLENBViaVSETVLIX0(
MBB,
MBBI);
197 case RISCV::PseudoClearFPR64:
198 return expandPseudoClearFPR64(
MBB,
MBBI);
208 if (expandCCOpToCMov(
MBB,
MBBI))
223 unsigned BranchOpCode =
224 MI.getOperand(
MI.getNumExplicitOperands() - 3).getImm();
228 .
add(
MI.getOperand(
MI.getNumExplicitOperands() - 2))
229 .
add(
MI.getOperand(
MI.getNumExplicitOperands() - 1))
233 assert(
MI.getOperand(1).getReg() == DestReg);
235 if (
MI.getOpcode() == RISCV::PseudoCCMOVGPR ||
236 MI.getOpcode() == RISCV::PseudoCCMOVGPRNoX0) {
239 .
add(
MI.getOperand(2))
244 switch (
MI.getOpcode()) {
247 case RISCV::PseudoCCADD: NewOpc = RISCV::ADD;
break;
248 case RISCV::PseudoCCSUB: NewOpc = RISCV::SUB;
break;
249 case RISCV::PseudoCCSLL: NewOpc = RISCV::SLL;
break;
250 case RISCV::PseudoCCSRL: NewOpc = RISCV::SRL;
break;
251 case RISCV::PseudoCCSRA: NewOpc = RISCV::SRA;
break;
252 case RISCV::PseudoCCAND: NewOpc = RISCV::AND;
break;
253 case RISCV::PseudoCCOR: NewOpc = RISCV::OR;
break;
254 case RISCV::PseudoCCXOR: NewOpc = RISCV::XOR;
break;
255 case RISCV::PseudoCCMAX: NewOpc = RISCV::MAX;
break;
256 case RISCV::PseudoCCMIN: NewOpc = RISCV::MIN;
break;
257 case RISCV::PseudoCCMAXU: NewOpc = RISCV::MAXU;
break;
258 case RISCV::PseudoCCMINU: NewOpc = RISCV::MINU;
break;
259 case RISCV::PseudoCCMUL: NewOpc = RISCV::MUL;
break;
260 case RISCV::PseudoCCLUI: NewOpc = RISCV::LUI;
break;
261 case RISCV::PseudoCCQC_E_LB: NewOpc = RISCV::QC_E_LB;
break;
262 case RISCV::PseudoCCQC_E_LH: NewOpc = RISCV::QC_E_LH;
break;
263 case RISCV::PseudoCCQC_E_LW: NewOpc = RISCV::QC_E_LW;
break;
264 case RISCV::PseudoCCQC_E_LHU: NewOpc = RISCV::QC_E_LHU;
break;
265 case RISCV::PseudoCCQC_E_LBU: NewOpc = RISCV::QC_E_LBU;
break;
266 case RISCV::PseudoCCLB: NewOpc = RISCV::LB;
break;
267 case RISCV::PseudoCCLH: NewOpc = RISCV::LH;
break;
268 case RISCV::PseudoCCLW: NewOpc = RISCV::LW;
break;
269 case RISCV::PseudoCCLHU: NewOpc = RISCV::LHU;
break;
270 case RISCV::PseudoCCLBU: NewOpc = RISCV::LBU;
break;
271 case RISCV::PseudoCCLWU: NewOpc = RISCV::LWU;
break;
272 case RISCV::PseudoCCLD: NewOpc = RISCV::LD;
break;
273 case RISCV::PseudoCCQC_LI: NewOpc = RISCV::QC_LI;
break;
274 case RISCV::PseudoCCQC_E_LI: NewOpc = RISCV::QC_E_LI;
break;
275 case RISCV::PseudoCCADDI: NewOpc = RISCV::ADDI;
break;
276 case RISCV::PseudoCCSLLI: NewOpc = RISCV::SLLI;
break;
277 case RISCV::PseudoCCSRLI: NewOpc = RISCV::SRLI;
break;
278 case RISCV::PseudoCCSRAI: NewOpc = RISCV::SRAI;
break;
279 case RISCV::PseudoCCANDI: NewOpc = RISCV::ANDI;
break;
280 case RISCV::PseudoCCORI: NewOpc = RISCV::ORI;
break;
281 case RISCV::PseudoCCXORI: NewOpc = RISCV::XORI;
break;
282 case RISCV::PseudoCCADDW: NewOpc = RISCV::ADDW;
break;
283 case RISCV::PseudoCCSUBW: NewOpc = RISCV::SUBW;
break;
284 case RISCV::PseudoCCSLLW: NewOpc = RISCV::SLLW;
break;
285 case RISCV::PseudoCCSRLW: NewOpc = RISCV::SRLW;
break;
286 case RISCV::PseudoCCSRAW: NewOpc = RISCV::SRAW;
break;
287 case RISCV::PseudoCCADDIW: NewOpc = RISCV::ADDIW;
break;
288 case RISCV::PseudoCCSLLIW: NewOpc = RISCV::SLLIW;
break;
289 case RISCV::PseudoCCSRLIW: NewOpc = RISCV::SRLIW;
break;
290 case RISCV::PseudoCCSRAIW: NewOpc = RISCV::SRAIW;
break;
291 case RISCV::PseudoCCANDN: NewOpc = RISCV::ANDN;
break;
292 case RISCV::PseudoCCORN: NewOpc = RISCV::ORN;
break;
293 case RISCV::PseudoCCXNOR: NewOpc = RISCV::XNOR;
break;
294 case RISCV::PseudoCCNDS_BFOS: NewOpc = RISCV::NDS_BFOS;
break;
295 case RISCV::PseudoCCNDS_BFOZ: NewOpc = RISCV::NDS_BFOZ;
break;
299 if (NewOpc == RISCV::NDS_BFOZ || NewOpc == RISCV::NDS_BFOS) {
301 .
add(
MI.getOperand(2))
302 .
add(
MI.getOperand(3))
303 .
add(
MI.getOperand(4));
304 }
else if (NewOpc == RISCV::LUI || NewOpc == RISCV::QC_LI ||
305 NewOpc == RISCV::QC_E_LI) {
309 .
add(
MI.getOperand(2))
310 .
add(
MI.getOperand(3));
319 MBB.addSuccessor(TrueBB);
320 MBB.addSuccessor(MergeBB);
322 NextMBBI =
MBB.end();
323 MI.eraseFromParent();
338 if (
MI.getOpcode() != RISCV::PseudoCCMOVGPR &&
339 MI.getOpcode() != RISCV::PseudoCCMOVGPRNoX0)
342 if (!STI->hasVendorXqcicm())
349 if (
LHS.getReg() == RISCV::X0 ||
MI.getOperand(1).getReg() == RISCV::X0 ||
350 MI.getOperand(2).getReg() == RISCV::X0)
354 unsigned BCC =
MI.getOperand(
MI.getNumExplicitOperands() - 3).getImm();
355 std::optional<unsigned> CMovRegOpcode;
356 unsigned CMovImmOpcode;
361 CMovRegOpcode = RISCV::QC_MVEQ;
362 CMovImmOpcode = RISCV::QC_MVEQI;
365 CMovRegOpcode = RISCV::QC_MVNE;
366 CMovImmOpcode = RISCV::QC_MVNEI;
369 CMovRegOpcode = RISCV::QC_MVLT;
370 CMovImmOpcode = RISCV::QC_MVLTI;
373 CMovRegOpcode = RISCV::QC_MVGE;
374 CMovImmOpcode = RISCV::QC_MVGEI;
377 CMovRegOpcode = RISCV::QC_MVLTU;
378 CMovImmOpcode = RISCV::QC_MVLTUI;
381 CMovRegOpcode = RISCV::QC_MVGEU;
382 CMovImmOpcode = RISCV::QC_MVGEUI;
385 CMovImmOpcode = RISCV::QC_MVEQI;
388 CMovImmOpcode = RISCV::QC_MVNEI;
391 CMovImmOpcode = RISCV::QC_MVLTI;
394 CMovImmOpcode = RISCV::QC_MVGEI;
396 case RISCV::QC_BLTUI:
397 CMovImmOpcode = RISCV::QC_MVLTUI;
399 case RISCV::QC_BGEUI:
400 CMovImmOpcode = RISCV::QC_MVGEUI;
416 MI.eraseFromParent();
420 if (
RHS.getReg() == RISCV::X0) {
432 MI.eraseFromParent();
449 MI.eraseFromParent();
462 MBBI->eraseFromParent();
471 MBBI->getOperand(0).getReg(), RISCV::sub_16, &RISCV::GPRRegClass);
473 MBBI->getOperand(1).getReg(), RISCV::sub_16, &RISCV::GPRRegClass);
479 MBBI->eraseFromParent();
488 MBBI->getOperand(0).getReg(), RISCV::sub_32, &RISCV::GPRRegClass);
490 MBBI->getOperand(1).getReg(), RISCV::sub_32, &RISCV::GPRRegClass);
496 MBBI->eraseFromParent();
508 TRI->getSubReg(
MBBI->getOperand(0).getReg(), RISCV::sub_gpr_even);
510 TRI->getSubReg(
MBBI->getOperand(0).getReg(), RISCV::sub_gpr_odd);
511 if (
Hi == RISCV::DUMMY_REG_PAIR_WITH_X0)
520 if (
MBBI->getOperand(2).isGlobal() ||
MBBI->getOperand(2).isCPI()) {
521 assert(
MBBI->getOperand(2).getOffset() % 8 == 0);
522 MBBI->getOperand(2).setOffset(
MBBI->getOperand(2).getOffset() + 4);
542 MIBLo.setMemRefs(NewLoMMOs);
545 MBBI->eraseFromParent();
557 TRI->getSubReg(
MBBI->getOperand(0).getReg(), RISCV::sub_gpr_even);
559 TRI->getSubReg(
MBBI->getOperand(0).getReg(), RISCV::sub_gpr_odd);
560 assert(
Hi != RISCV::DUMMY_REG_PAIR_WITH_X0 &&
"Cannot write to X0_Pair");
566 bool IsOp1EqualToLo =
Lo ==
MBBI->getOperand(1).getReg();
568 if (!IsOp1EqualToLo) {
574 if (
MBBI->getOperand(2).isGlobal() ||
MBBI->getOperand(2).isCPI()) {
575 auto Offset =
MBBI->getOperand(2).getOffset();
590 if (IsOp1EqualToLo) {
606 MBBI->eraseFromParent();
610bool RISCVExpandPseudo::expandPseudoReadVLENBViaVSETVLIX0(
614 unsigned Mul =
MBBI->getOperand(1).getImm();
617 VLMUL, 8,
true,
true);
624 MBBI->eraseFromParent();
628bool RISCVExpandPseudo::expandPseudoClearFPR64(
641 MBBI->eraseFromParent();
670 unsigned FlagsHi,
unsigned SecondOpcode);
698char RISCVPreRAExpandPseudo::ID = 0;
700bool RISCVPreRAExpandPseudo::runOnMachineFunction(
MachineFunction &MF) {
714 assert(OldSize >= NewSize);
736 switch (
MBBI->getOpcode()) {
737 case RISCV::PseudoLLA:
738 return expandLoadLocalAddress(
MBB,
MBBI, NextMBBI);
739 case RISCV::PseudoLGA:
740 return expandLoadGlobalAddress(
MBB,
MBBI, NextMBBI);
741 case RISCV::PseudoLA_TLS_IE:
742 return expandLoadTLSIEAddress(
MBB,
MBBI, NextMBBI);
743 case RISCV::PseudoLA_TLS_GD:
744 return expandLoadTLSGDAddress(
MBB,
MBBI, NextMBBI);
745 case RISCV::PseudoLA_TLSDESC:
746 return expandLoadTLSDescAddress(
MBB,
MBBI, NextMBBI);
751bool RISCVPreRAExpandPseudo::expandAuipcInstPair(
754 unsigned SecondOpcode) {
764 Symbol.setTargetFlags(FlagsHi);
776 if (
MI.hasOneMemOperand())
779 MI.eraseFromParent();
783bool RISCVPreRAExpandPseudo::expandLoadLocalAddress(
790bool RISCVPreRAExpandPseudo::expandLoadGlobalAddress(
793 unsigned SecondOpcode = STI->
is64Bit() ? RISCV::LD : RISCV::LW;
798bool RISCVPreRAExpandPseudo::expandLoadTLSIEAddress(
801 unsigned SecondOpcode = STI->
is64Bit() ? RISCV::LD : RISCV::LW;
806bool RISCVPreRAExpandPseudo::expandLoadTLSGDAddress(
813bool RISCVPreRAExpandPseudo::expandLoadTLSDescAddress(
821 unsigned SecondOpcode = STI.
is64Bit() ? RISCV::LD : RISCV::LW;
823 Register FinalReg =
MI.getOperand(0).getReg();
854 MI.eraseFromParent();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
Register const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
#define RISCV_PRERA_EXPAND_PSEUDO_NAME
#define RISCV_EXPAND_PSEUDO_NAME
static unsigned getInstSizeInBytes(const MachineInstr &MI, const SystemZInstrInfo *TII)
Represent the analysis usage information of a pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
FunctionPass class - This class is used to implement most global optimizations.
A set of physical registers with utility functions to track liveness when walking backward/forward th...
LLVM_ABI MCSymbol * createNamedTempSymbol()
Create a temporary symbol with a unique name whose name cannot be omitted in the symbol table.
Describe properties that are true of each instruction in the target description file.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
LLVM_ABI void transferSuccessors(MachineBasicBlock *FromMBB)
Transfers all the successors from MBB to this machine basic block (i.e., copies all the successors Fr...
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
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 TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
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 & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
LLVM_ABI void setPreInstrSymbol(MachineFunction &MF, MCSymbol *Symbol)
Set a symbol that will be emitted just prior to the instruction itself.
LLVM_ABI void addMemOperand(MachineFunction &MF, MachineMemOperand *MO)
Add a MachineMemOperand to the machine instruction.
A description of a memory reference used in the backend.
MachineOperand class - Representation of each machine instruction operand.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
const RISCVRegisterInfo * getRegisterInfo() const override
const RISCVInstrInfo * getInstrInfo() const override
Wrapper class representing virtual and physical registers.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
static VLMUL encodeLMUL(unsigned LMUL, bool Fractional)
LLVM_ABI unsigned encodeVTYPE(VLMUL VLMUL, unsigned SEW, bool TailAgnostic, bool MaskAgnostic, bool AltFmt=false)
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
@ Define
Register definition.
constexpr RegState getKillRegState(bool B)
LLVM_ABI void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().
FunctionPass * createRISCVExpandPseudoPass()
FunctionPass * createRISCVPreRAExpandPseudoPass()