27#define RISCV_MOVE_MERGE_NAME "RISC-V Zcmp move merging pass"
45class RISCVMoveMergeImpl {
53 bool isGPRPairCopyCandidate(
const DestSourcePair &RegPair,
bool EvenRegPair);
88char RISCVMoveMergeLegacy::ID = 0;
96 if (ST.hasStdExtZcmp())
97 return MoveFromSToA ? RISCV::CM_MVA01S : RISCV::CM_MVSA01;
99 if (ST.hasVendorXqccmp())
100 return MoveFromSToA ? RISCV::QC_CM_MVA01S : RISCV::QC_CM_MVSA01;
109 return RISCV::PLI_DB;
111 return RISCV::PLI_DH;
113 return RISCV::PLUI_DH;
119bool RISCVMoveMergeImpl::isGPRPairCopyCandidate(
const DestSourcePair &RegPair,
124 if (Source == Destination)
127 if ((!
ST->hasStdExtZdinx() && !
ST->hasStdExtP()) ||
ST->is64Bit())
130 unsigned SubIdx = EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
133 TRI->getMatchingSuperReg(Source, SubIdx, &RISCV::GPRPairRegClass);
135 TRI->getMatchingSuperReg(Destination, SubIdx, &RISCV::GPRPairRegClass);
141bool RISCVMoveMergeImpl::isCandidateToMergeMVA01S(
142 const DestSourcePair &RegPair) {
146 if ((
ST->hasStdExtZcmp() ||
ST->hasVendorXqccmp()) &&
147 (Destination == RISCV::X10 || Destination == RISCV::X11) &&
148 RISCV::GPRS07RegClass.contains(Source))
154bool RISCVMoveMergeImpl::isCandidateToMergeMVSA01(
155 const DestSourcePair &RegPair) {
159 if ((
ST->hasStdExtZcmp() ||
ST->hasVendorXqccmp()) &&
160 (Source == RISCV::X10 || Source == RISCV::X11) &&
161 RISCV::GPRS07RegClass.contains(Destination))
168bool RISCVMoveMergeImpl::isPLIPairCandidate(
const MachineInstr &
MI,
170 if (!
ST->hasStdExtP() ||
ST->is64Bit())
174 unsigned SubIdx = EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
176 ->getMatchingSuperReg(
MI.getOperand(0).getReg(), SubIdx,
177 &RISCV::GPRPairRegClass)
184 bool RegPairIsEven) {
187 DestSourcePair FirstPair = *
TII->isCopyInstrImpl(*
I);
188 DestSourcePair SecondPair = *
TII->isCopyInstrImpl(*Paired);
196 MachineOperand PairedSource = *SecondPair.
Source;
198 for (
auto It = std::next(
I); It != Paired && PairedSource.
isKill(); ++It)
199 if (It->readsRegister(PairedSource.
getReg(),
TRI))
202 unsigned GPRPairIdx =
203 RegPairIsEven ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
204 MCRegister SrcReg =
TRI->getMatchingSuperReg(
205 FirstPair.
Source->
getReg(), GPRPairIdx, &RISCV::GPRPairRegClass);
206 MCRegister DestReg =
TRI->getMatchingSuperReg(
212 I->eraseFromParent();
213 Paired->eraseFromParent();
221 const MachineOperand *Sreg1, *Sreg2;
224 DestSourcePair FirstPair = *
TII->isCopyInstrImpl(*
I);
225 DestSourcePair PairedRegs = *
TII->isCopyInstrImpl(*Paired);
234 MachineOperand PairedSource = *PairedRegs.
Source;
249 for (
auto It = std::next(
I); It != Paired && PairedSource.
isKill(); ++It)
250 if (It->readsRegister(PairedSource.
getReg(),
TRI))
254 Sreg2 = &PairedSource;
267 Paired->eraseFromParent();
274 bool RegPairIsEven) {
283 unsigned GPRPairIdx =
284 RegPairIsEven ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
286 I->getOperand(0).getReg(), GPRPairIdx, &RISCV::GPRPairRegClass);
289 .
addImm(
I->getOperand(1).getImm());
292 Paired->eraseFromParent();
299 const DestSourcePair &RegPair) {
301 ModifiedRegUnits.
clear();
302 UsedRegUnits.
clear();
303 unsigned RegPairIdx = EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
304 unsigned SecondPairIdx =
305 !EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
309 RegPair.
Source->
getReg(), RegPairIdx, &RISCV::GPRPairRegClass);
316 Register ExpectedSourceReg =
TRI->getSubReg(SrcGPRPair, SecondPairIdx);
317 Register ExpectedDestReg =
TRI->getSubReg(DestGPRPair, SecondPairIdx);
325 MachineInstr &
MI = *
I;
327 if (
auto SecondPair =
TII->isCopyInstrImpl(
MI)) {
337 if (SourceReg == ExpectedSourceReg && DestReg == ExpectedDestReg)
344 if (!ModifiedRegUnits.
available(ExpectedDestReg) ||
345 !UsedRegUnits.
available(ExpectedDestReg) ||
346 !ModifiedRegUnits.
available(ExpectedSourceReg))
355 const DestSourcePair &RegPair) {
360 ModifiedRegUnits.
clear();
361 UsedRegUnits.
clear();
366 MachineInstr &
MI = *
I;
368 if (
auto SecondPair =
TII->isCopyInstrImpl(
MI)) {
372 bool IsCandidate =
MoveFromSToA ? isCandidateToMergeMVA01S(*SecondPair)
373 : isCandidateToMergeMVSA01(*SecondPair);
386 if (!ModifiedRegUnits.
available(DestReg) ||
406 ModifiedRegUnits.
clear();
407 UsedRegUnits.
clear();
408 unsigned Opc =
MBBI->getOpcode();
410 int64_t FirstImm =
MBBI->getOperand(1).getImm();
411 unsigned RegPairIdx = EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
412 unsigned SecondPairIdx =
413 !EvenRegPair ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
416 Register DestGPRPair =
TRI->getMatchingSuperReg(FirstDestReg, RegPairIdx,
417 &RISCV::GPRPairRegClass);
419 Register ExpectedDestReg =
TRI->getSubReg(DestGPRPair, SecondPairIdx);
425 MachineInstr &
MI = *
I;
427 if (
MI.getOpcode() ==
Opc) {
429 int64_t
Imm =
MI.getOperand(1).getImm();
431 if (FirstDestReg == DestReg)
435 if (DestReg == ExpectedDestReg &&
Imm == FirstImm)
442 if (!ModifiedRegUnits.
available(ExpectedDestReg) ||
443 !UsedRegUnits.
available(ExpectedDestReg))
451bool RISCVMoveMergeImpl::mergeMovePairs(MachineBasicBlock &
MBB) {
457 bool IsPLIEven = isPLIPairCandidate(*
MBBI,
true);
458 bool IsPLIOdd = isPLIPairCandidate(*
MBBI,
false);
459 if (IsPLIEven != IsPLIOdd) {
462 MBBI = mergePLIPair(
MBBI, Paired, IsPLIEven);
470 auto RegPair =
TII->isCopyInstrImpl(*
MBBI);
471 if (RegPair.has_value()) {
473 bool MoveFromAToS = isCandidateToMergeMVSA01(*RegPair);
474 bool IsEven = isGPRPairCopyCandidate(*RegPair,
true);
475 bool IsOdd = isGPRPairCopyCandidate(*RegPair,
false);
476 if (!
MoveFromSToA && !MoveFromAToS && !IsEven && !IsOdd) {
490 if (IsEven != IsOdd) {
491 Paired = findMatchingGPRPairCopy(
MBBI, IsEven, *RegPair);
493 MBBI = mergeGPRPairInsns(
MBBI, Paired, IsEven);
506 bool HasGPRPairCopy =
507 !
ST->is64Bit() && (
ST->hasStdExtZdinx() ||
ST->hasStdExtP());
508 if (!
ST->hasStdExtZcmp() && !
ST->hasVendorXqccmp() && !HasGPRPairCopy)
511 TII =
ST->getInstrInfo();
512 TRI =
ST->getRegisterInfo();
526 return new RISCVMoveMergeLegacy();
532 RISCVMoveMergeImpl Impl;
533 return Impl.runOnMachineFunction(MF);
539 RISCVMoveMergeImpl Impl;
540 return Impl.runOnMachineFunction(MF)
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)
Represent the analysis usage information of a pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
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...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
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.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
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...
Pass manager infrastructure for declaring and invalidating analyses.
#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.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
FunctionPass * createRISCVMoveMergeLegacyPass()
Returns an instance of the move merge pass.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
const MachineOperand * Source
const MachineOperand * Destination