33#define DEBUG_TYPE "mips-expand-pseudo"
48 return "Mips pseudo instruction expansion pass";
51char MipsExpandPseudoLegacy::ID = 0;
66 unsigned ZERO = Mips::R0;
67 unsigned BNE = Mips::BNE;
68 unsigned BEQ = Mips::BEQ;
70 I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I8_POSTRA ? Mips::SEB : Mips::SEH;
73 LL = STI->
hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
74 SC = STI->
hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
75 BNE = STI->
hasMips32r6() ? Mips::BNEC_MMR6 : Mips::BNE_MM;
76 BEQ = STI->
hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
78 LL = STI->
hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
79 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
80 SC = STI->
hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
81 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
84 Register Dest =
I->getOperand(0).getReg();
86 Register Mask =
I->getOperand(2).getReg();
87 Register ShiftCmpVal =
I->getOperand(3).getReg();
88 Register Mask2 =
I->getOperand(4).getReg();
89 Register ShiftNewVal =
I->getOperand(5).getReg();
90 Register ShiftAmnt =
I->getOperand(6).getReg();
91 Register Scratch =
I->getOperand(7).getReg();
92 Register Scratch2 =
I->getOperand(8).getReg();
163 const unsigned ShiftImm =
164 I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I16_POSTRA ? 16 : 24;
180 I->eraseFromParent();
190 const unsigned Size =
191 I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I32_POSTRA ? 4 : 8;
197 unsigned LL, SC,
ZERO, BNE, BEQ, MOVE;
201 LL = STI->
hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
202 SC = STI->
hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
203 BNE = STI->
hasMips32r6() ? Mips::BNEC_MMR6 : Mips::BNE_MM;
204 BEQ = STI->
hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
207 ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
208 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
210 ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
211 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
219 LL = STI->
hasMips64r6() ? Mips::LLD_R6 : Mips::LLD;
220 SC = STI->
hasMips64r6() ? Mips::SCD_R6 : Mips::SCD;
227 Register Dest =
I->getOperand(0).getReg();
228 Register Ptr =
I->getOperand(1).getReg();
229 Register OldVal =
I->getOperand(2).getReg();
230 Register NewVal =
I->getOperand(3).getReg();
231 Register Scratch =
I->getOperand(4).getReg();
282 I->eraseFromParent();
297 unsigned LL, SC, SLT, SLTu, OR, MOVN, MOVZ, SELNEZ, SELEQZ;
298 unsigned BEQ = Mips::BEQ;
299 unsigned SEOp = Mips::SEH;
302 LL = STI->
hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
303 SC = STI->
hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
304 BEQ = STI->
hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
306 SLTu = Mips::SLTu_MM;
307 OR = STI->
hasMips32r6() ? Mips::OR_MMR6 : Mips::OR_MM;
308 MOVN = Mips::MOVN_I_MM;
309 MOVZ = Mips::MOVZ_I_MM;
310 SELNEZ = STI->
hasMips32r6() ? Mips::SELNEZ_MMR6 : Mips::SELNEZ;
311 SELEQZ = STI->
hasMips32r6() ? Mips::SELEQZ_MMR6 : Mips::SELEQZ;
313 LL = STI->
hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
314 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
315 SC = STI->
hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
316 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
320 MOVN = Mips::MOVN_I_I;
321 MOVZ = Mips::MOVZ_I_I;
322 SELNEZ = Mips::SELNEZ;
323 SELEQZ = Mips::SELEQZ;
330 bool IsUnsigned =
false;
334 switch (
I->getOpcode()) {
335 case Mips::ATOMIC_LOAD_NAND_I8_POSTRA:
338 case Mips::ATOMIC_LOAD_NAND_I16_POSTRA:
341 case Mips::ATOMIC_SWAP_I8_POSTRA:
344 case Mips::ATOMIC_SWAP_I16_POSTRA:
347 case Mips::ATOMIC_LOAD_ADD_I8_POSTRA:
350 case Mips::ATOMIC_LOAD_ADD_I16_POSTRA:
353 case Mips::ATOMIC_LOAD_SUB_I8_POSTRA:
356 case Mips::ATOMIC_LOAD_SUB_I16_POSTRA:
359 case Mips::ATOMIC_LOAD_AND_I8_POSTRA:
362 case Mips::ATOMIC_LOAD_AND_I16_POSTRA:
365 case Mips::ATOMIC_LOAD_OR_I8_POSTRA:
368 case Mips::ATOMIC_LOAD_OR_I16_POSTRA:
371 case Mips::ATOMIC_LOAD_XOR_I8_POSTRA:
374 case Mips::ATOMIC_LOAD_XOR_I16_POSTRA:
377 case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA:
382 case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA:
386 case Mips::ATOMIC_LOAD_MIN_I8_POSTRA:
390 case Mips::ATOMIC_LOAD_MIN_I16_POSTRA:
393 case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:
398 case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA:
402 case Mips::ATOMIC_LOAD_MAX_I8_POSTRA:
406 case Mips::ATOMIC_LOAD_MAX_I16_POSTRA:
413 Register Dest =
I->getOperand(0).getReg();
414 Register Ptr =
I->getOperand(1).getReg();
415 Register Incr =
I->getOperand(2).getReg();
416 Register Mask =
I->getOperand(3).getReg();
417 Register Mask2 =
I->getOperand(4).getReg();
418 Register ShiftAmnt =
I->getOperand(5).getReg();
419 Register OldVal =
I->getOperand(6).getReg();
420 Register BinOpRes =
I->getOperand(7).getReg();
421 Register StoreVal =
I->getOperand(8).getReg();
475 }
else if (IsMin || IsMax) {
477 assert(
I->getNumOperands() == 10 &&
478 "Atomics min|max|umin|umax use an additional register");
479 Register Scratch4 =
I->getOperand(9).getReg();
481 unsigned SLTScratch4 = IsUnsigned ? SLTu : SLT;
482 unsigned SELIncr = IsMax ? SELNEZ : SELEQZ;
483 unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ;
484 unsigned MOVIncr = IsMax ? MOVN : MOVZ;
490 const unsigned OpMask = SEOp == Mips::SEH ? 0xffff : 0xff;
497 const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
498 const unsigned SROp = IsUnsigned ? Mips::SRL : Mips::SRA;
602 }
else if (!IsSwap) {
669 const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
682 assert(loop2MBB &&
"should have 2 loop blocks");
690 I->eraseFromParent();
705 unsigned LL, SC,
ZERO, BEQ, SLT, SLTu, OR, MOVN, MOVZ, SELNEZ, SELEQZ;
709 LL = STI->
hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
710 SC = STI->
hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
711 BEQ = STI->
hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
713 SLTu = Mips::SLTu_MM;
714 OR = STI->
hasMips32r6() ? Mips::OR_MMR6 : Mips::OR_MM;
715 MOVN = Mips::MOVN_I_MM;
716 MOVZ = Mips::MOVZ_I_MM;
717 SELNEZ = STI->
hasMips32r6() ? Mips::SELNEZ_MMR6 : Mips::SELNEZ;
718 SELEQZ = STI->
hasMips32r6() ? Mips::SELEQZ_MMR6 : Mips::SELEQZ;
721 ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
722 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
724 ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
725 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
730 MOVN = Mips::MOVN_I_I;
731 MOVZ = Mips::MOVZ_I_I;
732 SELNEZ = Mips::SELNEZ;
733 SELEQZ = Mips::SELEQZ;
738 LL = STI->
hasMips64r6() ? Mips::LLD_R6 : Mips::LLD;
739 SC = STI->
hasMips64r6() ? Mips::SCD_R6 : Mips::SCD;
745 MOVN = Mips::MOVN_I64_I64;
746 MOVZ = Mips::MOVZ_I64_I64;
747 SELNEZ = Mips::SELNEZ64;
748 SELEQZ = Mips::SELEQZ64;
751 Register OldVal =
I->getOperand(0).getReg();
752 Register Ptr =
I->getOperand(1).getReg();
753 Register Incr =
I->getOperand(2).getReg();
754 Register Scratch =
I->getOperand(3).getReg();
764 bool IsUnsigned =
false;
766 switch (
I->getOpcode()) {
767 case Mips::ATOMIC_LOAD_ADD_I32_POSTRA:
770 case Mips::ATOMIC_LOAD_SUB_I32_POSTRA:
773 case Mips::ATOMIC_LOAD_AND_I32_POSTRA:
776 case Mips::ATOMIC_LOAD_OR_I32_POSTRA:
779 case Mips::ATOMIC_LOAD_XOR_I32_POSTRA:
782 case Mips::ATOMIC_LOAD_NAND_I32_POSTRA:
787 case Mips::ATOMIC_SWAP_I32_POSTRA:
790 case Mips::ATOMIC_LOAD_ADD_I64_POSTRA:
791 Opcode = Mips::DADDu;
793 case Mips::ATOMIC_LOAD_SUB_I64_POSTRA:
794 Opcode = Mips::DSUBu;
796 case Mips::ATOMIC_LOAD_AND_I64_POSTRA:
797 Opcode = Mips::AND64;
799 case Mips::ATOMIC_LOAD_OR_I64_POSTRA:
802 case Mips::ATOMIC_LOAD_XOR_I64_POSTRA:
803 Opcode = Mips::XOR64;
805 case Mips::ATOMIC_LOAD_NAND_I64_POSTRA:
810 case Mips::ATOMIC_SWAP_I64_POSTRA:
813 case Mips::ATOMIC_LOAD_UMIN_I32_POSTRA:
814 case Mips::ATOMIC_LOAD_UMIN_I64_POSTRA:
817 case Mips::ATOMIC_LOAD_MIN_I32_POSTRA:
818 case Mips::ATOMIC_LOAD_MIN_I64_POSTRA:
821 case Mips::ATOMIC_LOAD_UMAX_I32_POSTRA:
822 case Mips::ATOMIC_LOAD_UMAX_I64_POSTRA:
825 case Mips::ATOMIC_LOAD_MAX_I32_POSTRA:
826 case Mips::ATOMIC_LOAD_MAX_I64_POSTRA:
870 assert((OldVal != Ptr) &&
"Clobbered the wrong ptr reg!");
871 assert((OldVal != Incr) &&
"Clobbered the wrong reg!");
872 if (IsMin || IsMax) {
878 while (
I->getNumOperands() > 5) {
879 auto &
Op =
I->getOperand(
I->getNumOperands() - 1);
883 bool HasOverlapWithKill =
false;
884 for (
unsigned i = 1; i <= 4; ++i) {
885 auto &RefOp =
I->getOperand(i);
886 if (RefOp.isReg() && RefOp.getReg().isPhysical() &&
887 TRI->regsOverlap(
Op.getReg(), RefOp.getReg()) &&
888 (RefOp.isKill() || RefOp.isDead())) {
889 HasOverlapWithKill =
true;
894 bool HasKillOrDead =
Op.isReg() &&
Op.getReg().isPhysical() &&
895 (
Op.isKill() ||
Op.isDead());
896 if (!HasOverlapWithKill && !HasKillOrDead)
898 I->removeOperand(
I->getNumOperands() - 1);
901 assert(
I->getNumOperands() == 5 &&
902 "Atomics min|max|umin|umax use an additional register");
903 MCRegister Scratch2 =
I->getOperand(4).getReg().asMCReg();
910 unsigned SLTScratch2 = IsUnsigned ? SLTu : SLT;
911 unsigned SELIncr = IsMax ? SELNEZ : SELEQZ;
912 unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ;
913 unsigned MOVIncr = IsMax ? MOVN : MOVZ;
917 BuildMI(loopMBB,
DL,
TII->get(SLTScratch2), Scratch2_32)
987 "Unknown nand instruction for atomic pseudo expansion");
991 assert(IsOr && OR &&
"Unknown instruction for atomic pseudo expansion!");
1017 I->eraseFromParent();
1022 assert(loop2MBB &&
"should have 2 loop blocks");
1037 switch (
MBBI->getOpcode()) {
1038 case Mips::ATOMIC_CMP_SWAP_I32_POSTRA:
1039 case Mips::ATOMIC_CMP_SWAP_I64_POSTRA:
1041 case Mips::ATOMIC_CMP_SWAP_I8_POSTRA:
1042 case Mips::ATOMIC_CMP_SWAP_I16_POSTRA:
1044 case Mips::ATOMIC_SWAP_I8_POSTRA:
1045 case Mips::ATOMIC_SWAP_I16_POSTRA:
1046 case Mips::ATOMIC_LOAD_NAND_I8_POSTRA:
1047 case Mips::ATOMIC_LOAD_NAND_I16_POSTRA:
1048 case Mips::ATOMIC_LOAD_ADD_I8_POSTRA:
1049 case Mips::ATOMIC_LOAD_ADD_I16_POSTRA:
1050 case Mips::ATOMIC_LOAD_SUB_I8_POSTRA:
1051 case Mips::ATOMIC_LOAD_SUB_I16_POSTRA:
1052 case Mips::ATOMIC_LOAD_AND_I8_POSTRA:
1053 case Mips::ATOMIC_LOAD_AND_I16_POSTRA:
1054 case Mips::ATOMIC_LOAD_OR_I8_POSTRA:
1055 case Mips::ATOMIC_LOAD_OR_I16_POSTRA:
1056 case Mips::ATOMIC_LOAD_XOR_I8_POSTRA:
1057 case Mips::ATOMIC_LOAD_XOR_I16_POSTRA:
1058 case Mips::ATOMIC_LOAD_MIN_I8_POSTRA:
1059 case Mips::ATOMIC_LOAD_MIN_I16_POSTRA:
1060 case Mips::ATOMIC_LOAD_MAX_I8_POSTRA:
1061 case Mips::ATOMIC_LOAD_MAX_I16_POSTRA:
1062 case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA:
1063 case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA:
1064 case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:
1065 case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA:
1067 case Mips::ATOMIC_LOAD_ADD_I32_POSTRA:
1068 case Mips::ATOMIC_LOAD_SUB_I32_POSTRA:
1069 case Mips::ATOMIC_LOAD_AND_I32_POSTRA:
1070 case Mips::ATOMIC_LOAD_OR_I32_POSTRA:
1071 case Mips::ATOMIC_LOAD_XOR_I32_POSTRA:
1072 case Mips::ATOMIC_LOAD_NAND_I32_POSTRA:
1073 case Mips::ATOMIC_SWAP_I32_POSTRA:
1074 case Mips::ATOMIC_LOAD_MIN_I32_POSTRA:
1075 case Mips::ATOMIC_LOAD_MAX_I32_POSTRA:
1076 case Mips::ATOMIC_LOAD_UMIN_I32_POSTRA:
1077 case Mips::ATOMIC_LOAD_UMAX_I32_POSTRA:
1079 case Mips::ATOMIC_LOAD_ADD_I64_POSTRA:
1080 case Mips::ATOMIC_LOAD_SUB_I64_POSTRA:
1081 case Mips::ATOMIC_LOAD_AND_I64_POSTRA:
1082 case Mips::ATOMIC_LOAD_OR_I64_POSTRA:
1083 case Mips::ATOMIC_LOAD_XOR_I64_POSTRA:
1084 case Mips::ATOMIC_LOAD_NAND_I64_POSTRA:
1085 case Mips::ATOMIC_SWAP_I64_POSTRA:
1086 case Mips::ATOMIC_LOAD_MIN_I64_POSTRA:
1087 case Mips::ATOMIC_LOAD_MAX_I64_POSTRA:
1088 case Mips::ATOMIC_LOAD_UMIN_I64_POSTRA:
1089 case Mips::ATOMIC_LOAD_UMAX_I64_POSTRA:
1127 return new MipsExpandPseudoLegacy();
1130bool MipsExpandPseudoLegacy::runOnMachineFunction(
MachineFunction &MF) {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
@ ZERO
Special weight used for cases with exact zero probability.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
Register const TargetRegisterInfo * TRI
static bool expandPseudosInMF(MachineFunction &MF)
static bool expandAtomicBinOp(MachineBasicBlock &BB, MachineBasicBlock::iterator I, MachineBasicBlock::iterator &NMBBI, unsigned Size, const MipsSubtarget *STI, const MipsInstrInfo *TII)
static bool expandAtomicCmpSwap(MachineBasicBlock &BB, MachineBasicBlock::iterator I, MachineBasicBlock::iterator &NMBBI, const MipsSubtarget *STI, const MipsInstrInfo *TII)
static bool expandMBB(MachineBasicBlock &MBB, const MipsSubtarget *STI, const MipsInstrInfo *TII)
static bool expandAtomicCmpSwapSubword(MachineBasicBlock &BB, MachineBasicBlock::iterator I, MachineBasicBlock::iterator &NMBBI, const MipsSubtarget *STI, const MipsInstrInfo *TII)
static bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, MachineBasicBlock::iterator &NMBB, const MipsSubtarget *STI, const MipsInstrInfo *TII)
static bool expandAtomicBinOpSubword(MachineBasicBlock &BB, MachineBasicBlock::iterator I, MachineBasicBlock::iterator &NMBBI, const MipsSubtarget *STI, const MipsInstrInfo *TII)
LLVM Basic Block Representation.
static constexpr BranchProbability getOne()
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...
Wrapper class representing physical registers. Should be passed by value.
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
void normalizeSuccProbs()
Normalize probabilities of all successors so that the sum of them becomes one.
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 '...
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Properties which a MachineFunction may have at a given point in time.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
BasicBlockListType::iterator iterator
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)
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
bool ArePtrs64bit() const
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
bool inMicroMipsMode() const
const MipsInstrInfo * getInstrInfo() const override
const MipsRegisterInfo * getRegisterInfo() const override
const MipsABIInfo & getABI() const
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
Represent a constant reference to a string, i.e.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
self_iterator getIterator()
Pass manager infrastructure for declaring and invalidating analyses.
#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.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Kill
The last use of a register.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
FunctionPass * createMipsExpandPseudoLegacyPass()
createMipsExpandPseudoPass - returns an instance of the pseudo instruction expansion pass.
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
DWARFExpression::Operation Op
LLVM_ABI void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().