30#define DEBUG_TYPE "mips-pseudo"
48 return "Mips pseudo instruction expansion pass";
70 char MipsExpandPseudo::ID = 0;
73bool MipsExpandPseudo::expandAtomicCmpSwapSubword(
83 unsigned ZERO = Mips::ZERO;
84 unsigned BNE = Mips::BNE;
85 unsigned BEQ = Mips::BEQ;
87 I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I8_POSTRA ? Mips::SEB : Mips::SEH;
90 LL = STI->
hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
91 SC = STI->
hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
92 BNE = STI->
hasMips32r6() ? Mips::BNEC_MMR6 : Mips::BNE_MM;
93 BEQ = STI->
hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
95 LL = STI->
hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
96 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
97 SC = STI->
hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
98 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
101 Register Dest =
I->getOperand(0).getReg();
104 Register ShiftCmpVal =
I->getOperand(3).getReg();
105 Register Mask2 =
I->getOperand(4).getReg();
106 Register ShiftNewVal =
I->getOperand(5).getReg();
107 Register ShiftAmnt =
I->getOperand(6).getReg();
108 Register Scratch =
I->getOperand(7).getReg();
109 Register Scratch2 =
I->getOperand(8).getReg();
180 const unsigned ShiftImm =
181 I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I16_POSTRA ? 16 : 24;
190 LivePhysRegs LiveRegs;
197 I->eraseFromParent();
201bool MipsExpandPseudo::expandAtomicCmpSwap(MachineBasicBlock &BB,
205 const unsigned Size =
206 I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I32_POSTRA ? 4 : 8;
212 unsigned LL, SC,
ZERO, BNE, BEQ, MOVE;
216 LL = STI->
hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
217 SC = STI->
hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
218 BNE = STI->
hasMips32r6() ? Mips::BNEC_MMR6 : Mips::BNE_MM;
219 BEQ = STI->
hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
222 ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
223 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
225 ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
226 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
234 LL = STI->
hasMips64r6() ? Mips::LLD_R6 : Mips::LLD;
235 SC = STI->
hasMips64r6() ? Mips::SCD_R6 : Mips::SCD;
236 ZERO = Mips::ZERO_64;
242 Register Dest =
I->getOperand(0).getReg();
244 Register OldVal =
I->getOperand(2).getReg();
245 Register NewVal =
I->getOperand(3).getReg();
246 Register Scratch =
I->getOperand(4).getReg();
291 LivePhysRegs LiveRegs;
297 I->eraseFromParent();
301bool MipsExpandPseudo::expandAtomicBinOpSubword(
310 unsigned LL, SC, SLT, SLTu,
OR, MOVN, MOVZ, SELNEZ, SELEQZ;
311 unsigned BEQ = Mips::BEQ;
312 unsigned SEOp = Mips::SEH;
315 LL = STI->
hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
316 SC = STI->
hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
317 BEQ = STI->
hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
319 SLTu = Mips::SLTu_MM;
321 MOVN = Mips::MOVN_I_MM;
322 MOVZ = Mips::MOVZ_I_MM;
323 SELNEZ = STI->
hasMips32r6() ? Mips::SELNEZ_MMR6 : Mips::SELNEZ;
324 SELEQZ = STI->
hasMips32r6() ? Mips::SELEQZ_MMR6 : Mips::SELEQZ;
326 LL = STI->
hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
327 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
328 SC = STI->
hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
329 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
333 MOVN = Mips::MOVN_I_I;
334 MOVZ = Mips::MOVZ_I_I;
335 SELNEZ = Mips::SELNEZ;
336 SELEQZ = Mips::SELEQZ;
343 bool IsUnsigned =
false;
347 switch (
I->getOpcode()) {
348 case Mips::ATOMIC_LOAD_NAND_I8_POSTRA:
351 case Mips::ATOMIC_LOAD_NAND_I16_POSTRA:
354 case Mips::ATOMIC_SWAP_I8_POSTRA:
357 case Mips::ATOMIC_SWAP_I16_POSTRA:
360 case Mips::ATOMIC_LOAD_ADD_I8_POSTRA:
363 case Mips::ATOMIC_LOAD_ADD_I16_POSTRA:
366 case Mips::ATOMIC_LOAD_SUB_I8_POSTRA:
369 case Mips::ATOMIC_LOAD_SUB_I16_POSTRA:
372 case Mips::ATOMIC_LOAD_AND_I8_POSTRA:
375 case Mips::ATOMIC_LOAD_AND_I16_POSTRA:
378 case Mips::ATOMIC_LOAD_OR_I8_POSTRA:
381 case Mips::ATOMIC_LOAD_OR_I16_POSTRA:
384 case Mips::ATOMIC_LOAD_XOR_I8_POSTRA:
387 case Mips::ATOMIC_LOAD_XOR_I16_POSTRA:
390 case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA:
395 case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA:
399 case Mips::ATOMIC_LOAD_MIN_I8_POSTRA:
403 case Mips::ATOMIC_LOAD_MIN_I16_POSTRA:
406 case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:
411 case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA:
415 case Mips::ATOMIC_LOAD_MAX_I8_POSTRA:
419 case Mips::ATOMIC_LOAD_MAX_I16_POSTRA:
426 Register Dest =
I->getOperand(0).getReg();
428 Register Incr =
I->getOperand(2).getReg();
430 Register Mask2 =
I->getOperand(4).getReg();
431 Register ShiftAmnt =
I->getOperand(5).getReg();
432 Register OldVal =
I->getOperand(6).getReg();
433 Register BinOpRes =
I->getOperand(7).getReg();
434 Register StoreVal =
I->getOperand(8).getReg();
439 MachineBasicBlock *loop1MBB =
nullptr;
440 MachineBasicBlock *loop2MBB =
nullptr;
488 }
else if (IsMin || IsMax) {
490 assert(
I->getNumOperands() == 10 &&
491 "Atomics min|max|umin|umax use an additional register");
492 Register Scratch4 =
I->getOperand(9).getReg();
494 unsigned SLTScratch4 = IsUnsigned ? SLTu : SLT;
495 unsigned SELIncr = IsMax ? SELNEZ : SELEQZ;
496 unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ;
497 unsigned MOVIncr = IsMax ? MOVN : MOVZ;
503 const unsigned OpMask = SEOp == Mips::SEH ? 0xffff : 0xff;
510 const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
511 const unsigned SROp = IsUnsigned ? Mips::SRL : Mips::SRA;
615 }
else if (!IsSwap) {
682 const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
692 LivePhysRegs LiveRegs;
695 assert(loop2MBB &&
"should have 2 loop blocks");
703 I->eraseFromParent();
708bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB,
717 unsigned LL, SC,
ZERO, BEQ, SLT, SLTu,
OR, MOVN, MOVZ, SELNEZ, SELEQZ;
721 LL = STI->
hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
722 SC = STI->
hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
723 BEQ = STI->
hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
725 SLTu = Mips::SLTu_MM;
727 MOVN = Mips::MOVN_I_MM;
728 MOVZ = Mips::MOVZ_I_MM;
729 SELNEZ = STI->
hasMips32r6() ? Mips::SELNEZ_MMR6 : Mips::SELNEZ;
730 SELEQZ = STI->
hasMips32r6() ? Mips::SELEQZ_MMR6 : Mips::SELEQZ;
733 ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
734 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
736 ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
737 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
742 MOVN = Mips::MOVN_I_I;
743 MOVZ = Mips::MOVZ_I_I;
744 SELNEZ = Mips::SELNEZ;
745 SELEQZ = Mips::SELEQZ;
750 LL = STI->
hasMips64r6() ? Mips::LLD_R6 : Mips::LLD;
751 SC = STI->
hasMips64r6() ? Mips::SCD_R6 : Mips::SCD;
752 ZERO = Mips::ZERO_64;
757 MOVN = Mips::MOVN_I64_I64;
758 MOVZ = Mips::MOVZ_I64_I64;
759 SELNEZ = Mips::SELNEZ64;
760 SELEQZ = Mips::SELEQZ64;
763 Register OldVal =
I->getOperand(0).getReg();
765 Register Incr =
I->getOperand(2).getReg();
766 Register Scratch =
I->getOperand(3).getReg();
776 bool IsUnsigned =
false;
778 switch (
I->getOpcode()) {
779 case Mips::ATOMIC_LOAD_ADD_I32_POSTRA:
782 case Mips::ATOMIC_LOAD_SUB_I32_POSTRA:
785 case Mips::ATOMIC_LOAD_AND_I32_POSTRA:
788 case Mips::ATOMIC_LOAD_OR_I32_POSTRA:
791 case Mips::ATOMIC_LOAD_XOR_I32_POSTRA:
794 case Mips::ATOMIC_LOAD_NAND_I32_POSTRA:
799 case Mips::ATOMIC_SWAP_I32_POSTRA:
802 case Mips::ATOMIC_LOAD_ADD_I64_POSTRA:
803 Opcode = Mips::DADDu;
805 case Mips::ATOMIC_LOAD_SUB_I64_POSTRA:
806 Opcode = Mips::DSUBu;
808 case Mips::ATOMIC_LOAD_AND_I64_POSTRA:
809 Opcode = Mips::AND64;
811 case Mips::ATOMIC_LOAD_OR_I64_POSTRA:
814 case Mips::ATOMIC_LOAD_XOR_I64_POSTRA:
815 Opcode = Mips::XOR64;
817 case Mips::ATOMIC_LOAD_NAND_I64_POSTRA:
822 case Mips::ATOMIC_SWAP_I64_POSTRA:
825 case Mips::ATOMIC_LOAD_UMIN_I32_POSTRA:
826 case Mips::ATOMIC_LOAD_UMIN_I64_POSTRA:
829 case Mips::ATOMIC_LOAD_MIN_I32_POSTRA:
830 case Mips::ATOMIC_LOAD_MIN_I64_POSTRA:
833 case Mips::ATOMIC_LOAD_UMAX_I32_POSTRA:
834 case Mips::ATOMIC_LOAD_UMAX_I64_POSTRA:
837 case Mips::ATOMIC_LOAD_MAX_I32_POSTRA:
838 case Mips::ATOMIC_LOAD_MAX_I64_POSTRA:
848 MachineBasicBlock *loop1MBB =
nullptr;
849 MachineBasicBlock *loop2MBB =
nullptr;
882 assert((OldVal !=
Ptr) &&
"Clobbered the wrong ptr reg!");
883 assert((OldVal != Incr) &&
"Clobbered the wrong reg!");
884 if (IsMin || IsMax) {
886 assert(
I->getNumOperands() == 5 &&
887 "Atomics min|max|umin|umax use an additional register");
888 MCRegister Scratch2 =
I->getOperand(4).getReg().
asMCReg();
891 MCRegister Scratch2_32 =
895 unsigned SLTScratch2 = IsUnsigned ? SLTu : SLT;
896 unsigned SELIncr = IsMax ? SELNEZ : SELEQZ;
897 unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ;
898 unsigned MOVIncr = IsMax ? MOVN : MOVZ;
902 BuildMI(loopMBB,
DL,
TII->get(SLTScratch2), Scratch2_32)
972 "Unknown nand instruction for atomic pseudo expansion");
976 assert(IsOr && OR &&
"Unknown instruction for atomic pseudo expansion!");
1002 I->eraseFromParent();
1004 LivePhysRegs LiveRegs;
1007 assert(loop2MBB &&
"should have 2 loop blocks");
1016bool MipsExpandPseudo::expandMI(MachineBasicBlock &
MBB,
1022 switch (
MBBI->getOpcode()) {
1023 case Mips::ATOMIC_CMP_SWAP_I32_POSTRA:
1024 case Mips::ATOMIC_CMP_SWAP_I64_POSTRA:
1025 return expandAtomicCmpSwap(
MBB,
MBBI, NMBB);
1026 case Mips::ATOMIC_CMP_SWAP_I8_POSTRA:
1027 case Mips::ATOMIC_CMP_SWAP_I16_POSTRA:
1028 return expandAtomicCmpSwapSubword(
MBB,
MBBI, NMBB);
1029 case Mips::ATOMIC_SWAP_I8_POSTRA:
1030 case Mips::ATOMIC_SWAP_I16_POSTRA:
1031 case Mips::ATOMIC_LOAD_NAND_I8_POSTRA:
1032 case Mips::ATOMIC_LOAD_NAND_I16_POSTRA:
1033 case Mips::ATOMIC_LOAD_ADD_I8_POSTRA:
1034 case Mips::ATOMIC_LOAD_ADD_I16_POSTRA:
1035 case Mips::ATOMIC_LOAD_SUB_I8_POSTRA:
1036 case Mips::ATOMIC_LOAD_SUB_I16_POSTRA:
1037 case Mips::ATOMIC_LOAD_AND_I8_POSTRA:
1038 case Mips::ATOMIC_LOAD_AND_I16_POSTRA:
1039 case Mips::ATOMIC_LOAD_OR_I8_POSTRA:
1040 case Mips::ATOMIC_LOAD_OR_I16_POSTRA:
1041 case Mips::ATOMIC_LOAD_XOR_I8_POSTRA:
1042 case Mips::ATOMIC_LOAD_XOR_I16_POSTRA:
1043 case Mips::ATOMIC_LOAD_MIN_I8_POSTRA:
1044 case Mips::ATOMIC_LOAD_MIN_I16_POSTRA:
1045 case Mips::ATOMIC_LOAD_MAX_I8_POSTRA:
1046 case Mips::ATOMIC_LOAD_MAX_I16_POSTRA:
1047 case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA:
1048 case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA:
1049 case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:
1050 case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA:
1051 return expandAtomicBinOpSubword(
MBB,
MBBI, NMBB);
1052 case Mips::ATOMIC_LOAD_ADD_I32_POSTRA:
1053 case Mips::ATOMIC_LOAD_SUB_I32_POSTRA:
1054 case Mips::ATOMIC_LOAD_AND_I32_POSTRA:
1055 case Mips::ATOMIC_LOAD_OR_I32_POSTRA:
1056 case Mips::ATOMIC_LOAD_XOR_I32_POSTRA:
1057 case Mips::ATOMIC_LOAD_NAND_I32_POSTRA:
1058 case Mips::ATOMIC_SWAP_I32_POSTRA:
1059 case Mips::ATOMIC_LOAD_MIN_I32_POSTRA:
1060 case Mips::ATOMIC_LOAD_MAX_I32_POSTRA:
1061 case Mips::ATOMIC_LOAD_UMIN_I32_POSTRA:
1062 case Mips::ATOMIC_LOAD_UMAX_I32_POSTRA:
1063 return expandAtomicBinOp(
MBB,
MBBI, NMBB, 4);
1064 case Mips::ATOMIC_LOAD_ADD_I64_POSTRA:
1065 case Mips::ATOMIC_LOAD_SUB_I64_POSTRA:
1066 case Mips::ATOMIC_LOAD_AND_I64_POSTRA:
1067 case Mips::ATOMIC_LOAD_OR_I64_POSTRA:
1068 case Mips::ATOMIC_LOAD_XOR_I64_POSTRA:
1069 case Mips::ATOMIC_LOAD_NAND_I64_POSTRA:
1070 case Mips::ATOMIC_SWAP_I64_POSTRA:
1071 case Mips::ATOMIC_LOAD_MIN_I64_POSTRA:
1072 case Mips::ATOMIC_LOAD_MAX_I64_POSTRA:
1073 case Mips::ATOMIC_LOAD_UMIN_I64_POSTRA:
1074 case Mips::ATOMIC_LOAD_UMAX_I64_POSTRA:
1075 return expandAtomicBinOp(
MBB,
MBBI, NMBB, 8);
1081bool MipsExpandPseudo::expandMBB(MachineBasicBlock &
MBB) {
1094bool MipsExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
1099 for (MachineBasicBlock &
MBB : MF)
1103 MF.RenumberBlocks();
1111 return new MipsExpandPseudo();
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.
Promote Memory to Register
static BranchProbability getOne()
FunctionPass class - This class is used to implement most global optimizations.
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
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 & 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
bool ArePtrs64bit() const
bool inMicroMipsMode() const
const MipsInstrInfo * getInstrInfo() const override
const MipsRegisterInfo * getRegisterInfo() const override
const MipsABIInfo & getABI() const
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
StringRef - 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.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ BasicBlock
Various leaf nodes.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ Kill
The last use of a register.
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.
void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().
FunctionPass * createMipsExpandPseudoPass()
createMipsExpandPseudoPass - returns an instance of the pseudo instruction expansion pass.