21#define RISCV_MOVE_MERGE_NAME "RISC-V Zcmp move merging pass"
64char RISCVMoveMerge::ID = 0;
72 if (ST.hasStdExtZdinx())
73 return RISCV::FSGNJ_D_IN32X;
76 return RISCV::PADD_DW;
82 if (ST.hasStdExtZcmp())
83 return MoveFromSToA ? RISCV::CM_MVA01S : RISCV::CM_MVSA01;
85 if (ST.hasVendorXqccmp())
86 return MoveFromSToA ? RISCV::QC_CM_MVA01S : RISCV::QC_CM_MVSA01;
91bool RISCVMoveMerge::isGPRPairCopyCandidateEven(
const DestSourcePair &RegPair) {
95 if (Source == Destination)
98 if ((!ST->hasStdExtZdinx() && !ST->hasStdExtP()) || ST->
is64Bit())
100 Register SrcPair =
TRI->getMatchingSuperReg(Source, RISCV::sub_gpr_even,
101 &RISCV::GPRPairRegClass);
102 Register DestPair =
TRI->getMatchingSuperReg(Destination, RISCV::sub_gpr_even,
103 &RISCV::GPRPairRegClass);
108bool RISCVMoveMerge::isGPRPairCopyCandidateOdd(
const DestSourcePair &RegPair) {
112 if (Source == Destination)
115 if ((!ST->hasStdExtZdinx() && !ST->hasStdExtP()) || ST->
is64Bit())
117 Register SrcPair =
TRI->getMatchingSuperReg(Source, RISCV::sub_gpr_odd,
118 &RISCV::GPRPairRegClass);
119 Register DestPair =
TRI->getMatchingSuperReg(Destination, RISCV::sub_gpr_odd,
120 &RISCV::GPRPairRegClass);
126bool RISCVMoveMerge::isCandidateToMergeMVA01S(
const DestSourcePair &RegPair) {
130 if ((ST->hasStdExtZcmp() || ST->hasVendorXqccmp()) &&
131 (Destination == RISCV::X10 || Destination == RISCV::X11) &&
132 RISCV::SR07RegClass.contains(Source))
138bool RISCVMoveMerge::isCandidateToMergeMVSA01(
const DestSourcePair &RegPair) {
142 if ((ST->hasStdExtZcmp() || ST->hasVendorXqccmp()) &&
143 (Source == RISCV::X10 || Source == RISCV::X11) &&
144 RISCV::SR07RegClass.contains(Destination))
152 bool RegPairIsEven) {
155 DestSourcePair FirstPair =
TII->isCopyInstrImpl(*I).value();
156 DestSourcePair SecondPair =
TII->isCopyInstrImpl(*Paired).value();
164 MachineOperand PairedSource = *SecondPair.
Source;
166 unsigned Opcode = getGPRPairCopyOpcode(*ST);
167 for (
auto It = std::next(
I); It != Paired && PairedSource.
isKill(); ++It)
168 if (It->readsRegister(PairedSource.
getReg(),
TRI))
172 unsigned GPRPairIdx =
173 RegPairIsEven ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
174 SrcReg1 =
TRI->getMatchingSuperReg(FirstPair.
Source->
getReg(), GPRPairIdx,
175 &RISCV::GPRPairRegClass);
176 SrcReg2 = ST->hasStdExtZdinx() ? SrcReg1 :
Register(RISCV::X0_Pair);
178 GPRPairIdx, &RISCV::GPRPairRegClass);
187 Paired->eraseFromParent();
195 const MachineOperand *Sreg1, *Sreg2;
198 DestSourcePair FirstPair =
TII->isCopyInstrImpl(*I).value();
199 DestSourcePair PairedRegs =
TII->isCopyInstrImpl(*Paired).value();
208 MachineOperand PairedSource = *PairedRegs.
Source;
223 for (
auto It = std::next(
I); It != Paired && PairedSource.
isKill(); ++It)
224 if (It->readsRegister(PairedSource.
getReg(),
TRI))
228 Sreg2 = &PairedSource;
241 Paired->eraseFromParent();
248 const DestSourcePair &RegPair) {
250 ModifiedRegUnits.
clear();
251 UsedRegUnits.
clear();
256 MachineInstr &
MI = *
I;
258 if (
auto SecondPair =
TII->isCopyInstrImpl(
MI)) {
266 unsigned RegPairIdx =
267 EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
268 unsigned SecondPairIdx =
269 !EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
273 RegPair.
Source->
getReg(), RegPairIdx, &RISCV::GPRPairRegClass);
280 if (SourceReg !=
TRI->getSubReg(SrcGPRPair, SecondPairIdx) ||
281 DestReg !=
TRI->getSubReg(DestGPRPair, SecondPairIdx))
284 if (!ModifiedRegUnits.
available(DestReg) ||
300 const DestSourcePair &RegPair) {
305 ModifiedRegUnits.
clear();
306 UsedRegUnits.
clear();
311 MachineInstr &
MI = *
I;
313 if (
auto SecondPair =
TII->isCopyInstrImpl(
MI)) {
317 bool IsCandidate = MoveFromSToA ? isCandidateToMergeMVA01S(*SecondPair)
318 : isCandidateToMergeMVSA01(*SecondPair);
325 if (!MoveFromSToA && RegPair.
Source->
getReg() == SourceReg)
331 if (!ModifiedRegUnits.
available(DestReg) ||
347bool RISCVMoveMerge::mergeMoveSARegPair(MachineBasicBlock &
MBB) {
354 auto RegPair =
TII->isCopyInstrImpl(*
MBBI);
355 if (RegPair.has_value()) {
356 bool MoveFromSToA = isCandidateToMergeMVA01S(*RegPair);
357 bool IsEven = isGPRPairCopyCandidateEven(*RegPair);
358 bool IsOdd = isGPRPairCopyCandidateOdd(*RegPair);
359 if (!MoveFromSToA && !isCandidateToMergeMVSA01(*RegPair) && !IsEven &&
366 if (ST->hasStdExtZcmp() || ST->hasVendorXqccmp()) {
367 Paired = findMatchingInst(
MBBI, MoveFromSToA, RegPair.value());
369 MBBI = mergePairedInsns(
MBBI, Paired, MoveFromSToA);
374 if (IsEven != IsOdd) {
375 Paired = findMatchingInstPair(
MBBI, IsEven, RegPair.value());
377 MBBI = mergeGPRPairInsns(
MBBI, Paired, IsEven);
388bool RISCVMoveMerge::runOnMachineFunction(MachineFunction &Fn) {
393 bool HasGPRPairCopy =
394 !ST->
is64Bit() && (ST->hasStdExtZdinx() || ST->hasStdExtP());
395 if (!ST->hasStdExtZcmp() && !ST->hasVendorXqccmp() && !HasGPRPairCopy)
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)
static unsigned getCM_MVOpcode(const RISCVSubtarget &ST, bool MoveFromSToA)
#define RISCV_MOVE_MERGE_NAME
FunctionPass class - This class is used to implement most global optimizations.
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 & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
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.
const RISCVRegisterInfo * getRegisterInfo() const override
const RISCVInstrInfo * getInstrInfo() const override
constexpr bool isValid() const
StringRef - 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.
constexpr RegState getKillRegState(bool B)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
const MachineOperand * Source
const MachineOperand * Destination