LLVM: lib/CodeGen/GlobalISel/CSEInfo.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
15
16#define DEBUG_TYPE "cseinfo"
17
18using namespace llvm;
25 "Analysis containing CSE Info", false, true)
27 "Analysis containing CSE Info", false, true)
28
29
30
34
35
36
38 switch (Opc) {
39 default:
40 break;
41 case TargetOpcode::G_ADD:
42 case TargetOpcode::G_AND:
43 case TargetOpcode::G_ASHR:
44 case TargetOpcode::G_LSHR:
45 case TargetOpcode::G_MUL:
46 case TargetOpcode::G_OR:
47 case TargetOpcode::G_SHL:
48 case TargetOpcode::G_SUB:
49 case TargetOpcode::G_XOR:
50 case TargetOpcode::G_UDIV:
51 case TargetOpcode::G_SDIV:
52 case TargetOpcode::G_UREM:
53 case TargetOpcode::G_SREM:
54 case TargetOpcode::G_CONSTANT:
55 case TargetOpcode::G_FCONSTANT:
56 case TargetOpcode::G_IMPLICIT_DEF:
57 case TargetOpcode::G_ZEXT:
58 case TargetOpcode::G_SEXT:
59 case TargetOpcode::G_ANYEXT:
60 case TargetOpcode::G_UNMERGE_VALUES:
61 case TargetOpcode::G_TRUNC:
62 case TargetOpcode::G_PTR_ADD:
63 case TargetOpcode::G_EXTRACT:
64 case TargetOpcode::G_SELECT:
65 case TargetOpcode::G_BUILD_VECTOR:
66 case TargetOpcode::G_BUILD_VECTOR_TRUNC:
67 case TargetOpcode::G_SEXT_INREG:
68 case TargetOpcode::G_FADD:
69 case TargetOpcode::G_FSUB:
70 case TargetOpcode::G_FMUL:
71 case TargetOpcode::G_FDIV:
72 case TargetOpcode::G_FABS:
73
74 case TargetOpcode::G_FMAXNUM:
75 case TargetOpcode::G_FMINNUM:
76 case TargetOpcode::G_FMAXNUM_IEEE:
77 case TargetOpcode::G_FMINNUM_IEEE:
78 return true;
79 }
80 return false;
81}
82
84 return Opc == TargetOpcode::G_CONSTANT || Opc == TargetOpcode::G_FCONSTANT ||
85 Opc == TargetOpcode::G_IMPLICIT_DEF;
86}
87
88std::unique_ptr
90 std::unique_ptr Config;
92 Config = std::make_unique();
93 else
94 Config = std::make_unique();
95 return Config;
96}
97
98
99
100
105
107
108bool GISelCSEInfo::isUniqueMachineInstValid(
110
111
112
113
114 return true;
115}
116
117void GISelCSEInfo::invalidateUniqueMachineInstr(UniqueMachineInstr *UMI) {
118 bool Removed = CSEMap.RemoveNode(UMI);
119 (void)Removed;
120 assert(Removed && "Invalidation called on invalid UMI");
121
122}
123
126 void *&InsertPos) {
127 auto *Node = CSEMap.FindNodeOrInsertPos(ID, InsertPos);
128 if (Node) {
129 if (!isUniqueMachineInstValid(*Node)) {
130 invalidateUniqueMachineInstr(Node);
131 return nullptr;
132 }
133
134 if (Node->MI->getParent() != MBB)
135 return nullptr;
136 }
138}
139
140void GISelCSEInfo::insertNode(UniqueMachineInstr *UMI, void *InsertPos) {
143 UniqueMachineInstr *MaybeNewNode = UMI;
144 if (InsertPos)
145 CSEMap.InsertNode(UMI, InsertPos);
146 else
147 MaybeNewNode = CSEMap.GetOrInsertNode(UMI);
148 if (MaybeNewNode != UMI) {
149
150 return;
151 }
152 assert(InstrMapping.count(UMI->MI) == 0 &&
153 "This instruction should not be in the map");
154 InstrMapping[UMI->MI] = MaybeNewNode;
155}
156
158 assert(shouldCSE(MI->getOpcode()) && "Trying to CSE an unsupported Node");
159 auto *Node = new (UniqueInstrAllocator) UniqueMachineInstr(MI);
161}
162
163void GISelCSEInfo::insertInstr(MachineInstr *MI, void *InsertPos) {
165
166 TemporaryInsts.remove(MI);
167 auto *Node = getUniqueInstrForMI(MI);
168 insertNode(Node, InsertPos);
169}
170
173 void *&InsertPos) {
175 if (auto *Inst = getNodeIfExists(ID, MBB, InsertPos)) {
176 LLVM_DEBUG(dbgs() << "CSEInfo::Found Instr " << *Inst->MI);
177 return const_cast<MachineInstr *>(Inst->MI);
178 }
179 return nullptr;
180}
181
183#ifndef NDEBUG
184 ++OpcodeHitTable[Opc];
185#endif
186
187}
188
191 TemporaryInsts.insert(MI);
193 }
194}
195
197 assert(shouldCSE(MI->getOpcode()) && "Invalid instruction for CSE");
198 auto *UMI = InstrMapping.lookup(MI);
199 LLVM_DEBUG(dbgs() << "CSEInfo::Handling recorded MI " << *MI);
200 if (UMI) {
201
202 invalidateUniqueMachineInstr(UMI);
203 InstrMapping.erase(MI);
204 }
205
206 if (UMI) {
207
208
210 insertNode(UMI, nullptr);
211 } else {
212
213
214 insertInstr(MI);
215 }
216}
217
219 if (auto *UMI = InstrMapping.lookup(MI)) {
220 invalidateUniqueMachineInstr(UMI);
221 InstrMapping.erase(MI);
222 }
223 TemporaryInsts.remove(MI);
224}
225
227 if (HandlingRecordedInstrs)
228 return;
229 HandlingRecordedInstrs = true;
230 while (!TemporaryInsts.empty()) {
231 auto *MI = TemporaryInsts.pop_back_val();
233 }
234 HandlingRecordedInstrs = false;
235}
236
238 assert(CSEOpt.get() && "CSEConfig not set");
239 return CSEOpt->shouldCSEOpc(Opc);
240}
241
250
253 for (auto &MBB : MF) {
256 continue;
258 insertInstr(&MI);
259 }
260 }
261}
262
265 CSEMap.clear();
266 InstrMapping.clear();
267 UniqueInstrAllocator.Reset();
268 TemporaryInsts.clear();
269 CSEOpt.reset();
270 MRI = nullptr;
271 MF = nullptr;
272#ifndef NDEBUG
273 OpcodeHitTable.clear();
274#endif
275}
276
277#ifndef NDEBUG
280 OS << *MI;
281 return OS.str().c_str();
282}
283#endif
284
286#ifndef NDEBUG
287 std::string S1, S2;
289
290
291 for (auto &It : InstrMapping) {
294 void *InsertPos;
296 CSEMap.FindNodeOrInsertPos(TmpID, InsertPos);
297 if (FoundNode != It.second)
299 "CSEMap mismatch, InstrMapping has MIs without "
300 "corresponding Nodes in CSEMap:\n%s",
302 }
303
304
305
307 if (!InstrMapping.count(UMI.MI))
309 "Node in CSE without InstrMapping:\n%s",
311
312 if (InstrMapping[UMI.MI] != &UMI)
313 return createStringError(std::make_error_code(std::errc::not_supported),
314 "Mismatch in CSE mapping:\n%s\n%s",
317 }
318#endif
320}
321
324 for (auto &It : OpcodeHitTable)
325 dbgs() << "CSEInfo::CSE Hit for Opc " << It.first << " : " << It.second
326 << "\n";
327 });
328}
329
330
335 for (const auto &Op : MI->operands())
338 return *this;
339}
340
343 ID.AddInteger(Opc);
344 return *this;
345}
346
349 uint64_t Val = Ty.getUniqueRAWLLTData();
350 ID.AddInteger(Val);
351 return *this;
352}
353
356 ID.AddPointer(RC);
357 return *this;
358}
359
362 ID.AddPointer(RB);
363 return *this;
364}
365
369
371 if (RCOrRB) {
374 else
376 }
377 return *this;
378}
379
382 ID.AddInteger(Imm);
383 return *this;
384}
385
388 ID.AddInteger(Reg.id());
389 return *this;
390}
391
397
400 ID.AddPointer(MBB);
401 return *this;
402}
403
406 if (Flag)
407 ID.AddInteger(Flag);
408 return *this;
409}
410
416
419 if (MO.isReg()) {
423
424
427 } else if (MO.isImm())
428 ID.AddInteger(MO.getImm());
429 else if (MO.isCImm())
430 ID.AddPointer(MO.getCImm());
432 ID.AddPointer(MO.getFPImm());
435 else
437
438 return *this;
439}
440
443 bool Recompute) {
444 if (!AlreadyComputed || Recompute) {
445 Info.releaseMemory();
446 Info.setCSEConfig(std::move(CSEOpt));
447 Info.analyze(*MF);
448 AlreadyComputed = true;
449 }
450 return Info;
451}
456
459 Wrapper.setMF(MF);
460 return false;
461}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static const char * stringify(const MachineInstr *MI, std::string &S)
Definition CSEInfo.cpp:278
Provides analysis for continuously CSEing during GISel passes.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
bool shouldCSEOpc(unsigned Opc) override
Definition CSEInfo.cpp:83
bool shouldCSEOpc(unsigned Opc) override
------— CSEConfigFull -------— ///
Definition CSEInfo.cpp:37
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
The actual analysis pass wrapper.
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition CSEInfo.cpp:452
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition CSEInfo.cpp:457
GISelCSEAnalysisWrapperPass()
Definition CSEInfo.cpp:20
LLVM_ABI GISelCSEInfo & get(std::unique_ptr< CSEConfigBase > CSEOpt, bool ReCompute=false)
Takes a CSEConfigBase object that defines what opcodes get CSEd.
Definition CSEInfo.cpp:442
bool shouldCSE(unsigned Opc) const
Definition CSEInfo.cpp:237
void changingInstr(MachineInstr &MI) override
This instruction is about to be mutated in some way.
Definition CSEInfo.cpp:244
void analyze(MachineFunction &MF)
Definition CSEInfo.cpp:251
void changedInstr(MachineInstr &MI) override
This instruction was mutated in some way.
Definition CSEInfo.cpp:249
void recordNewInstruction(MachineInstr *MI)
Records a newly created inst in a list and lazily insert it to the CSEMap.
Definition CSEInfo.cpp:189
void setMF(MachineFunction &MF)
-----— GISelCSEInfo ----------—//
Definition CSEInfo.cpp:101
void erasingInstr(MachineInstr &MI) override
An instruction is about to be erased.
Definition CSEInfo.cpp:242
void countOpcodeHit(unsigned Opc)
Definition CSEInfo.cpp:182
void handleRecordedInsts()
Use this callback to insert all the recorded instructions.
Definition CSEInfo.cpp:226
void handleRecordedInst(MachineInstr *MI)
Use this callback to inform CSE about a newly fully created instruction.
Definition CSEInfo.cpp:196
void handleRemoveInst(MachineInstr *MI)
Remove this inst from the CSE map.
Definition CSEInfo.cpp:218
void releaseMemory()
Definition CSEInfo.cpp:263
Error verify()
Definition CSEInfo.cpp:285
void print()
Definition CSEInfo.cpp:322
void createdInstr(MachineInstr &MI) override
An instruction has been created and inserted into the function.
Definition CSEInfo.cpp:243
LLVM_ABI const GISelInstProfileBuilder & addNodeIDOpcode(unsigned Opc) const
Definition CSEInfo.cpp:342
LLVM_ABI const GISelInstProfileBuilder & addNodeIDRegNum(Register Reg) const
Definition CSEInfo.cpp:387
LLVM_ABI const GISelInstProfileBuilder & addNodeIDFlag(unsigned Flag) const
Definition CSEInfo.cpp:405
LLVM_ABI const GISelInstProfileBuilder & addNodeIDImmediate(int64_t Imm) const
Definition CSEInfo.cpp:381
LLVM_ABI const GISelInstProfileBuilder & addNodeIDReg(Register Reg) const
Definition CSEInfo.cpp:412
LLVM_ABI const GISelInstProfileBuilder & addNodeID(const MachineInstr *MI) const
Definition CSEInfo.cpp:332
LLVM_ABI const GISelInstProfileBuilder & addNodeIDMBB(const MachineBasicBlock *MBB) const
Definition CSEInfo.cpp:399
GISelInstProfileBuilder(FoldingSetNodeID &ID, const MachineRegisterInfo &MRI)
LLVM_ABI const GISelInstProfileBuilder & addNodeIDRegType(const LLT Ty) const
Definition CSEInfo.cpp:348
LLVM_ABI const GISelInstProfileBuilder & addNodeIDMachineOperand(const MachineOperand &MO) const
Definition CSEInfo.cpp:417
MachineFunctionPass(char &ID)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
const ConstantInt * getCImm() const
bool isCImm() const
isCImm - Test if this is a MO_CImmediate operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Register getReg() const
getReg - Returns the register number.
const ConstantFP * getFPImm() const
unsigned getPredicate() const
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
bool isFPImm() const
isFPImm - Tests if this is a MO_FPImmediate operand.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class implements the register bank concept.
Wrapper class representing virtual and physical registers.
A class that wraps MachineInstrs and derives from FoldingSetNode in order to be uniqued in a CSEMap.
LLVM_ABI void Profile(FoldingSetNodeID &ID)
-----— UniqueMachineInstr ----------—//
Definition CSEInfo.cpp:31
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
#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.
NodeAddr< NodeBase * > Node
This is an optimization pass for GlobalISel generic memory operations.
PointerUnion< const TargetRegisterClass *, const RegisterBank * > RegClassOrRegBank
Convenient type to represent either a register class or a register bank.
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present - Functionally identical to dyn_cast, except that a null (or none in the case ...
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
LLVM_ABI std::unique_ptr< CSEConfigBase > getStandardCSEConfigForOpt(CodeGenOptLevel Level)
Definition CSEInfo.cpp:89
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
CodeGenOptLevel
Code generation optimization level.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
LLVM_ABI void initializeGISelCSEAnalysisWrapperPassPass(PassRegistry &)
All attributes(register class or bank and low-level type) a virtual register can have.