30#define DEBUG_TYPE "mips-pseudo"
45 MachineFunctionProperties::Property::NoVRegs);
49 return "Mips pseudo instruction expansion pass";
71 char MipsExpandPseudo::ID = 0;
74bool MipsExpandPseudo::expandAtomicCmpSwapSubword(
80 const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
84 unsigned ZERO = Mips::ZERO;
85 unsigned BNE = Mips::BNE;
86 unsigned BEQ = Mips::BEQ;
88 I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I8_POSTRA ? Mips::SEB : Mips::SEH;
90 if (STI->inMicroMipsMode()) {
91 LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
92 SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
93 BNE = STI->hasMips32r6() ? Mips::BNEC_MMR6 : Mips::BNE_MM;
94 BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
96 LL = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
97 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
98 SC = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
99 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
102 Register Dest =
I->getOperand(0).getReg();
105 Register ShiftCmpVal =
I->getOperand(3).getReg();
106 Register Mask2 =
I->getOperand(4).getReg();
107 Register ShiftNewVal =
I->getOperand(5).getReg();
108 Register ShiftAmnt =
I->getOperand(6).getReg();
109 Register Scratch =
I->getOperand(7).getReg();
110 Register Scratch2 =
I->getOperand(8).getReg();
178 if (STI->hasMips32r2()) {
181 const unsigned ShiftImm =
182 I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I16_POSTRA ? 16 : 24;
198 I->eraseFromParent();
206 const unsigned Size =
207 I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I32_POSTRA ? 4 : 8;
210 const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
213 unsigned LL,
SC,
ZERO, BNE, BEQ, MOVE;
216 if (STI->inMicroMipsMode()) {
217 LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
218 SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
219 BNE = STI->hasMips32r6() ? Mips::BNEC_MMR6 : Mips::BNE_MM;
220 BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
222 LL = STI->hasMips32r6()
223 ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
224 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
225 SC = STI->hasMips32r6()
226 ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
227 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
235 LL = STI->hasMips64r6() ? Mips::LLD_R6 : Mips::LLD;
236 SC = STI->hasMips64r6() ? Mips::SCD_R6 : Mips::SCD;
237 ZERO = Mips::ZERO_64;
243 Register Dest =
I->getOperand(0).getReg();
245 Register OldVal =
I->getOperand(2).getReg();
246 Register NewVal =
I->getOperand(3).getReg();
247 Register Scratch =
I->getOperand(4).getReg();
298 I->eraseFromParent();
302bool MipsExpandPseudo::expandAtomicBinOpSubword(
308 const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
311 unsigned LL,
SC, SLT, SLTu,
OR, MOVN, MOVZ, SELNEZ, SELEQZ;
312 unsigned BEQ = Mips::BEQ;
313 unsigned SEOp = Mips::SEH;
315 if (STI->inMicroMipsMode()) {
316 LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
317 SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
318 BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
320 SLTu = Mips::SLTu_MM;
321 OR = STI->hasMips32r6() ? Mips::OR_MMR6 : Mips::OR_MM;
322 MOVN = Mips::MOVN_I_MM;
323 MOVZ = Mips::MOVZ_I_MM;
324 SELNEZ = STI->hasMips32r6() ? Mips::SELNEZ_MMR6 : Mips::SELNEZ;
325 SELEQZ = STI->hasMips32r6() ? Mips::SELEQZ_MMR6 : Mips::SELEQZ;
327 LL = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
328 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
329 SC = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
330 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
334 MOVN = Mips::MOVN_I_I;
335 MOVZ = Mips::MOVZ_I_I;
336 SELNEZ = Mips::SELNEZ;
337 SELEQZ = Mips::SELEQZ;
344 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:
394 case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA:
398 case Mips::ATOMIC_LOAD_MIN_I8_POSTRA:
402 case Mips::ATOMIC_LOAD_MIN_I16_POSTRA:
405 case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:
409 case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA:
413 case Mips::ATOMIC_LOAD_MAX_I8_POSTRA:
417 case Mips::ATOMIC_LOAD_MAX_I16_POSTRA:
424 Register Dest =
I->getOperand(0).getReg();
426 Register Incr =
I->getOperand(2).getReg();
428 Register Mask2 =
I->getOperand(4).getReg();
429 Register ShiftAmnt =
I->getOperand(5).getReg();
430 Register OldVal =
I->getOperand(6).getReg();
431 Register BinOpRes =
I->getOperand(7).getReg();
432 Register StoreVal =
I->getOperand(8).getReg();
465 }
else if (IsMin || IsMax) {
467 assert(
I->getNumOperands() == 10 &&
468 "Atomics min|max|umin|umax use an additional register");
469 Register Scratch4 =
I->getOperand(9).getReg();
471 unsigned SLTScratch4 = IsUnsigned ? SLTu : SLT;
472 unsigned SELIncr = IsMax ? SELNEZ : SELEQZ;
473 unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ;
474 unsigned MOVIncr = IsMax ? MOVN : MOVZ;
477 if (STI->isLittle()) {
485 if (STI->hasMips32r2()) {
489 const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
520 if (STI->hasMips64r6() || STI->hasMips32r6()) {
555 }
else if (!IsSwap) {
596 if (STI->hasMips32r2()) {
599 const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
614 I->eraseFromParent();
625 const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
628 unsigned LL,
SC,
ZERO, BEQ, SLT, SLTu,
OR, MOVN, MOVZ, SELNEZ, SELEQZ;
631 if (STI->inMicroMipsMode()) {
632 LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
633 SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
634 BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
636 SLTu = Mips::SLTu_MM;
637 OR = STI->hasMips32r6() ? Mips::OR_MMR6 : Mips::OR_MM;
638 MOVN = Mips::MOVN_I_MM;
639 MOVZ = Mips::MOVZ_I_MM;
640 SELNEZ = STI->hasMips32r6() ? Mips::SELNEZ_MMR6 : Mips::SELNEZ;
641 SELEQZ = STI->hasMips32r6() ? Mips::SELEQZ_MMR6 : Mips::SELEQZ;
643 LL = STI->hasMips32r6()
644 ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
645 : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
646 SC = STI->hasMips32r6()
647 ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
648 : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
653 MOVN = Mips::MOVN_I_I;
654 MOVZ = Mips::MOVZ_I_I;
655 SELNEZ = Mips::SELNEZ;
656 SELEQZ = Mips::SELEQZ;
661 LL = STI->hasMips64r6() ? Mips::LLD_R6 : Mips::LLD;
662 SC = STI->hasMips64r6() ? Mips::SCD_R6 : Mips::SCD;
663 ZERO = Mips::ZERO_64;
668 MOVN = Mips::MOVN_I64_I64;
669 MOVZ = Mips::MOVZ_I64_I64;
670 SELNEZ = Mips::SELNEZ64;
671 SELEQZ = Mips::SELEQZ64;
674 Register OldVal =
I->getOperand(0).getReg();
676 Register Incr =
I->getOperand(2).getReg();
677 Register Scratch =
I->getOperand(3).getReg();
687 bool IsUnsigned =
false;
689 switch (
I->getOpcode()) {
690 case Mips::ATOMIC_LOAD_ADD_I32_POSTRA:
693 case Mips::ATOMIC_LOAD_SUB_I32_POSTRA:
696 case Mips::ATOMIC_LOAD_AND_I32_POSTRA:
699 case Mips::ATOMIC_LOAD_OR_I32_POSTRA:
702 case Mips::ATOMIC_LOAD_XOR_I32_POSTRA:
705 case Mips::ATOMIC_LOAD_NAND_I32_POSTRA:
710 case Mips::ATOMIC_SWAP_I32_POSTRA:
713 case Mips::ATOMIC_LOAD_ADD_I64_POSTRA:
714 Opcode = Mips::DADDu;
716 case Mips::ATOMIC_LOAD_SUB_I64_POSTRA:
717 Opcode = Mips::DSUBu;
719 case Mips::ATOMIC_LOAD_AND_I64_POSTRA:
720 Opcode = Mips::AND64;
722 case Mips::ATOMIC_LOAD_OR_I64_POSTRA:
725 case Mips::ATOMIC_LOAD_XOR_I64_POSTRA:
726 Opcode = Mips::XOR64;
728 case Mips::ATOMIC_LOAD_NAND_I64_POSTRA:
733 case Mips::ATOMIC_SWAP_I64_POSTRA:
736 case Mips::ATOMIC_LOAD_UMIN_I32_POSTRA:
737 case Mips::ATOMIC_LOAD_UMIN_I64_POSTRA:
740 case Mips::ATOMIC_LOAD_MIN_I32_POSTRA:
741 case Mips::ATOMIC_LOAD_MIN_I64_POSTRA:
744 case Mips::ATOMIC_LOAD_UMAX_I32_POSTRA:
745 case Mips::ATOMIC_LOAD_UMAX_I64_POSTRA:
748 case Mips::ATOMIC_LOAD_MAX_I32_POSTRA:
749 case Mips::ATOMIC_LOAD_MAX_I64_POSTRA:
772 assert((OldVal !=
Ptr) &&
"Clobbered the wrong ptr reg!");
773 assert((OldVal != Incr) &&
"Clobbered the wrong reg!");
774 if (IsMin || IsMax) {
776 assert(
I->getNumOperands() == 5 &&
777 "Atomics min|max|umin|umax use an additional register");
778 MCRegister Scratch2 =
I->getOperand(4).getReg().asMCReg();
782 (
Size == 8) ? STI->getRegisterInfo()->getSubReg(Scratch2, Mips::sub_32)
785 unsigned SLTScratch2 = IsUnsigned ? SLTu : SLT;
786 unsigned SELIncr = IsMax ? SELNEZ : SELEQZ;
787 unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ;
788 unsigned MOVIncr = IsMax ? MOVN : MOVZ;
792 BuildMI(loopMBB,
DL,
TII->get(SLTScratch2), Scratch2_32)
796 if (STI->hasMips64r6() || STI->hasMips32r6()) {
830 "Unknown nand instruction for atomic pseudo expansion");
834 assert(IsOr && OR &&
"Unknown instruction for atomic pseudo expansion!");
849 I->eraseFromParent();
864 switch (
MBBI->getOpcode()) {
865 case Mips::ATOMIC_CMP_SWAP_I32_POSTRA:
866 case Mips::ATOMIC_CMP_SWAP_I64_POSTRA:
867 return expandAtomicCmpSwap(
MBB,
MBBI, NMBB);
868 case Mips::ATOMIC_CMP_SWAP_I8_POSTRA:
869 case Mips::ATOMIC_CMP_SWAP_I16_POSTRA:
870 return expandAtomicCmpSwapSubword(
MBB,
MBBI, NMBB);
871 case Mips::ATOMIC_SWAP_I8_POSTRA:
872 case Mips::ATOMIC_SWAP_I16_POSTRA:
873 case Mips::ATOMIC_LOAD_NAND_I8_POSTRA:
874 case Mips::ATOMIC_LOAD_NAND_I16_POSTRA:
875 case Mips::ATOMIC_LOAD_ADD_I8_POSTRA:
876 case Mips::ATOMIC_LOAD_ADD_I16_POSTRA:
877 case Mips::ATOMIC_LOAD_SUB_I8_POSTRA:
878 case Mips::ATOMIC_LOAD_SUB_I16_POSTRA:
879 case Mips::ATOMIC_LOAD_AND_I8_POSTRA:
880 case Mips::ATOMIC_LOAD_AND_I16_POSTRA:
881 case Mips::ATOMIC_LOAD_OR_I8_POSTRA:
882 case Mips::ATOMIC_LOAD_OR_I16_POSTRA:
883 case Mips::ATOMIC_LOAD_XOR_I8_POSTRA:
884 case Mips::ATOMIC_LOAD_XOR_I16_POSTRA:
885 case Mips::ATOMIC_LOAD_MIN_I8_POSTRA:
886 case Mips::ATOMIC_LOAD_MIN_I16_POSTRA:
887 case Mips::ATOMIC_LOAD_MAX_I8_POSTRA:
888 case Mips::ATOMIC_LOAD_MAX_I16_POSTRA:
889 case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA:
890 case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA:
891 case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:
892 case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA:
893 return expandAtomicBinOpSubword(
MBB,
MBBI, NMBB);
894 case Mips::ATOMIC_LOAD_ADD_I32_POSTRA:
895 case Mips::ATOMIC_LOAD_SUB_I32_POSTRA:
896 case Mips::ATOMIC_LOAD_AND_I32_POSTRA:
897 case Mips::ATOMIC_LOAD_OR_I32_POSTRA:
898 case Mips::ATOMIC_LOAD_XOR_I32_POSTRA:
899 case Mips::ATOMIC_LOAD_NAND_I32_POSTRA:
900 case Mips::ATOMIC_SWAP_I32_POSTRA:
901 case Mips::ATOMIC_LOAD_MIN_I32_POSTRA:
902 case Mips::ATOMIC_LOAD_MAX_I32_POSTRA:
903 case Mips::ATOMIC_LOAD_UMIN_I32_POSTRA:
904 case Mips::ATOMIC_LOAD_UMAX_I32_POSTRA:
905 return expandAtomicBinOp(
MBB,
MBBI, NMBB, 4);
906 case Mips::ATOMIC_LOAD_ADD_I64_POSTRA:
907 case Mips::ATOMIC_LOAD_SUB_I64_POSTRA:
908 case Mips::ATOMIC_LOAD_AND_I64_POSTRA:
909 case Mips::ATOMIC_LOAD_OR_I64_POSTRA:
910 case Mips::ATOMIC_LOAD_XOR_I64_POSTRA:
911 case Mips::ATOMIC_LOAD_NAND_I64_POSTRA:
912 case Mips::ATOMIC_SWAP_I64_POSTRA:
913 case Mips::ATOMIC_LOAD_MIN_I64_POSTRA:
914 case Mips::ATOMIC_LOAD_MAX_I64_POSTRA:
915 case Mips::ATOMIC_LOAD_UMIN_I64_POSTRA:
916 case Mips::ATOMIC_LOAD_UMAX_I64_POSTRA:
917 return expandAtomicBinOp(
MBB,
MBBI, NMBB, 8);
938 TII = STI->getInstrInfo();
953 return new MipsExpandPseudo();
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
@ ZERO
Special weight used for cases with exact zero probability.
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Basic Block Representation.
static 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.
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.
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...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
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
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.
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.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
@ 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.