21#define RISCV_MOVE_MERGE_NAME "RISC-V Zcmp move merging pass"
36 bool isGPRPairCopyCandidate(
const DestSourcePair &RegPair,
bool EvenRegPair);
63char RISCVMoveMerge::ID = 0;
71 if (ST.hasStdExtZdinx())
72 return RISCV::FSGNJ_D_IN32X;
75 return RISCV::PADD_DW;
81 if (ST.hasStdExtZcmp())
82 return MoveFromSToA ? RISCV::CM_MVA01S : RISCV::CM_MVSA01;
84 if (ST.hasVendorXqccmp())
85 return MoveFromSToA ? RISCV::QC_CM_MVA01S : RISCV::QC_CM_MVSA01;
90bool RISCVMoveMerge::isGPRPairCopyCandidate(
const DestSourcePair &RegPair,
95 if (Source == Destination)
98 if ((!ST->hasStdExtZdinx() && !ST->hasStdExtP()) || ST->
is64Bit())
101 unsigned SubIdx = EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
104 TRI->getMatchingSuperReg(Source, SubIdx, &RISCV::GPRPairRegClass);
106 TRI->getMatchingSuperReg(Destination, SubIdx, &RISCV::GPRPairRegClass);
112bool RISCVMoveMerge::isCandidateToMergeMVA01S(
const DestSourcePair &RegPair) {
116 if ((ST->hasStdExtZcmp() || ST->hasVendorXqccmp()) &&
117 (Destination == RISCV::X10 || Destination == RISCV::X11) &&
118 RISCV::SR07RegClass.contains(Source))
124bool RISCVMoveMerge::isCandidateToMergeMVSA01(
const DestSourcePair &RegPair) {
128 if ((ST->hasStdExtZcmp() || ST->hasVendorXqccmp()) &&
129 (Source == RISCV::X10 || Source == RISCV::X11) &&
130 RISCV::SR07RegClass.contains(Destination))
138 bool RegPairIsEven) {
141 DestSourcePair FirstPair = *
TII->isCopyInstrImpl(*
I);
142 DestSourcePair SecondPair = *
TII->isCopyInstrImpl(*Paired);
150 MachineOperand PairedSource = *SecondPair.
Source;
152 unsigned Opcode = getGPRPairCopyOpcode(*ST);
153 for (
auto It = std::next(
I); It != Paired && PairedSource.
isKill(); ++It)
154 if (It->readsRegister(PairedSource.
getReg(),
TRI))
158 unsigned GPRPairIdx =
159 RegPairIsEven ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
160 SrcReg1 =
TRI->getMatchingSuperReg(FirstPair.
Source->
getReg(), GPRPairIdx,
161 &RISCV::GPRPairRegClass);
162 SrcReg2 = ST->hasStdExtZdinx() ? SrcReg1 :
Register(RISCV::X0_Pair);
164 GPRPairIdx, &RISCV::GPRPairRegClass);
173 Paired->eraseFromParent();
181 const MachineOperand *Sreg1, *Sreg2;
184 DestSourcePair FirstPair = *
TII->isCopyInstrImpl(*
I);
185 DestSourcePair PairedRegs = *
TII->isCopyInstrImpl(*Paired);
194 MachineOperand PairedSource = *PairedRegs.
Source;
209 for (
auto It = std::next(
I); It != Paired && PairedSource.
isKill(); ++It)
210 if (It->readsRegister(PairedSource.
getReg(),
TRI))
214 Sreg2 = &PairedSource;
227 Paired->eraseFromParent();
234 const DestSourcePair &RegPair) {
236 ModifiedRegUnits.
clear();
237 UsedRegUnits.
clear();
238 unsigned RegPairIdx = EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
239 unsigned SecondPairIdx =
240 !EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
244 RegPair.
Source->
getReg(), RegPairIdx, &RISCV::GPRPairRegClass);
247 Register ExpectedSourceReg =
TRI->getSubReg(SrcGPRPair, SecondPairIdx);
248 Register ExpectedDestReg =
TRI->getSubReg(DestGPRPair, SecondPairIdx);
253 MachineInstr &
MI = *
I;
255 if (
auto SecondPair =
TII->isCopyInstrImpl(
MI)) {
265 if (SourceReg == ExpectedSourceReg && DestReg == ExpectedDestReg)
272 if (!ModifiedRegUnits.
available(ExpectedDestReg) ||
273 !UsedRegUnits.
available(ExpectedDestReg) ||
274 !ModifiedRegUnits.
available(ExpectedSourceReg))
283 const DestSourcePair &RegPair) {
288 ModifiedRegUnits.
clear();
289 UsedRegUnits.
clear();
294 MachineInstr &
MI = *
I;
296 if (
auto SecondPair =
TII->isCopyInstrImpl(
MI)) {
300 bool IsCandidate = MoveFromSToA ? isCandidateToMergeMVA01S(*SecondPair)
301 : isCandidateToMergeMVSA01(*SecondPair);
308 if (!MoveFromSToA && RegPair.
Source->
getReg() == SourceReg)
314 if (!ModifiedRegUnits.
available(DestReg) ||
330bool RISCVMoveMerge::mergeMoveSARegPair(MachineBasicBlock &
MBB) {
337 auto RegPair =
TII->isCopyInstrImpl(*
MBBI);
338 if (RegPair.has_value()) {
339 bool MoveFromSToA = isCandidateToMergeMVA01S(*RegPair);
340 bool MoveFromAToS = isCandidateToMergeMVSA01(*RegPair);
341 bool IsEven = isGPRPairCopyCandidate(*RegPair,
true);
342 bool IsOdd = isGPRPairCopyCandidate(*RegPair,
false);
343 if (!MoveFromSToA && !MoveFromAToS && !IsEven && !IsOdd) {
349 if (MoveFromSToA || MoveFromAToS) {
350 Paired = findMatchingInst(
MBBI, MoveFromSToA, *RegPair);
352 MBBI = mergePairedInsns(
MBBI, Paired, MoveFromSToA);
357 if (IsEven != IsOdd) {
358 Paired = findMatchingInstPair(
MBBI, IsEven, *RegPair);
360 MBBI = mergeGPRPairInsns(
MBBI, Paired, IsEven);
371bool RISCVMoveMerge::runOnMachineFunction(MachineFunction &Fn) {
376 bool HasGPRPairCopy =
377 !ST->
is64Bit() && (ST->hasStdExtZdinx() || ST->hasStdExtP());
378 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
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