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::SR07RegClass.contains(Source))
136bool RISCVMoveMerge::isCandidateToMergeMVSA01(
const DestSourcePair &RegPair) {
140 if ((
ST->hasStdExtZcmp() ||
ST->hasVendorXqccmp()) &&
141 (Source == RISCV::X10 || Source == RISCV::X11) &&
142 RISCV::SR07RegClass.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);
293 Register ExpectedSourceReg =
TRI->getSubReg(SrcGPRPair, SecondPairIdx);
294 Register ExpectedDestReg =
TRI->getSubReg(DestGPRPair, SecondPairIdx);
299 MachineInstr &
MI = *
I;
301 if (
auto SecondPair =
TII->isCopyInstrImpl(
MI)) {
311 if (SourceReg == ExpectedSourceReg && DestReg == ExpectedDestReg)
318 if (!ModifiedRegUnits.
available(ExpectedDestReg) ||
319 !UsedRegUnits.
available(ExpectedDestReg) ||
320 !ModifiedRegUnits.
available(ExpectedSourceReg))
329 const DestSourcePair &RegPair) {
334 ModifiedRegUnits.
clear();
335 UsedRegUnits.
clear();
340 MachineInstr &
MI = *
I;
342 if (
auto SecondPair =
TII->isCopyInstrImpl(
MI)) {
346 bool IsCandidate =
MoveFromSToA ? isCandidateToMergeMVA01S(*SecondPair)
347 : isCandidateToMergeMVSA01(*SecondPair);
360 if (!ModifiedRegUnits.
available(DestReg) ||
380 ModifiedRegUnits.
clear();
381 UsedRegUnits.
clear();
382 unsigned Opc =
MBBI->getOpcode();
384 int64_t FirstImm =
MBBI->getOperand(1).getImm();
385 unsigned RegPairIdx = EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
386 unsigned SecondPairIdx =
387 !EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
390 Register DestGPRPair =
TRI->getMatchingSuperReg(FirstDestReg, RegPairIdx,
391 &RISCV::GPRPairRegClass);
392 Register ExpectedDestReg =
TRI->getSubReg(DestGPRPair, SecondPairIdx);
397 MachineInstr &
MI = *
I;
399 if (
MI.getOpcode() ==
Opc) {
401 int64_t
Imm =
MI.getOperand(1).getImm();
403 if (FirstDestReg == DestReg)
407 if (DestReg == ExpectedDestReg && Imm == FirstImm)
414 if (!ModifiedRegUnits.
available(ExpectedDestReg) ||
415 !UsedRegUnits.
available(ExpectedDestReg))
423bool RISCVMoveMerge::mergeMovePairs(MachineBasicBlock &
MBB) {
429 bool IsPLIEven = isPLIPairCandidate(*
MBBI,
true);
430 bool IsPLIOdd = isPLIPairCandidate(*
MBBI,
false);
431 if (IsPLIEven != IsPLIOdd) {
434 MBBI = mergePLIPair(
MBBI, Paired, IsPLIEven);
442 auto RegPair =
TII->isCopyInstrImpl(*
MBBI);
443 if (RegPair.has_value()) {
445 bool MoveFromAToS = isCandidateToMergeMVSA01(*RegPair);
446 bool IsEven = isGPRPairCopyCandidate(*RegPair,
true);
447 bool IsOdd = isGPRPairCopyCandidate(*RegPair,
false);
448 if (!
MoveFromSToA && !MoveFromAToS && !IsEven && !IsOdd) {
462 if (IsEven != IsOdd) {
463 Paired = findMatchingGPRPairCopy(
MBBI, IsEven, *RegPair);
465 MBBI = mergeGPRPairInsns(
MBBI, Paired, IsEven);
476bool RISCVMoveMerge::runOnMachineFunction(MachineFunction &Fn) {
481 bool HasGPRPairCopy =
482 !
ST->is64Bit() && (
ST->hasStdExtZdinx() ||
ST->hasStdExtP());
483 if (!
ST->hasStdExtZcmp() && !
ST->hasVendorXqccmp() && !HasGPRPairCopy)
486 TII =
ST->getInstrInfo();
487 TRI =
ST->getRegisterInfo();
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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