26 #define RISCV_EXPAND_PSEUDO_NAME "RISCV pseudo instruction expansion pass" 49 bool IsMasked,
int Width,
66 Modified |= expandMBB(MBB);
76 Modified |= expandMI(MBB, MBBI, NMBBI);
86 switch (MBBI->getOpcode()) {
87 case RISCV::PseudoAtomicLoadNand32:
90 case RISCV::PseudoMaskedAtomicSwap32:
93 case RISCV::PseudoMaskedAtomicLoadAdd32:
95 case RISCV::PseudoMaskedAtomicLoadSub32:
97 case RISCV::PseudoMaskedAtomicLoadNand32:
100 case RISCV::PseudoMaskedAtomicLoadMax32:
103 case RISCV::PseudoMaskedAtomicLoadMin32:
106 case RISCV::PseudoMaskedAtomicLoadUMax32:
109 case RISCV::PseudoMaskedAtomicLoadUMin32:
112 case RISCV::PseudoCmpXchg32:
113 return expandAtomicCmpXchg(MBB, MBBI,
false, 32, NextMBBI);
114 case RISCV::PseudoMaskedCmpXchg32:
115 return expandAtomicCmpXchg(MBB, MBBI,
true, 32, NextMBBI);
128 return RISCV::LR_W_AQ;
132 return RISCV::LR_W_AQ;
134 return RISCV::LR_W_AQ_RL;
147 return RISCV::SC_W_RL;
149 return RISCV::SC_W_RL;
151 return RISCV::SC_W_AQ_RL;
160 assert(Width == 32 &&
"RV64 atomic expansion currently unsupported");
173 BuildMI(LoopMBB, DL, TII->get(getLRForRMW32(Ordering)), DestReg)
182 BuildMI(LoopMBB, DL, TII->get(RISCV::XORI), ScratchReg)
187 BuildMI(LoopMBB, DL, TII->get(getSCForRMW32(Ordering)), ScratchReg)
190 BuildMI(LoopMBB, DL, TII->get(RISCV::BNE))
198 unsigned OldValReg,
unsigned NewValReg,
199 unsigned MaskReg,
unsigned ScratchReg) {
200 assert(OldValReg != ScratchReg &&
"OldValReg and ScratchReg must be unique");
201 assert(OldValReg != MaskReg &&
"OldValReg and MaskReg must be unique");
202 assert(ScratchReg != MaskReg &&
"ScratchReg and MaskReg must be unique");
218 static void doMaskedAtomicBinOpExpansion(
222 assert(Width == 32 &&
"RV64 atomic expansion currently unsupported");
239 BuildMI(LoopMBB, DL, TII->get(getLRForRMW32(Ordering)), DestReg)
263 BuildMI(LoopMBB, DL, TII->get(RISCV::XORI), ScratchReg)
269 insertMaskedMerge(TII, DL, LoopMBB, ScratchReg, DestReg, ScratchReg, MaskReg,
272 BuildMI(LoopMBB, DL, TII->get(getSCForRMW32(Ordering)), ScratchReg)
275 BuildMI(LoopMBB, DL, TII->get(RISCV::BNE))
281 bool RISCVExpandPseudo::expandAtomicBinOp(
304 doAtomicBinOpExpansion(TII, MI, DL, &MBB, LoopMBB, DoneMBB, BinOp, Width);
306 doMaskedAtomicBinOpExpansion(TII, MI, DL, &MBB, LoopMBB, DoneMBB, BinOp,
309 NextMBBI = MBB.
end();
310 MI.eraseFromParent();
322 BuildMI(MBB, DL, TII->get(RISCV::SLL), ValReg)
330 bool RISCVExpandPseudo::expandAtomicMinMaxOp(
334 assert(IsMasked ==
true &&
335 "Should only need to expand masked atomic max/min");
336 assert(Width == 32 &&
"RV64 atomic expansion currently unsupported");
348 MF->
insert(++LoopHeadMBB->getIterator(), LoopIfBodyMBB);
349 MF->
insert(++LoopIfBodyMBB->getIterator(), LoopTailMBB);
350 MF->
insert(++LoopTailMBB->getIterator(), DoneMBB);
353 LoopHeadMBB->addSuccessor(LoopIfBodyMBB);
354 LoopHeadMBB->addSuccessor(LoopTailMBB);
355 LoopIfBodyMBB->addSuccessor(LoopTailMBB);
356 LoopTailMBB->addSuccessor(LoopHeadMBB);
357 LoopTailMBB->addSuccessor(DoneMBB);
362 unsigned DestReg = MI.getOperand(0).getReg();
363 unsigned Scratch1Reg = MI.getOperand(1).getReg();
364 unsigned Scratch2Reg = MI.getOperand(2).getReg();
365 unsigned AddrReg = MI.getOperand(3).getReg();
366 unsigned IncrReg = MI.getOperand(4).getReg();
367 unsigned MaskReg = MI.getOperand(5).getReg();
370 static_cast<AtomicOrdering>(MI.getOperand(IsSigned ? 7 : 6).getImm());
379 BuildMI(LoopHeadMBB, DL, TII->get(getLRForRMW32(Ordering)), DestReg)
384 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::ADDI), Scratch1Reg)
392 insertSext(TII, DL, LoopHeadMBB, Scratch2Reg, MI.getOperand(6).getReg());
393 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BGE))
400 insertSext(TII, DL, LoopHeadMBB, Scratch2Reg, MI.getOperand(6).getReg());
401 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BGE))
408 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BGEU))
414 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BGEU))
425 insertMaskedMerge(TII, DL, LoopIfBodyMBB, Scratch1Reg, DestReg, IncrReg,
426 MaskReg, Scratch1Reg);
431 BuildMI(LoopTailMBB, DL, TII->get(getSCForRMW32(Ordering)), Scratch1Reg)
434 BuildMI(LoopTailMBB, DL, TII->get(RISCV::BNE))
439 NextMBBI = MBB.
end();
440 MI.eraseFromParent();
451 bool RISCVExpandPseudo::expandAtomicCmpXchg(
454 assert(Width == 32 &&
"RV64 atomic expansion currently unsupported");
464 MF->
insert(++LoopHeadMBB->getIterator(), LoopTailMBB);
465 MF->
insert(++LoopTailMBB->getIterator(), DoneMBB);
468 LoopHeadMBB->addSuccessor(LoopTailMBB);
469 LoopHeadMBB->addSuccessor(DoneMBB);
470 LoopTailMBB->addSuccessor(DoneMBB);
471 LoopTailMBB->addSuccessor(LoopHeadMBB);
476 unsigned DestReg = MI.getOperand(0).getReg();
477 unsigned ScratchReg = MI.getOperand(1).getReg();
478 unsigned AddrReg = MI.getOperand(2).getReg();
479 unsigned CmpValReg = MI.getOperand(3).getReg();
480 unsigned NewValReg = MI.getOperand(4).getReg();
482 static_cast<AtomicOrdering>(MI.getOperand(IsMasked ? 6 : 5).getImm());
488 BuildMI(LoopHeadMBB, DL, TII->get(getLRForRMW32(Ordering)), DestReg)
490 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BNE))
497 BuildMI(LoopTailMBB, DL, TII->get(getSCForRMW32(Ordering)), ScratchReg)
500 BuildMI(LoopTailMBB, DL, TII->get(RISCV::BNE))
509 unsigned MaskReg = MI.getOperand(5).getReg();
510 BuildMI(LoopHeadMBB, DL, TII->get(getLRForRMW32(Ordering)), DestReg)
515 BuildMI(LoopHeadMBB, DL, TII->get(RISCV::BNE))
526 insertMaskedMerge(TII, DL, LoopTailMBB, ScratchReg, DestReg, NewValReg,
527 MaskReg, ScratchReg);
528 BuildMI(LoopTailMBB, DL, TII->get(getSCForRMW32(Ordering)), ScratchReg)
531 BuildMI(LoopTailMBB, DL, TII->get(RISCV::BNE))
537 NextMBBI = MBB.
end();
538 MI.eraseFromParent();
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
*p = old <signed v ? old : v
This class represents lattice values for constants.
void initializeRISCVExpandPseudoPass(PassRegistry &)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
unsigned getReg() const
getReg - Returns the register number.
void transferSuccessors(MachineBasicBlock *FromMBB)
Transfers all the successors from MBB to this machine basic block (i.e., copies all the successors Fr...
*p = old <unsigned v ? old : v
*p = old >unsigned v ? old : v
*p = old >signed v ? old : v
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
AtomicOrdering
Atomic ordering for LLVM's memory model.
BinOp
This enumeration lists the possible modifications atomicrmw can make.
Simple integer binary arithmetic operators.
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.
self_iterator getIterator()
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
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.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Bitwise operators - logical and, logical or, logical xor.
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 '...
A set of physical registers with utility functions to track liveness when walking backward/forward th...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
#define RISCV_EXPAND_PSEUDO_NAME
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
FunctionPass * createRISCVExpandPseudoPass()
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void insert(iterator MBBI, MachineBasicBlock *MBB)
StringRef - Represent a constant reference to a string, i.e.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
const MachineOperand & getOperand(unsigned i) const