LLVM: lib/Target/RISCV/RISCVMoveMerger.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
18
19using namespace llvm;
20
21#define RISCV_MOVE_MERGE_NAME "RISC-V Zcmp move merging pass"
22
23namespace {
25 static char ID;
26
28
32
33
35
36 bool isCandidateToMergeMVA01S(const DestSourcePair &RegPair);
37 bool isCandidateToMergeMVSA01(const DestSourcePair &RegPair);
38
42
43
44
45
51
53};
54
55char RISCVMoveMerge::ID = 0;
56
57}
58
60 false, false)
61
63 if (ST.hasStdExtZcmp())
64 return RISCV::CM_MVA01S;
65
66 if (ST.hasVendorXqccmp())
67 return RISCV::QC_CM_MVA01S;
68
69 llvm_unreachable("Unhandled subtarget with paired A to S move.");
70}
71
73 if (ST.hasStdExtZcmp())
74 return RISCV::CM_MVSA01;
75
76 if (ST.hasVendorXqccmp())
77 return RISCV::QC_CM_MVSA01;
78
79 llvm_unreachable("Unhandled subtarget with paired S to A move");
80}
81
82
83bool RISCVMoveMerge::isCandidateToMergeMVA01S(const DestSourcePair &RegPair) {
86
87 if ((Destination == RISCV::X10 || Destination == RISCV::X11) &&
88 RISCV::SR07RegClass.contains(Source))
89 return true;
90 return false;
91}
92
93
94bool RISCVMoveMerge::isCandidateToMergeMVSA01(const DestSourcePair &RegPair) {
97
98 if ((Source == RISCV::X10 || Source == RISCV::X11) &&
99 RISCV::SR07RegClass.contains(Destination))
100 return true;
101 return false;
102}
103
107 bool MoveFromSToA) {
108 const MachineOperand *Sreg1, *Sreg2;
113
114 if (NextI == Paired)
117
118
119
120
121 MachineOperand PairedSource = *PairedRegs.Source;
122
123
124
125
126
127
128
129
130
131 unsigned Opcode;
132 if (MoveFromSToA) {
133
134
135
136 for (auto It = std::next(I); It != Paired && PairedSource.isKill(); ++It)
137 if (It->readsRegister(PairedSource.getReg(), TRI))
139
140 Opcode = getMoveFromSToAOpcode(*ST);
141 Sreg1 = FirstPair.Source;
142 Sreg2 = &PairedSource;
145 } else {
149 if (FirstPair.Source->getReg() != RISCV::X10)
151 }
152
154
156 Paired->eraseFromParent();
157 return NextI;
158}
159
162 bool MoveFromSToA,
163 const DestSourcePair &RegPair) {
165
166
167
168 ModifiedRegUnits.clear();
169 UsedRegUnits.clear();
170
173
175
177 Register SourceReg = SecondPair->Source->getReg();
178 Register DestReg = SecondPair->Destination->getReg();
179
180 bool IsCandidate = MoveFromSToA ? isCandidateToMergeMVA01S(*SecondPair)
181 : isCandidateToMergeMVSA01(*SecondPair);
182 if (IsCandidate) {
183
185 return E;
186
187
188 if (!MoveFromSToA && RegPair.Source->getReg() == SourceReg)
189 return E;
190
191
192
193
194 if (!ModifiedRegUnits.available(DestReg) ||
195 !UsedRegUnits.available(DestReg) ||
196 !ModifiedRegUnits.available(SourceReg))
197 return E;
198
199 return I;
200 }
201 }
202
204 }
205 return E;
206}
207
208
209
210bool RISCVMoveMerge::mergeMoveSARegPair(MachineBasicBlock &MBB) {
212
215
216
218 if (RegPair.has_value()) {
219 bool MoveFromSToA = isCandidateToMergeMVA01S(*RegPair);
220 if (!MoveFromSToA && !isCandidateToMergeMVSA01(*RegPair)) {
222 continue;
223 }
224
226 findMatchingInst(MBBI, MoveFromSToA, RegPair.value());
227
228 if (Paired != E) {
229 MBBI = mergePairedInsns(MBBI, Paired, MoveFromSToA);
231 continue;
232 }
233 }
235 }
237}
238
239bool RISCVMoveMerge::runOnMachineFunction(MachineFunction &Fn) {
241 return false;
242
244 if (!ST->hasStdExtZcmp() && !ST->hasVendorXqccmp())
245 return false;
246
249
250
251
252 ModifiedRegUnits.init(*TRI);
255 for (auto &MBB : Fn)
258}
259
260
261
const TargetInstrInfo & TII
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
#define RISCV_MOVE_MERGE_NAME
Definition RISCVMoveMerger.cpp:21
static unsigned getMoveFromAToSOpcode(const RISCVSubtarget &ST)
Definition RISCVMoveMerger.cpp:72
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
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 MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
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 & 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
StringRef - Represent a constant reference to a string, i.e.
virtual std::optional< DestSourcePair > isCopyInstrImpl(const MachineInstr &MI) const
Target-dependent implementation for IsCopyInstr.
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.
Definition RISCVMoveMerger.cpp:262
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