LLVM 23.0.0git
CSEInfo.h
Go to the documentation of this file.
1//===- llvm/CodeGen/GlobalISel/CSEInfo.h ------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// Provides analysis for continuously CSEing during GISel passes.
10///
11//===----------------------------------------------------------------------===//
12#ifndef LLVM_CODEGEN_GLOBALISEL_CSEINFO_H
13#define LLVM_CODEGEN_GLOBALISEL_CSEINFO_H
14
15#include "llvm/ADT/FoldingSet.h"
25
26namespace llvm {
28
29/// A class that wraps MachineInstrs and derives from FoldingSetNode in order to
30/// be uniqued in a CSEMap. The tradeoff here is extra memory allocations for
31/// UniqueMachineInstr vs making MachineInstr bigger.
32class UniqueMachineInstr : public FoldingSetNode {
33 friend class GISelCSEInfo;
34 const MachineInstr *MI;
35 explicit UniqueMachineInstr(const MachineInstr *MI) : MI(MI) {}
36
37public:
39};
40
41// A CSE config for fully optimized builds.
43public:
44 ~CSEConfigFull() override = default;
45 bool shouldCSEOpc(unsigned Opc) override;
46};
47
48// Commonly used for O0 config.
50public:
51 ~CSEConfigConstantOnly() override = default;
52 bool shouldCSEOpc(unsigned Opc) override;
53};
54
55// Returns the standard expected CSEConfig for the given optimization level.
56// We have this logic here so targets can make use of it from their derived
57// TargetPassConfig, but can't put this logic into TargetPassConfig directly
58// because the CodeGen library can't depend on GlobalISel.
59LLVM_ABI std::unique_ptr<CSEConfigBase>
61
62/// The CSE Analysis object.
63/// This installs itself as a delegate to the MachineFunction to track
64/// new instructions as well as deletions. It however will not be able to
65/// track instruction mutations. In such cases, recordNewInstruction should be
66/// called (for eg inside MachineIRBuilder::recordInsertion).
67/// Also because of how just the instruction can be inserted without adding any
68/// operands to the instruction, instructions are uniqued and inserted lazily.
69/// CSEInfo should assert when trying to enter an incomplete instruction into
70/// the CSEMap. There is Opcode level granularity on which instructions can be
71/// CSE'd and for now, only Generic instructions are CSEable.
73 // Make it accessible only to CSEMIRBuilder.
74 friend class CSEMIRBuilder;
75
76 BumpPtrAllocator UniqueInstrAllocator;
78 MachineRegisterInfo *MRI = nullptr;
79 MachineFunction *MF = nullptr;
80 std::unique_ptr<CSEConfigBase> CSEOpt;
81 /// Keep a cache of UniqueInstrs for each MachineInstr. In GISel,
82 /// often instructions are mutated (while their ID has completely changed).
83 /// Whenever mutation happens, invalidate the UniqueMachineInstr for the
84 /// MachineInstr
86
87 /// Store instructions that are not fully formed in TemporaryInsts.
88 /// Also because CSE insertion happens lazily, we can remove insts from this
89 /// list and avoid inserting and then removing from the CSEMap.
90 GISelWorkList<8> TemporaryInsts;
91
92 // Only used in asserts.
93 DenseMap<unsigned, unsigned> OpcodeHitTable;
94
95 bool isUniqueMachineInstValid(const UniqueMachineInstr &UMI) const;
96
97 void invalidateUniqueMachineInstr(UniqueMachineInstr *UMI);
98
99 UniqueMachineInstr *getNodeIfExists(FoldingSetNodeID &ID,
100 MachineBasicBlock *MBB, void *&InsertPos);
101
102 /// Allocate and construct a new UniqueMachineInstr for MI and return.
103 UniqueMachineInstr *getUniqueInstrForMI(const MachineInstr *MI);
104
105 void insertNode(UniqueMachineInstr *UMI, void *InsertPos = nullptr);
106
107 /// Get the MachineInstr(Unique) if it exists already in the CSEMap and the
108 /// same MachineBasicBlock.
109 MachineInstr *getMachineInstrIfExists(FoldingSetNodeID &ID,
111 void *&InsertPos);
112
113 /// Use this method to allocate a new UniqueMachineInstr for MI and insert it
114 /// into the CSEMap. MI should return true for shouldCSE(MI->getOpcode())
115 void insertInstr(MachineInstr *MI, void *InsertPos = nullptr);
116
117 bool HandlingRecordedInstrs = false;
118
119public:
120 GISelCSEInfo() = default;
121
122 ~GISelCSEInfo() override;
123
124 void setMF(MachineFunction &MF);
125
126 Error verify();
127
128 /// Records a newly created inst in a list and lazily insert it to the CSEMap.
129 /// Sometimes, this method might be called with a partially constructed
130 /// MachineInstr,
131 // (right after BuildMI without adding any operands) - and in such cases,
132 // defer the hashing of the instruction to a later stage.
134
135 /// Use this callback to inform CSE about a newly fully created instruction.
137
138 /// Use this callback to insert all the recorded instructions. At this point,
139 /// all of these insts need to be fully constructed and should not be missing
140 /// any operands.
141 void handleRecordedInsts();
142
143 /// Remove this inst from the CSE map. If this inst has not been inserted yet,
144 /// it will be removed from the Tempinsts list if it exists.
146
147 void releaseMemory();
148
149 void setCSEConfig(std::unique_ptr<CSEConfigBase> Opt) {
150 CSEOpt = std::move(Opt);
151 }
152
153 bool shouldCSE(unsigned Opc) const;
154
155 void analyze(MachineFunction &MF);
156
157 void countOpcodeHit(unsigned Opc);
158
159 void print();
160
161 // Observer API
162 void erasingInstr(MachineInstr &MI) override;
163 void createdInstr(MachineInstr &MI) override;
164 void changingInstr(MachineInstr &MI) override;
165 void changedInstr(MachineInstr &MI) override;
166};
167
168class TargetRegisterClass;
169class RegisterBank;
170
171// Simple builder class to easily profile properties about MIs.
174 const MachineRegisterInfo &MRI;
175
176public:
178 : ID(ID), MRI(MRI) {}
179 // Profiling methods.
183 addNodeIDRegType(const Register) const;
186
188 addNodeIDRegType(const TargetRegisterClass *RC) const;
190 addNodeIDRegType(const RegisterBank *RB) const;
191
193
195
196 LLVM_ABI const GISelInstProfileBuilder &addNodeIDImmediate(int64_t Imm) const;
198 addNodeIDMBB(const MachineBasicBlock *MBB) const;
199
202
203 LLVM_ABI const GISelInstProfileBuilder &addNodeIDFlag(unsigned Flag) const;
205 addNodeID(const MachineInstr *MI) const;
206};
207
208/// Simple wrapper that does the following.
209/// 1) Lazily evaluate the MachineFunction to compute CSEable instructions.
210/// 2) Allows configuration of which instructions are CSEd through CSEConfig
211/// object. Provides a method called get which takes a CSEConfig object.
213 GISelCSEInfo Info;
214 MachineFunction *MF = nullptr;
215 bool AlreadyComputed = false;
216
217public:
218 /// Takes a CSEConfigBase object that defines what opcodes get CSEd.
219 /// If CSEConfig is already set, and the CSE Analysis has been preserved,
220 /// it will not use the new CSEOpt(use Recompute to force using the new
221 /// CSEOpt).
222 LLVM_ABI GISelCSEInfo &get(std::unique_ptr<CSEConfigBase> CSEOpt);
223 void setMF(MachineFunction &MFunc) { MF = &MFunc; }
224 void setComputed(bool Computed) { AlreadyComputed = Computed; }
225 void releaseMemory() { Info.releaseMemory(); }
226};
227
228class GISelCSEAnalysis : public AnalysisInfoMixin<GISelCSEAnalysis> {
230 LLVM_ABI static AnalysisKey Key;
231 TargetMachine *TM;
232
233public:
234 using Result = std::unique_ptr<GISelCSEInfo>;
236
239};
240
241/// The actual analysis pass wrapper.
244
245public:
246 static char ID;
248
249 void getAnalysisUsage(AnalysisUsage &AU) const override;
250
251 const GISelCSEAnalysisWrapper &getCSEWrapper() const { return Wrapper; }
253
254 bool runOnMachineFunction(MachineFunction &MF) override;
255
256 void releaseMemory() override {
257 Wrapper.releaseMemory();
258 Wrapper.setComputed(false);
259 }
260};
261
262} // namespace llvm
263
264#endif
MachineBasicBlock & MBB
This file defines the BumpPtrAllocator interface.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
#define LLVM_ABI
Definition Compiler.h:213
This file defines a hash set that can be used to remove duplication of nodes in a graph.
This contains common code to allow clients to notify changes to machine instr.
IRTranslator LLVM IR MI
Register Reg
ppc ctr loops verify
Represent the analysis usage information of a pass.
bool shouldCSEOpc(unsigned Opc) override
Definition CSEInfo.cpp:79
~CSEConfigConstantOnly() override=default
bool shouldCSEOpc(unsigned Opc) override
------— CSEConfigFull -------— ///
Definition CSEInfo.cpp:33
~CSEConfigFull() override=default
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
Definition FoldingSet.h:209
FoldingSet - This template class is used to instantiate a specialized implementation of the folding s...
Definition FoldingSet.h:535
const GISelCSEAnalysisWrapper & getCSEWrapper() const
Definition CSEInfo.h:251
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
Definition CSEInfo.h:256
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition CSEInfo.cpp:459
GISelCSEAnalysisWrapper & getCSEWrapper()
Definition CSEInfo.h:252
Simple wrapper that does the following.
Definition CSEInfo.h:212
void setComputed(bool Computed)
Definition CSEInfo.h:224
LLVM_ABI GISelCSEInfo & get(std::unique_ptr< CSEConfigBase > CSEOpt)
Takes a CSEConfigBase object that defines what opcodes get CSEd.
Definition CSEInfo.cpp:438
void setMF(MachineFunction &MFunc)
Definition CSEInfo.h:223
LLVM_ABI Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Definition CSEInfo.cpp:451
LLVM_ABI GISelCSEAnalysis(TargetMachine *TM)
Definition CSEInfo.h:235
std::unique_ptr< GISelCSEInfo > Result
Definition CSEInfo.h:234
The CSE Analysis object.
Definition CSEInfo.h:72
~GISelCSEInfo() override
void recordNewInstruction(MachineInstr *MI)
Records a newly created inst in a list and lazily insert it to the CSEMap.
Definition CSEInfo.cpp:185
friend class CSEMIRBuilder
Definition CSEInfo.h:74
void setMF(MachineFunction &MF)
-----— GISelCSEInfo ----------—//
Definition CSEInfo.cpp:97
void setCSEConfig(std::unique_ptr< CSEConfigBase > Opt)
Definition CSEInfo.h:149
void handleRecordedInsts()
Use this callback to insert all the recorded instructions.
Definition CSEInfo.cpp:222
void handleRecordedInst(MachineInstr *MI)
Use this callback to inform CSE about a newly fully created instruction.
Definition CSEInfo.cpp:192
void handleRemoveInst(MachineInstr *MI)
Remove this inst from the CSE map.
Definition CSEInfo.cpp:214
GISelCSEInfo()=default
Abstract class that contains various methods for clients to notify about changes.
LLVM_ABI const GISelInstProfileBuilder & addNodeIDOpcode(unsigned Opc) const
Definition CSEInfo.cpp:338
LLVM_ABI const GISelInstProfileBuilder & addNodeIDRegNum(Register Reg) const
Definition CSEInfo.cpp:383
LLVM_ABI const GISelInstProfileBuilder & addNodeIDFlag(unsigned Flag) const
Definition CSEInfo.cpp:401
LLVM_ABI const GISelInstProfileBuilder & addNodeIDImmediate(int64_t Imm) const
Definition CSEInfo.cpp:377
LLVM_ABI const GISelInstProfileBuilder & addNodeIDReg(Register Reg) const
Definition CSEInfo.cpp:408
LLVM_ABI const GISelInstProfileBuilder & addNodeID(const MachineInstr *MI) const
Definition CSEInfo.cpp:328
LLVM_ABI const GISelInstProfileBuilder & addNodeIDMBB(const MachineBasicBlock *MBB) const
Definition CSEInfo.cpp:395
GISelInstProfileBuilder(FoldingSetNodeID &ID, const MachineRegisterInfo &MRI)
Definition CSEInfo.h:177
LLVM_ABI const GISelInstProfileBuilder & addNodeIDRegType(const LLT Ty) const
Definition CSEInfo.cpp:344
LLVM_ABI const GISelInstProfileBuilder & addNodeIDMachineOperand(const MachineOperand &MO) const
Definition CSEInfo.cpp:413
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This class implements the register bank concept.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Primary interface to the complete machine description for the target machine.
A class that wraps MachineInstrs and derives from FoldingSetNode in order to be uniqued in a CSEMap.
Definition CSEInfo.h:32
LLVM_ABI void Profile(FoldingSetNodeID &ID)
friend class GISelCSEInfo
Definition CSEInfo.h:33
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
FoldingSetBase::Node FoldingSetNode
Definition FoldingSet.h:408
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI std::unique_ptr< CSEConfigBase > getStandardCSEConfigForOpt(CodeGenOptLevel Level)
Definition CSEInfo.cpp:85
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:82
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383
A CRTP mix-in that provides informational APIs needed for analysis passes.
Definition PassManager.h:93
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29
All attributes(register class or bank and low-level type) a virtual register can have.