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(
341 doMaskedAtomicBinOpExpansion(
TII,
MI,
DL, &
MBB, LoopMBB, DoneMBB, BinOp,
344 doAtomicBinOpExpansion(
TII,
MI,
DL, &
MBB, LoopMBB, DoneMBB, BinOp, Width);
347 MI.eraseFromParent();
367bool LoongArchExpandAtomicPseudo::expandAtomicMinMaxOp(
371 assert(Width == 32 &&
"Should never need to expand masked 64-bit operations");
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);
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)
488 MI.eraseFromParent();
499bool LoongArchExpandAtomicPseudo::expandAtomicCmpXchg(
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);
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) {
611 case AtomicOrdering::Acquire:
612 case AtomicOrdering::AcquireRelease:
613 case AtomicOrdering::SequentiallyConsistent:
625 BuildMI(TailMBB,
DL,
TII->get(LoongArch::DBAR)).addImm(hint);
628 MI.eraseFromParent();
639bool LoongArchExpandAtomicPseudo::expandAtomicCmpXchg128(
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);
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:
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
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...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI 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.
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.
AtomicOrdering
Atomic ordering for LLVM's memory model.
void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().