21#define RISCV_MOVE_MERGE_NAME "RISC-V Zcmp move merging pass"
36 bool isGPRPairCopyCandidate(
const DestSourcePair &RegPair,
bool EvenRegPair);
71char RISCVMoveMerge::ID = 0;
79 if (ST.hasStdExtZcmp())
80 return MoveFromSToA ? RISCV::CM_MVA01S : RISCV::CM_MVSA01;
82 if (ST.hasVendorXqccmp())
83 return MoveFromSToA ? RISCV::QC_CM_MVA01S : RISCV::QC_CM_MVSA01;
96 return RISCV::PLUI_DH;
102bool RISCVMoveMerge::isGPRPairCopyCandidate(
const DestSourcePair &RegPair,
107 if (Source == Destination)
110 if ((!
ST->hasStdExtZdinx() && !
ST->hasStdExtP()) ||
ST->is64Bit())
113 unsigned SubIdx = EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
116 TRI->getMatchingSuperReg(Source, SubIdx, &RISCV::GPRPairRegClass);
118 TRI->getMatchingSuperReg(Destination, SubIdx, &RISCV::GPRPairRegClass);
124bool RISCVMoveMerge::isCandidateToMergeMVA01S(
const DestSourcePair &RegPair) {
128 if ((
ST->hasStdExtZcmp() ||
ST->hasVendorXqccmp()) &&
129 (Destination == RISCV::X10 || Destination == RISCV::X11) &&
130 RISCV::GPRS07RegClass.contains(Source))
136bool RISCVMoveMerge::isCandidateToMergeMVSA01(
const DestSourcePair &RegPair) {
140 if ((
ST->hasStdExtZcmp() ||
ST->hasVendorXqccmp()) &&
141 (Source == RISCV::X10 || Source == RISCV::X11) &&
142 RISCV::GPRS07RegClass.contains(Destination))
149bool RISCVMoveMerge::isPLIPairCandidate(
const MachineInstr &
MI,
151 if (!
ST->hasStdExtP() ||
ST->is64Bit())
155 unsigned SubIdx = EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
157 ->getMatchingSuperReg(
MI.getOperand(0).getReg(), SubIdx,
158 &RISCV::GPRPairRegClass)
165 bool RegPairIsEven) {
168 DestSourcePair FirstPair = *
TII->isCopyInstrImpl(*
I);
169 DestSourcePair SecondPair = *
TII->isCopyInstrImpl(*Paired);
177 MachineOperand PairedSource = *SecondPair.
Source;
179 for (
auto It = std::next(
I); It != Paired && PairedSource.
isKill(); ++It)
180 if (It->readsRegister(PairedSource.
getReg(),
TRI))
183 unsigned GPRPairIdx =
184 RegPairIsEven ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
185 MCRegister SrcReg =
TRI->getMatchingSuperReg(
186 FirstPair.
Source->
getReg(), GPRPairIdx, &RISCV::GPRPairRegClass);
187 MCRegister DestReg =
TRI->getMatchingSuperReg(
193 I->eraseFromParent();
194 Paired->eraseFromParent();
202 const MachineOperand *Sreg1, *Sreg2;
205 DestSourcePair FirstPair = *
TII->isCopyInstrImpl(*
I);
206 DestSourcePair PairedRegs = *
TII->isCopyInstrImpl(*Paired);
215 MachineOperand PairedSource = *PairedRegs.
Source;
230 for (
auto It = std::next(
I); It != Paired && PairedSource.
isKill(); ++It)
231 if (It->readsRegister(PairedSource.
getReg(),
TRI))
235 Sreg2 = &PairedSource;
248 Paired->eraseFromParent();
255 bool RegPairIsEven) {
264 unsigned GPRPairIdx =
265 RegPairIsEven ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
267 I->getOperand(0).getReg(), GPRPairIdx, &RISCV::GPRPairRegClass);
270 .
addImm(
I->getOperand(1).getImm());
273 Paired->eraseFromParent();
280 const DestSourcePair &RegPair) {
282 ModifiedRegUnits.
clear();
283 UsedRegUnits.
clear();
284 unsigned RegPairIdx = EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
285 unsigned SecondPairIdx =
286 !EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
290 RegPair.
Source->
getReg(), RegPairIdx, &RISCV::GPRPairRegClass);
297 Register ExpectedSourceReg =
TRI->getSubReg(SrcGPRPair, SecondPairIdx);
298 Register ExpectedDestReg =
TRI->getSubReg(DestGPRPair, SecondPairIdx);
306 MachineInstr &
MI = *
I;
308 if (
auto SecondPair =
TII->isCopyInstrImpl(
MI)) {
318 if (SourceReg == ExpectedSourceReg && DestReg == ExpectedDestReg)
325 if (!ModifiedRegUnits.
available(ExpectedDestReg) ||
326 !UsedRegUnits.
available(ExpectedDestReg) ||
327 !ModifiedRegUnits.
available(ExpectedSourceReg))
336 const DestSourcePair &RegPair) {
341 ModifiedRegUnits.
clear();
342 UsedRegUnits.
clear();
347 MachineInstr &
MI = *
I;
349 if (
auto SecondPair =
TII->isCopyInstrImpl(
MI)) {
353 bool IsCandidate =
MoveFromSToA ? isCandidateToMergeMVA01S(*SecondPair)
354 : isCandidateToMergeMVSA01(*SecondPair);
367 if (!ModifiedRegUnits.
available(DestReg) ||
387 ModifiedRegUnits.
clear();
388 UsedRegUnits.
clear();
389 unsigned Opc =
MBBI->getOpcode();
391 int64_t FirstImm =
MBBI->getOperand(1).getImm();
392 unsigned RegPairIdx = EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
393 unsigned SecondPairIdx =
394 !EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
397 Register DestGPRPair =
TRI->getMatchingSuperReg(FirstDestReg, RegPairIdx,
398 &RISCV::GPRPairRegClass);
400 Register ExpectedDestReg =
TRI->getSubReg(DestGPRPair, SecondPairIdx);
406 MachineInstr &
MI = *
I;
408 if (
MI.getOpcode() ==
Opc) {
410 int64_t
Imm =
MI.getOperand(1).getImm();
412 if (FirstDestReg == DestReg)
416 if (DestReg == ExpectedDestReg &&
Imm == FirstImm)
423 if (!ModifiedRegUnits.
available(ExpectedDestReg) ||
424 !UsedRegUnits.
available(ExpectedDestReg))
432bool RISCVMoveMerge::mergeMovePairs(MachineBasicBlock &
MBB) {
438 bool IsPLIEven = isPLIPairCandidate(*
MBBI,
true);
439 bool IsPLIOdd = isPLIPairCandidate(*
MBBI,
false);
440 if (IsPLIEven != IsPLIOdd) {
443 MBBI = mergePLIPair(
MBBI, Paired, IsPLIEven);
451 auto RegPair =
TII->isCopyInstrImpl(*
MBBI);
452 if (RegPair.has_value()) {
454 bool MoveFromAToS = isCandidateToMergeMVSA01(*RegPair);
455 bool IsEven = isGPRPairCopyCandidate(*RegPair,
true);
456 bool IsOdd = isGPRPairCopyCandidate(*RegPair,
false);
457 if (!
MoveFromSToA && !MoveFromAToS && !IsEven && !IsOdd) {
471 if (IsEven != IsOdd) {
472 Paired = findMatchingGPRPairCopy(
MBBI, IsEven, *RegPair);
474 MBBI = mergeGPRPairInsns(
MBBI, Paired, IsEven);
490 bool HasGPRPairCopy =
491 !
ST->is64Bit() && (
ST->hasStdExtZdinx() ||
ST->hasStdExtP());
492 if (!
ST->hasStdExtZcmp() && !
ST->hasVendorXqccmp() && !HasGPRPairCopy)
495 TII =
ST->getInstrInfo();
496 TRI =
ST->getRegisterInfo();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
#define RISCV_MOVE_MERGE_NAME
static unsigned getPairedPLIOpcode(unsigned Opc)
FunctionPass class - This class is used to implement most global optimizations.
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
Emit instructions to copy a pair of physical registers.
A set of register units used to track register liveness.
static void accumulateUsedDefed(const MachineInstr &MI, LiveRegUnits &ModifiedRegUnits, LiveRegUnits &UsedRegUnits, const TargetRegisterInfo *TRI)
For a machine instruction MI, adds all register units used in UsedRegUnits and defined or clobbered i...
bool available(MCRegister Reg) const
Returns true if no part of physical register Reg is live.
void init(const TargetRegisterInfo &TRI)
Initialize and clear the set.
void clear()
Clears the set.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
Representation of each machine instruction.
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
void setIsKill(bool Val=true)
Register getReg() const
getReg - Returns the register number.
constexpr bool isValid() const
Represent a constant reference to a string, i.e.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#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.
IterT next_nodbg(IterT It, IterT End, bool SkipPseudoOp=true)
Increment It, then continue incrementing it while it points to a debug instruction.
FunctionPass * createRISCVMoveMergePass()
createRISCVMoveMergePass - returns an instance of the move merge pass.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
const MachineOperand * Source
const MachineOperand * Destination