26#define DEBUG_TYPE "ppc-atomic-expand"
57 if (Dest0 == Src1 && Dest1 == Src0) {
62 }
else if (Dest0 != Src0 || Dest1 != Src1) {
63 if (Dest0 == Src1 || Dest1 != Src0) {
76 TRI = &
TII->getRegisterInfo();
82 Changed |= expandMI(
MBB,
MI, NMBBI);
93 switch (
MI.getOpcode()) {
94 case PPC::ATOMIC_SWAP_I128:
95 case PPC::ATOMIC_LOAD_ADD_I128:
96 case PPC::ATOMIC_LOAD_SUB_I128:
97 case PPC::ATOMIC_LOAD_XOR_I128:
98 case PPC::ATOMIC_LOAD_NAND_I128:
99 case PPC::ATOMIC_LOAD_AND_I128:
100 case PPC::ATOMIC_LOAD_OR_I128:
101 return expandAtomicRMW128(
MBB,
MI, NMBBI);
102 case PPC::ATOMIC_CMP_SWAP_I128:
103 return expandAtomicCmpSwap128(
MBB,
MI, NMBBI);
104 case PPC::BUILD_QUADWORD: {
106 Register DstHi =
TRI->getSubReg(Dst, PPC::sub_gp8_x0);
107 Register DstLo =
TRI->getSubReg(Dst, PPC::sub_gp8_x1);
111 MI.eraseFromParent();
119bool PPCExpandAtomicPseudo::expandAtomicRMW128(
150 Register OldHi =
TRI->getSubReg(Old, PPC::sub_gp8_x0);
151 Register OldLo =
TRI->getSubReg(Old, PPC::sub_gp8_x1);
153 Register ScratchHi =
TRI->getSubReg(Scratch, PPC::sub_gp8_x0);
154 Register ScratchLo =
TRI->getSubReg(Scratch, PPC::sub_gp8_x1);
159 unsigned RMWOpcode =
MI.getOpcode();
165 case PPC::ATOMIC_SWAP_I128:
166 PairedCopy(
TII, *CurrentMBB, CurrentMBB->
end(),
DL, ScratchHi, ScratchLo,
169 case PPC::ATOMIC_LOAD_ADD_I128:
170 BuildMI(CurrentMBB,
DL,
TII->get(PPC::ADDC8), ScratchLo)
173 BuildMI(CurrentMBB,
DL,
TII->get(PPC::ADDE8), ScratchHi)
177 case PPC::ATOMIC_LOAD_SUB_I128:
178 BuildMI(CurrentMBB,
DL,
TII->get(PPC::SUBFC8), ScratchLo)
181 BuildMI(CurrentMBB,
DL,
TII->get(PPC::SUBFE8), ScratchHi)
186#define TRIVIAL_ATOMICRMW(Opcode, Instr) \
188 BuildMI(CurrentMBB, DL, TII->get((Instr)), ScratchLo) \
191 BuildMI(CurrentMBB, DL, TII->get((Instr)), ScratchHi) \
200#undef TRIVIAL_ATOMICRMW
213 MI.eraseFromParent();
217bool PPCExpandAtomicPseudo::expandAtomicCmpSwap128(
226 Register OldHi =
TRI->getSubReg(Old, PPC::sub_gp8_x0);
227 Register OldLo =
TRI->getSubReg(Old, PPC::sub_gp8_x1);
229 Register ScratchHi =
TRI->getSubReg(Scratch, PPC::sub_gp8_x0);
230 Register ScratchLo =
TRI->getSubReg(Scratch, PPC::sub_gp8_x1);
251 MF->
insert(MFI, LoopCmpMBB);
252 MF->
insert(MFI, CmpSuccMBB);
267 BuildMI(CurrentMBB,
DL,
TII->get(PPC::OR8_rec), ScratchLo)
277 CurrentMBB = CmpSuccMBB;
278 PairedCopy(
TII, *CurrentMBB, CurrentMBB->
end(),
DL, ScratchHi, ScratchLo,
290 MI.eraseFromParent();
299char PPCExpandAtomicPseudo::
ID = 0;
301 return new PPCExpandAtomicPseudo();
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
unsigned const TargetRegisterInfo * TRI
#define TRIVIAL_ATOMICRMW(Opcode, Instr)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
SI optimize exec mask operations pre RA
support::ulittle16_t & Lo
support::ulittle16_t & Hi
LLVM Basic Block Representation.
FunctionPass class - This class is used to implement most global optimizations.
Describe properties that are true of each instruction in the target description file.
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
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.
void RenumberBlocks(MachineBasicBlock *MBBFrom=nullptr)
RenumberBlocks - This discards all of the MachineBasicBlock numbers and recomputes them.
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...
Wrapper class representing virtual and physical registers.
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.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
FunctionPass * createPPCExpandAtomicPseudoPass()
void initializePPCExpandAtomicPseudoPass(PassRegistry &)
void fullyRecomputeLiveIns(ArrayRef< MachineBasicBlock * > MBBs)
Convenience function for recomputing live-in's for a set of MBBs until the computation converges.