26#define LoongArch_EXPAND_ATOMIC_PSEUDO_NAME \
27 "LoongArch atomic pseudo instruction expansion pass"
50 bool IsMasked,
int Width,
64char LoongArchExpandAtomicPseudo::ID = 0;
66bool LoongArchExpandAtomicPseudo::runOnMachineFunction(
MachineFunction &MF) {
88bool LoongArchExpandAtomicPseudo::expandMI(
91 switch (
MBBI->getOpcode()) {
92 case LoongArch::PseudoMaskedAtomicSwap32:
95 case LoongArch::PseudoAtomicSwap32:
98 case LoongArch::PseudoMaskedAtomicLoadAdd32:
100 case LoongArch::PseudoMaskedAtomicLoadSub32:
102 case LoongArch::PseudoAtomicLoadNand32:
105 case LoongArch::PseudoAtomicLoadNand64:
108 case LoongArch::PseudoMaskedAtomicLoadNand32:
111 case LoongArch::PseudoAtomicLoadAdd32:
114 case LoongArch::PseudoAtomicLoadSub32:
117 case LoongArch::PseudoAtomicLoadAnd32:
120 case LoongArch::PseudoAtomicLoadOr32:
122 case LoongArch::PseudoAtomicLoadXor32:
125 case LoongArch::PseudoAtomicLoadUMax32:
128 case LoongArch::PseudoAtomicLoadUMin32:
131 case LoongArch::PseudoAtomicLoadMax32:
134 case LoongArch::PseudoAtomicLoadMin32:
137 case LoongArch::PseudoMaskedAtomicLoadUMax32:
140 case LoongArch::PseudoMaskedAtomicLoadUMin32:
143 case LoongArch::PseudoCmpXchg32:
144 return expandAtomicCmpXchg(
MBB,
MBBI,
false, 32, NextMBBI);
145 case LoongArch::PseudoCmpXchg64:
146 return expandAtomicCmpXchg(
MBB,
MBBI,
false, 64, NextMBBI);
147 case LoongArch::PseudoCmpXchg128:
148 case LoongArch::PseudoCmpXchg128Acquire:
149 return expandAtomicCmpXchg128(
MBB,
MBBI, NextMBBI);
150 case LoongArch::PseudoMaskedCmpXchg32:
151 return expandAtomicCmpXchg(
MBB,
MBBI,
true, 32, NextMBBI);
152 case LoongArch::PseudoMaskedAtomicLoadMax32:
155 case LoongArch::PseudoMaskedAtomicLoadMin32:
169 Register ScratchReg =
MI.getOperand(1).getReg();
179 TII->get(Width == 32 ? LoongArch::LL_W : LoongArch::LL_D), DestReg)
186 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::OR), ScratchReg)
191 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::AND), ScratchReg)
194 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::NOR), ScratchReg)
199 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::ADD_W), ScratchReg)
204 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::SUB_W), ScratchReg)
209 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::AND), ScratchReg)
214 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::OR), ScratchReg)
219 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::XOR), ScratchReg)
225 TII->get(Width == 32 ? LoongArch::SC_W : LoongArch::SC_D), ScratchReg)
239 assert(OldValReg != ScratchReg &&
"OldValReg and ScratchReg must be unique");
240 assert(OldValReg != MaskReg &&
"OldValReg and MaskReg must be unique");
241 assert(ScratchReg != MaskReg &&
"ScratchReg and MaskReg must be unique");
255static void doMaskedAtomicBinOpExpansion(
259 assert(Width == 32 &&
"Should never need to expand masked 64-bit operations");
261 Register ScratchReg =
MI.getOperand(1).getReg();
274 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::LL_W), DestReg)
281 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::ADDI_W), ScratchReg)
286 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::ADD_W), ScratchReg)
291 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::SUB_W), ScratchReg)
296 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::AND), ScratchReg)
299 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::NOR), ScratchReg)
305 insertMaskedMerge(
TII,
DL, LoopMBB, ScratchReg, DestReg, ScratchReg, MaskReg,
308 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::SC_W), ScratchReg)
318bool LoongArchExpandAtomicPseudo::expandAtomicBinOp(
330 MF->
insert(++
MBB.getIterator(), LoopMBB);
338 MBB.addSuccessor(LoopMBB);
341 doMaskedAtomicBinOpExpansion(
TII,
MI,
DL, &
MBB, LoopMBB, DoneMBB, BinOp,
344 doAtomicBinOpExpansion(
TII,
MI,
DL, &
MBB, LoopMBB, DoneMBB, BinOp, Width);
346 NextMBBI =
MBB.end();
347 MI.eraseFromParent();
367bool LoongArchExpandAtomicPseudo::expandAtomicMinMaxOp(
371 assert(Width == 32 &&
"Should never need to expand masked 64-bit operations");
382 MF->
insert(++
MBB.getIterator(), LoopHeadMBB);
383 MF->
insert(++LoopHeadMBB->getIterator(), LoopIfBodyMBB);
384 MF->
insert(++LoopIfBodyMBB->getIterator(), LoopTailMBB);
385 MF->
insert(++LoopTailMBB->getIterator(), DoneMBB);
388 LoopHeadMBB->addSuccessor(LoopIfBodyMBB);
389 LoopHeadMBB->addSuccessor(LoopTailMBB);
390 LoopIfBodyMBB->addSuccessor(LoopTailMBB);
391 LoopTailMBB->addSuccessor(LoopHeadMBB);
392 LoopTailMBB->addSuccessor(DoneMBB);
395 MBB.addSuccessor(LoopHeadMBB);
398 Register ScratchReg =
MI.getOperand(1).getReg();
399 Register AddrReg =
MI.getOperand(IsMasked ? 3 : 2).getReg();
400 Register IncrReg =
MI.getOperand(IsMasked ? 4 : 3).getReg();
406 BuildMI(LoopHeadMBB,
DL,
TII->get(LoongArch::LL_W), DestReg)
412 CmprReg =
MI.getOperand(2).getReg();
413 BuildMI(LoopHeadMBB,
DL,
TII->get(LoongArch::AND), CmprReg)
418 BuildMI(LoopHeadMBB,
DL,
TII->get(LoongArch::OR), ScratchReg)
441 insertSext(
TII,
DL, LoopHeadMBB, CmprReg,
MI.getOperand(6).getReg());
450 insertSext(
TII,
DL, LoopHeadMBB, CmprReg,
MI.getOperand(6).getReg());
466 insertMaskedMerge(
TII,
DL, LoopIfBodyMBB, ScratchReg, DestReg, IncrReg,
467 MaskReg, ScratchReg);
470 BuildMI(LoopIfBodyMBB,
DL,
TII->get(LoongArch::OR), ScratchReg)
478 BuildMI(LoopTailMBB,
DL,
TII->get(LoongArch::SC_W), ScratchReg)
487 NextMBBI =
MBB.end();
488 MI.eraseFromParent();
499bool LoongArchExpandAtomicPseudo::expandAtomicCmpXchg(
511 MF->
insert(++
MBB.getIterator(), LoopHeadMBB);
512 MF->
insert(++LoopHeadMBB->getIterator(), LoopTailMBB);
513 MF->
insert(++LoopTailMBB->getIterator(), TailMBB);
514 MF->
insert(++TailMBB->getIterator(), DoneMBB);
517 LoopHeadMBB->addSuccessor(LoopTailMBB);
518 LoopHeadMBB->addSuccessor(TailMBB);
519 LoopTailMBB->addSuccessor(DoneMBB);
520 LoopTailMBB->addSuccessor(LoopHeadMBB);
521 TailMBB->addSuccessor(DoneMBB);
524 MBB.addSuccessor(LoopHeadMBB);
527 Register ScratchReg =
MI.getOperand(1).getReg();
529 Register CmpValReg =
MI.getOperand(3).getReg();
530 Register NewValReg =
MI.getOperand(4).getReg();
537 TII->get(Width == 32 ? LoongArch::LL_W : LoongArch::LL_D), DestReg)
549 BuildMI(LoopTailMBB,
DL,
TII->get(LoongArch::OR), ScratchReg)
553 TII->get(Width == 32 ? LoongArch::SC_W : LoongArch::SC_D),
570 TII->get(Width == 32 ? LoongArch::LL_W : LoongArch::LL_D), DestReg)
573 BuildMI(LoopHeadMBB,
DL,
TII->get(LoongArch::AND), ScratchReg)
587 BuildMI(LoopTailMBB,
DL,
TII->get(LoongArch::ANDN), ScratchReg)
590 BuildMI(LoopTailMBB,
DL,
TII->get(LoongArch::OR), ScratchReg)
594 TII->get(Width == 32 ? LoongArch::SC_W : LoongArch::SC_D),
610 switch (FailureOrdering) {
627 NextMBBI =
MBB.end();
628 MI.eraseFromParent();
639bool LoongArchExpandAtomicPseudo::expandAtomicCmpXchg128(
651 MF->
insert(++
MBB.getIterator(), LoopHeadMBB);
652 MF->
insert(++LoopHeadMBB->getIterator(), LoopTailMBB);
653 MF->
insert(++LoopTailMBB->getIterator(), TailMBB);
654 MF->
insert(++TailMBB->getIterator(), DoneMBB);
657 LoopHeadMBB->addSuccessor(LoopTailMBB);
658 LoopHeadMBB->addSuccessor(TailMBB);
659 LoopTailMBB->addSuccessor(DoneMBB);
660 LoopTailMBB->addSuccessor(LoopHeadMBB);
661 TailMBB->addSuccessor(DoneMBB);
664 MBB.addSuccessor(LoopHeadMBB);
666 Register DestLoReg =
MI.getOperand(0).getReg();
667 Register DestHiReg =
MI.getOperand(1).getReg();
668 Register ScratchReg =
MI.getOperand(2).getReg();
670 Register CmpValLoReg =
MI.getOperand(4).getReg();
671 Register CmpValHiReg =
MI.getOperand(5).getReg();
672 Register NewValLoReg =
MI.getOperand(6).getReg();
673 Register NewValHiReg =
MI.getOperand(7).getReg();
681 BuildMI(LoopHeadMBB,
DL,
TII->get(LoongArch::LL_D), DestLoReg)
685 BuildMI(LoopHeadMBB,
DL,
TII->get(LoongArch::LD_D), DestHiReg)
701 BuildMI(LoopTailMBB,
DL,
TII->get(LoongArch::OR), ScratchReg)
704 BuildMI(LoopTailMBB,
DL,
TII->get(LoongArch::SC_Q), ScratchReg)
715 switch (
MI.getOpcode()) {
716 case LoongArch::PseudoCmpXchg128Acquire:
720 case LoongArch::PseudoCmpXchg128:
732 NextMBBI =
MBB.end();
733 MI.eraseFromParent();
752 return new LoongArchExpandAtomicPseudo();
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.
#define LoongArch_EXPAND_ATOMIC_PSEUDO_NAME
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
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...
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...
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)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
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 & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
Wrapper class representing virtual and physical registers.
Represent a constant reference to a string, i.e.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
AtomicOrdering
Atomic ordering for LLVM's memory model.
LLVM_ABI void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().