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();
166 if (Ordering != AtomicOrdering::Monotonic)
169 TII->get(Width == 32 ? LoongArch::LL_W : LoongArch::LL_D), DestReg)
176 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::OR), ScratchReg)
181 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::AND), ScratchReg)
184 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::NOR), ScratchReg)
189 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::ADD_W), ScratchReg)
194 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::SUB_W), ScratchReg)
199 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::AND), ScratchReg)
204 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::OR), ScratchReg)
209 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::XOR), ScratchReg)
215 TII->get(Width == 32 ? LoongArch::SC_W : LoongArch::SC_D), ScratchReg)
228 assert(OldValReg != ScratchReg &&
"OldValReg and ScratchReg must be unique");
229 assert(OldValReg != MaskReg &&
"OldValReg and MaskReg must be unique");
230 assert(ScratchReg != MaskReg &&
"ScratchReg and MaskReg must be unique");
244static void doMaskedAtomicBinOpExpansion(
248 assert(Width == 32 &&
"Should never need to expand masked 64-bit operations");
250 Register ScratchReg =
MI.getOperand(1).getReg();
267 if (Ordering != AtomicOrdering::Monotonic)
269 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::LL_W), DestReg)
276 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::ADDI_W), ScratchReg)
281 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::ADD_W), ScratchReg)
286 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::SUB_W), ScratchReg)
291 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::AND), ScratchReg)
294 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::NOR), ScratchReg)
300 insertMaskedMerge(
TII,
DL, LoopMBB, ScratchReg, DestReg, ScratchReg, MaskReg,
303 BuildMI(LoopMBB,
DL,
TII->get(LoongArch::SC_W), ScratchReg)
312bool LoongArchExpandAtomicPseudo::expandAtomicBinOp(
335 doMaskedAtomicBinOpExpansion(
TII,
MI,
DL, &
MBB, LoopMBB, DoneMBB, BinOp,
338 doAtomicBinOpExpansion(
TII,
MI,
DL, &
MBB, LoopMBB, DoneMBB, BinOp, Width);
341 MI.eraseFromParent();
361bool LoongArchExpandAtomicPseudo::expandAtomicMinMaxOp(
365 assert(IsMasked ==
true &&
366 "Should only need to expand masked atomic max/min");
367 assert(Width == 32 &&
"Should never need to expand masked 64-bit operations");
380 MF->
insert(++LoopHeadMBB->getIterator(), LoopIfBodyMBB);
381 MF->
insert(++LoopIfBodyMBB->getIterator(), LoopTailMBB);
382 MF->
insert(++LoopTailMBB->getIterator(), TailMBB);
383 MF->
insert(++TailMBB->getIterator(), DoneMBB);
386 LoopHeadMBB->addSuccessor(LoopIfBodyMBB);
387 LoopHeadMBB->addSuccessor(LoopTailMBB);
388 LoopIfBodyMBB->addSuccessor(LoopTailMBB);
389 LoopTailMBB->addSuccessor(LoopHeadMBB);
390 LoopTailMBB->addSuccessor(TailMBB);
391 TailMBB->addSuccessor(DoneMBB);
397 Register Scratch1Reg =
MI.getOperand(1).getReg();
398 Register Scratch2Reg =
MI.getOperand(2).getReg();
410 BuildMI(LoopHeadMBB,
DL,
TII->get(LoongArch::LL_W), DestReg)
413 BuildMI(LoopHeadMBB,
DL,
TII->get(LoongArch::AND), Scratch2Reg)
416 BuildMI(LoopHeadMBB,
DL,
TII->get(LoongArch::OR), Scratch1Reg)
438 insertSext(
TII,
DL, LoopHeadMBB, Scratch2Reg,
MI.getOperand(6).getReg());
446 insertSext(
TII,
DL, LoopHeadMBB, Scratch2Reg,
MI.getOperand(6).getReg());
460 insertMaskedMerge(
TII,
DL, LoopIfBodyMBB, Scratch1Reg, DestReg, IncrReg,
461 MaskReg, Scratch1Reg);
467 BuildMI(LoopTailMBB,
DL,
TII->get(LoongArch::SC_W), Scratch1Reg)
480 MI.eraseFromParent();
492bool LoongArchExpandAtomicPseudo::expandAtomicCmpXchg(
505 MF->
insert(++LoopHeadMBB->getIterator(), LoopTailMBB);
506 MF->
insert(++LoopTailMBB->getIterator(), TailMBB);
507 MF->
insert(++TailMBB->getIterator(), DoneMBB);
510 LoopHeadMBB->addSuccessor(LoopTailMBB);
511 LoopHeadMBB->addSuccessor(TailMBB);
512 LoopTailMBB->addSuccessor(DoneMBB);
513 LoopTailMBB->addSuccessor(LoopHeadMBB);
514 TailMBB->addSuccessor(DoneMBB);
520 Register ScratchReg =
MI.getOperand(1).getReg();
522 Register CmpValReg =
MI.getOperand(3).getReg();
523 Register NewValReg =
MI.getOperand(4).getReg();
530 TII->get(Width == 32 ? LoongArch::LL_W : LoongArch::LL_D), DestReg)
544 BuildMI(LoopTailMBB,
DL,
TII->get(LoongArch::OR), ScratchReg)
548 TII->get(Width == 32 ? LoongArch::SC_W : LoongArch::SC_D),
564 TII->get(Width == 32 ? LoongArch::LL_W : LoongArch::LL_D), DestReg)
567 BuildMI(LoopHeadMBB,
DL,
TII->get(LoongArch::AND), ScratchReg)
583 BuildMI(LoopTailMBB,
DL,
TII->get(LoongArch::ANDN), ScratchReg)
586 BuildMI(LoopTailMBB,
DL,
TII->get(LoongArch::OR), ScratchReg)
590 TII->get(Width == 32 ? LoongArch::SC_W : LoongArch::SC_D),
606 MI.eraseFromParent();
625 return new LoongArchExpandAtomicPseudo();
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)
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...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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().