16#define DEBUG_TYPE "cseinfo"
25 "Analysis containing CSE Info",
false,
true)
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:
74 case TargetOpcode::G_FMAXNUM:
75 case TargetOpcode::G_FMINNUM:
76 case TargetOpcode::G_FMAXNUM_IEEE:
77 case TargetOpcode::G_FMINNUM_IEEE:
84 return Opc == TargetOpcode::G_CONSTANT || Opc == TargetOpcode::G_FCONSTANT ||
85 Opc == TargetOpcode::G_IMPLICIT_DEF;
88std::unique_ptr<CSEConfigBase>
90 std::unique_ptr<CSEConfigBase>
Config;
92 Config = std::make_unique<CSEConfigConstantOnly>();
94 Config = std::make_unique<CSEConfigFull>();
108bool GISelCSEInfo::isUniqueMachineInstValid(
118 bool Removed = CSEMap.RemoveNode(UMI);
120 assert(Removed &&
"Invalidation called on invalid UMI");
127 auto *
Node = CSEMap.FindNodeOrInsertPos(
ID, InsertPos);
129 if (!isUniqueMachineInstValid(*
Node)) {
130 invalidateUniqueMachineInstr(
Node);
134 if (
Node->MI->getParent() !=
MBB)
145 CSEMap.InsertNode(UMI, InsertPos);
147 MaybeNewNode = CSEMap.GetOrInsertNode(UMI);
148 if (MaybeNewNode != UMI) {
152 assert(InstrMapping.count(UMI->MI) == 0 &&
153 "This instruction should not be in the map");
154 InstrMapping[UMI->MI] = MaybeNewNode;
163void GISelCSEInfo::insertInstr(
MachineInstr *
MI,
void *InsertPos) {
167 auto *
Node = getUniqueInstrForMI(
MI);
168 insertNode(
Node, InsertPos);
175 if (
auto *Inst = getNodeIfExists(
ID,
MBB, InsertPos)) {
184 if (OpcodeHitTable.
count(Opc))
185 OpcodeHitTable[Opc] += 1;
187 OpcodeHitTable[Opc] = 1;
201 auto *UMI = InstrMapping.lookup(
MI);
205 invalidateUniqueMachineInstr(UMI);
206 InstrMapping.erase(
MI);
213 insertNode(UMI,
nullptr);
222 if (
auto *UMI = InstrMapping.lookup(
MI)) {
223 invalidateUniqueMachineInstr(UMI);
224 InstrMapping.erase(
MI);
230 if (HandlingRecordedInstrs)
232 HandlingRecordedInstrs =
true;
233 while (!TemporaryInsts.
empty()) {
237 HandlingRecordedInstrs =
false;
241 assert(CSEOpt.get() &&
"CSEConfig not set");
242 return CSEOpt->shouldCSEOpc(Opc);
256 for (
auto &
MBB : MF) {
269 InstrMapping.clear();
270 UniqueInstrAllocator.
Reset();
271 TemporaryInsts.
clear();
276 OpcodeHitTable.
clear();
284 return OS.str().c_str();
294 for (
auto &It : InstrMapping) {
299 CSEMap.FindNodeOrInsertPos(TmpID, InsertPos);
300 if (FoundNode != It.second)
302 "CSEMap mismatch, InstrMapping has MIs without "
303 "corresponding Nodes in CSEMap:\n%s",
310 if (!InstrMapping.count(UMI.MI))
312 "Node in CSE without InstrMapping:\n%s",
315 if (InstrMapping[UMI.MI] != &UMI)
317 "Mismatch in CSE mapping:\n%s\n%s",
327 for (
auto &It : OpcodeHitTable)
328 dbgs() <<
"CSEInfo::CSE Hit for Opc " << It.first <<
" : " << It.second
338 for (
const auto &
Op :
MI->operands())
375 if (
const auto *RB = dyn_cast_if_present<const RegisterBank *>(RCOrRB))
430 }
else if (MO.
isImm())
447 if (!AlreadyComputed || Recompute) {
451 AlreadyComputed =
true;
block Block Frequency Analysis
static const char * stringify(const MachineInstr *MI, std::string &S)
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
separate const offset from Split GEPs to a variadic base and a constant offset for better CSE
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
void Reset()
Deallocate all but the current slab and reset the current pointer to the beginning of it,...
bool shouldCSEOpc(unsigned Opc) override
bool shouldCSEOpc(unsigned Opc) override
------— CSEConfigFull -------— ///
This class represents an Operation in the Expression.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
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...
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
GISelCSEAnalysisWrapperPass()
void setMF(MachineFunction &MFunc)
GISelCSEInfo & get(std::unique_ptr< CSEConfigBase > CSEOpt, bool ReCompute=false)
Takes a CSEConfigBase object that defines what opcodes get CSEd.
bool shouldCSE(unsigned Opc) const
void changingInstr(MachineInstr &MI) override
This instruction is about to be mutated in some way.
void analyze(MachineFunction &MF)
void changedInstr(MachineInstr &MI) override
This instruction was mutated in some way.
void recordNewInstruction(MachineInstr *MI)
Records a newly created inst in a list and lazily insert it to the CSEMap.
void setMF(MachineFunction &MF)
-----— GISelCSEInfo ----------—//
void erasingInstr(MachineInstr &MI) override
An instruction is about to be erased.
void countOpcodeHit(unsigned Opc)
void setCSEConfig(std::unique_ptr< CSEConfigBase > Opt)
void handleRecordedInsts()
Use this callback to insert all the recorded instructions.
void handleRecordedInst(MachineInstr *MI)
Use this callback to inform CSE about a newly fully created instruction.
void handleRemoveInst(MachineInstr *MI)
Remove this inst from the CSE map.
void createdInstr(MachineInstr &MI) override
An instruction has been created and inserted into the function.
const GISelInstProfileBuilder & addNodeIDOpcode(unsigned Opc) const
const GISelInstProfileBuilder & addNodeIDRegNum(Register Reg) const
const GISelInstProfileBuilder & addNodeIDFlag(unsigned Flag) const
const GISelInstProfileBuilder & addNodeIDImmediate(int64_t Imm) const
const GISelInstProfileBuilder & addNodeIDReg(Register Reg) const
const GISelInstProfileBuilder & addNodeID(const MachineInstr *MI) const
const GISelInstProfileBuilder & addNodeIDMBB(const MachineBasicBlock *MBB) const
const GISelInstProfileBuilder & addNodeIDRegType(const LLT Ty) const
const GISelInstProfileBuilder & addNodeIDMachineOperand(const MachineOperand &MO) const
void insert(MachineInstr *I)
Add the specified instruction to the worklist if it isn't already in it.
MachineInstr * pop_back_val()
void remove(const MachineInstr *I)
Remove I from the worklist if it exists.
constexpr uint64_t getUniqueRAWLLTData() const
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.
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.
VRegAttrs getVRegAttrs(Register Reg) const
Returns register class or bank and low level type of Reg.
static 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.
A raw_ostream that writes to an std::string.
#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.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
std::unique_ptr< CSEConfigBase > getStandardCSEConfigForOpt(CodeGenOptLevel Level)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
CodeGenOptLevel
Code generation optimization level.
void initializeGISelCSEAnalysisWrapperPassPass(PassRegistry &)
All attributes(register class or bank and low-level type) a virtual register can have.