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::isEvenRegisterCopy(
const DestSourcePair &RegPair) {
95 if (Source == Destination)
98 Register SrcPair =
TRI->getMatchingSuperReg(Source, RISCV::sub_gpr_even,
99 &RISCV::GPRPairRegClass);
100 Register DestPair =
TRI->getMatchingSuperReg(Destination, RISCV::sub_gpr_even,
101 &RISCV::GPRPairRegClass);
106bool RISCVMoveMerge::isOddRegisterCopy(
const DestSourcePair &RegPair) {
110 if (Source == Destination)
113 Register SrcPair =
TRI->getMatchingSuperReg(Source, RISCV::sub_gpr_odd,
114 &RISCV::GPRPairRegClass);
115 Register DestPair =
TRI->getMatchingSuperReg(Destination, RISCV::sub_gpr_odd,
116 &RISCV::GPRPairRegClass);
122bool RISCVMoveMerge::isCandidateToMergeMVA01S(
const DestSourcePair &RegPair) {
126 if ((ST->hasStdExtZcmp() || ST->hasVendorXqccmp()) &&
127 (Destination == RISCV::X10 || Destination == RISCV::X11) &&
128 RISCV::SR07RegClass.contains(Source))
134bool RISCVMoveMerge::isCandidateToMergeMVSA01(
const DestSourcePair &RegPair) {
138 if ((ST->hasStdExtZcmp() || ST->hasVendorXqccmp()) &&
139 (Source == RISCV::X10 || Source == RISCV::X11) &&
140 RISCV::SR07RegClass.contains(Destination))
148 bool RegPairIsEven) {
151 DestSourcePair FirstPair =
TII->isCopyInstrImpl(*I).value();
152 DestSourcePair SecondPair =
TII->isCopyInstrImpl(*Paired).value();
160 MachineOperand PairedSource = *SecondPair.
Source;
162 unsigned Opcode = getGPRPairCopyOpcode(*ST);
163 for (
auto It = std::next(
I); It != Paired && PairedSource.
isKill(); ++It)
164 if (It->readsRegister(PairedSource.
getReg(),
TRI))
168 unsigned GPRPairIdx =
169 RegPairIsEven ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
170 SrcReg1 =
TRI->getMatchingSuperReg(FirstPair.
Source->
getReg(), GPRPairIdx,
171 &RISCV::GPRPairRegClass);
172 SrcReg2 = ST->hasStdExtZdinx() ? SrcReg1 :
Register(RISCV::X0_Pair);
174 GPRPairIdx, &RISCV::GPRPairRegClass);
183 Paired->eraseFromParent();
191 const MachineOperand *Sreg1, *Sreg2;
194 DestSourcePair FirstPair =
TII->isCopyInstrImpl(*I).value();
195 DestSourcePair PairedRegs =
TII->isCopyInstrImpl(*Paired).value();
204 MachineOperand PairedSource = *PairedRegs.
Source;
219 for (
auto It = std::next(
I); It != Paired && PairedSource.
isKill(); ++It)
220 if (It->readsRegister(PairedSource.
getReg(),
TRI))
224 Sreg2 = &PairedSource;
237 Paired->eraseFromParent();
244 const DestSourcePair &RegPair) {
246 ModifiedRegUnits.
clear();
247 UsedRegUnits.
clear();
252 MachineInstr &
MI = *
I;
254 if (
auto SecondPair =
TII->isCopyInstrImpl(
MI)) {
262 unsigned RegPairIdx =
263 EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
264 unsigned SecondPairIdx =
265 !EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
269 RegPair.
Source->
getReg(), RegPairIdx, &RISCV::GPRPairRegClass);
276 if (SourceReg !=
TRI->getSubReg(SrcGPRPair, SecondPairIdx) ||
277 DestReg !=
TRI->getSubReg(DestGPRPair, SecondPairIdx))
280 if (!ModifiedRegUnits.
available(DestReg) ||
296 const DestSourcePair &RegPair) {
301 ModifiedRegUnits.
clear();
302 UsedRegUnits.
clear();
307 MachineInstr &
MI = *
I;
309 if (
auto SecondPair =
TII->isCopyInstrImpl(
MI)) {
313 bool IsCandidate = MoveFromSToA ? isCandidateToMergeMVA01S(*SecondPair)
314 : isCandidateToMergeMVSA01(*SecondPair);
321 if (!MoveFromSToA && RegPair.
Source->
getReg() == SourceReg)
327 if (!ModifiedRegUnits.
available(DestReg) ||
343bool RISCVMoveMerge::mergeMoveSARegPair(MachineBasicBlock &
MBB) {
350 auto RegPair =
TII->isCopyInstrImpl(*
MBBI);
351 if (RegPair.has_value()) {
352 bool MoveFromSToA = isCandidateToMergeMVA01S(*RegPair);
353 bool IsEven = isEvenRegisterCopy(*RegPair);
354 bool IsOdd = isOddRegisterCopy(*RegPair);
355 if (!MoveFromSToA && !isCandidateToMergeMVSA01(*RegPair) && !IsEven &&
362 if (ST->hasStdExtZcmp() || ST->hasVendorXqccmp()) {
363 Paired = findMatchingInst(
MBBI, MoveFromSToA, RegPair.value());
365 MBBI = mergePairedInsns(
MBBI, Paired, MoveFromSToA);
370 if (IsEven != IsOdd) {
371 Paired = findMatchingInstPair(
MBBI, IsEven, RegPair.value());
373 MBBI = mergeGPRPairInsns(
MBBI, Paired, IsEven);
384bool RISCVMoveMerge::runOnMachineFunction(MachineFunction &Fn) {
389 bool HasGPRPairCopy =
390 !ST->
is64Bit() && (ST->hasStdExtZdinx() || ST->hasStdExtP());
391 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 void 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