26#define LoongArch_EXPAND_ATOMIC_PSEUDO_NAME \
27 "LoongArch atomic pseudo instruction expansion pass"
52 bool IsMasked,
int Width,
63char LoongArchExpandAtomicPseudo::ID = 0;
65bool LoongArchExpandAtomicPseudo::runOnMachineFunction(
MachineFunction &MF) {
87bool LoongArchExpandAtomicPseudo::expandMI(
90 switch (
MBBI->getOpcode()) {
91 case LoongArch::PseudoMaskedAtomicSwap32:
94 case LoongArch::PseudoAtomicSwap32:
97 case LoongArch::PseudoMaskedAtomicLoadAdd32:
99 case LoongArch::PseudoMaskedAtomicLoadSub32:
101 case LoongArch::PseudoAtomicLoadNand32:
104 case LoongArch::PseudoAtomicLoadNand64:
107 case LoongArch::PseudoMaskedAtomicLoadNand32:
110 case LoongArch::PseudoAtomicLoadAdd32:
113 case LoongArch::PseudoAtomicLoadSub32:
116 case LoongArch::PseudoAtomicLoadAnd32:
119 case LoongArch::PseudoAtomicLoadOr32:
121 case LoongArch::PseudoAtomicLoadXor32:
124 case LoongArch::PseudoMaskedAtomicLoadUMax32:
127 case LoongArch::PseudoMaskedAtomicLoadUMin32:
130 case LoongArch::PseudoCmpXchg32:
131 return expandAtomicCmpXchg(
MBB,
MBBI,
false, 32, NextMBBI);
132 case LoongArch::PseudoCmpXchg64:
133 return expandAtomicCmpXchg(
MBB,
MBBI,
false, 64, NextMBBI);
134 case LoongArch::PseudoMaskedCmpXchg32:
135 return expandAtomicCmpXchg(
MBB,
MBBI,
true, 32, NextMBBI);
136 case LoongArch::PseudoMaskedAtomicLoadMax32:
139 case LoongArch::PseudoMaskedAtomicLoadMin32:
153 Register ScratchReg =
MI.getOperand(1).getReg();
163 TII->get(Width == 32 ? LoongArch::LL_W : LoongArch::LL_D), DestReg)
170 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::OR), ScratchReg)
175 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::AND), ScratchReg)
178 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::NOR), ScratchReg)
183 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::ADD_W), ScratchReg)
188 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::SUB_W), ScratchReg)
193 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::AND), ScratchReg)
198 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::OR), ScratchReg)
203 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::XOR), ScratchReg)
209 TII->get(Width == 32 ? LoongArch::SC_W : LoongArch::SC_D), ScratchReg)
222 assert(OldValReg != ScratchReg &&
"OldValReg and ScratchReg must be unique");
223 assert(OldValReg != MaskReg &&
"OldValReg and MaskReg must be unique");
224 assert(ScratchReg != MaskReg &&
"ScratchReg and MaskReg must be unique");
238static void doMaskedAtomicBinOpExpansion(
242 assert(Width == 32 &&
"Should never need to expand masked 64-bit operations");
244 Register ScratchReg =
MI.getOperand(1).getReg();
257 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::LL_W), DestReg)
264 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::ADDI_W), ScratchReg)
269 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::ADD_W), ScratchReg)
274 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::SUB_W), ScratchReg)
279 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::AND), ScratchReg)
282 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::NOR), ScratchReg)
288 insertMaskedMerge(
TII,
DL, LoopMBB, ScratchReg, DestReg, ScratchReg, MaskReg,
291 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::SC_W), ScratchReg)
300bool LoongArchExpandAtomicPseudo::expandAtomicBinOp(
323 doMaskedAtomicBinOpExpansion(
TII,
MI,
DL, &
MBB, LoopMBB, DoneMBB, BinOp,
326 doAtomicBinOpExpansion(
TII,
MI,
DL, &
MBB, LoopMBB, DoneMBB, BinOp, Width);
329 MI.eraseFromParent();
349bool LoongArchExpandAtomicPseudo::expandAtomicMinMaxOp(
353 assert(IsMasked ==
true &&
354 "Should only need to expand masked atomic max/min");
355 assert(Width == 32 &&
"Should never need to expand masked 64-bit operations");
367 MF->
insert(++LoopHeadMBB->getIterator(), LoopIfBodyMBB);
368 MF->
insert(++LoopIfBodyMBB->getIterator(), LoopTailMBB);
369 MF->
insert(++LoopTailMBB->getIterator(), DoneMBB);
372 LoopHeadMBB->addSuccessor(LoopIfBodyMBB);
373 LoopHeadMBB->addSuccessor(LoopTailMBB);
374 LoopIfBodyMBB->addSuccessor(LoopTailMBB);
375 LoopTailMBB->addSuccessor(LoopHeadMBB);
376 LoopTailMBB->addSuccessor(DoneMBB);
382 Register Scratch1Reg =
MI.getOperand(1).getReg();
383 Register Scratch2Reg =
MI.getOperand(2).getReg();
393 BuildMI(LoopHeadMBB,
DL,
TII->get(LoongArch::LL_W), DestReg)
396 BuildMI(LoopHeadMBB,
DL,
TII->get(LoongArch::AND), Scratch2Reg)
399 BuildMI(LoopHeadMBB,
DL,
TII->get(LoongArch::OR), Scratch1Reg)
421 insertSext(
TII,
DL, LoopHeadMBB, Scratch2Reg,
MI.getOperand(6).getReg());
429 insertSext(
TII,
DL, LoopHeadMBB, Scratch2Reg,
MI.getOperand(6).getReg());
443 insertMaskedMerge(
TII,
DL, LoopIfBodyMBB, Scratch1Reg, DestReg, IncrReg,
444 MaskReg, Scratch1Reg);
449 BuildMI(LoopTailMBB,
DL,
TII->get(LoongArch::SC_W), Scratch1Reg)
458 MI.eraseFromParent();
469bool LoongArchExpandAtomicPseudo::expandAtomicCmpXchg(
482 MF->
insert(++LoopHeadMBB->getIterator(), LoopTailMBB);
483 MF->
insert(++LoopTailMBB->getIterator(), TailMBB);
484 MF->
insert(++TailMBB->getIterator(), DoneMBB);
487 LoopHeadMBB->addSuccessor(LoopTailMBB);
488 LoopHeadMBB->addSuccessor(TailMBB);
489 LoopTailMBB->addSuccessor(DoneMBB);
490 LoopTailMBB->addSuccessor(LoopHeadMBB);
491 TailMBB->addSuccessor(DoneMBB);
497 Register ScratchReg =
MI.getOperand(1).getReg();
499 Register CmpValReg =
MI.getOperand(3).getReg();
500 Register NewValReg =
MI.getOperand(4).getReg();
507 TII->get(Width == 32 ? LoongArch::LL_W : LoongArch::LL_D), DestReg)
519 BuildMI(LoopTailMBB,
DL,
TII->get(LoongArch::OR), ScratchReg)
523 TII->get(Width == 32 ? LoongArch::SC_W : LoongArch::SC_D),
539 TII->get(Width == 32 ? LoongArch::LL_W : LoongArch::LL_D), DestReg)
542 BuildMI(LoopHeadMBB,
DL,
TII->get(LoongArch::AND), ScratchReg)
556 BuildMI(LoopTailMBB,
DL,
TII->get(LoongArch::ANDN), ScratchReg)
559 BuildMI(LoopTailMBB,
DL,
TII->get(LoongArch::OR), ScratchReg)
563 TII->get(Width == 32 ? LoongArch::SC_W : LoongArch::SC_D),
578 switch (FailureOrdering) {
579 case AtomicOrdering::Acquire:
580 case AtomicOrdering::AcquireRelease:
581 case AtomicOrdering::SequentiallyConsistent:
593 BuildMI(TailMBB,
DL,
TII->get(LoongArch::DBAR)).addImm(hint);
596 MI.eraseFromParent();
615 return new LoongArchExpandAtomicPseudo();
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
#define LoongArch_EXPAND_ATOMIC_PSEUDO_NAME
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
BinOp
This enumeration lists the possible modifications atomicrmw can make.
@ Min
*p = old <signed v ? old : v
@ Max
*p = old >signed v ? old : v
@ UMin
*p = old <unsigned v ? old : v
@ UMax
*p = old >unsigned v ? old : v
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...
void transferSuccessors(MachineBasicBlock *FromMBB)
Transfers all the successors from MBB to this machine basic block (i.e., copies all the successors Fr...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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 '...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
StringRef - Represent a constant reference to a string, i.e.
virtual const TargetInstrInfo * getInstrInfo() const
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.
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createLoongArchExpandAtomicPseudoPass()
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void initializeLoongArchExpandAtomicPseudoPass(PassRegistry &)
AtomicOrdering
Atomic ordering for LLVM's memory model.
void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().