Go to the documentation of this file.
15 #define DEBUG_TYPE "cseinfo"
24 "Analysis containing CSE Info",
false,
true)
40 case TargetOpcode::G_ADD:
41 case TargetOpcode::G_AND:
42 case TargetOpcode::G_ASHR:
43 case TargetOpcode::G_LSHR:
44 case TargetOpcode::G_MUL:
45 case TargetOpcode::G_OR:
46 case TargetOpcode::G_SHL:
47 case TargetOpcode::G_SUB:
48 case TargetOpcode::G_XOR:
49 case TargetOpcode::G_UDIV:
50 case TargetOpcode::G_SDIV:
51 case TargetOpcode::G_UREM:
52 case TargetOpcode::G_SREM:
53 case TargetOpcode::G_CONSTANT:
54 case TargetOpcode::G_FCONSTANT:
55 case TargetOpcode::G_IMPLICIT_DEF:
56 case TargetOpcode::G_ZEXT:
57 case TargetOpcode::G_SEXT:
58 case TargetOpcode::G_ANYEXT:
59 case TargetOpcode::G_UNMERGE_VALUES:
60 case TargetOpcode::G_TRUNC:
61 case TargetOpcode::G_PTR_ADD:
62 case TargetOpcode::G_EXTRACT:
69 return Opc == TargetOpcode::G_CONSTANT || Opc == TargetOpcode::G_IMPLICIT_DEF;
72 std::unique_ptr<CSEConfigBase>
74 std::unique_ptr<CSEConfigBase> Config;
76 Config = std::make_unique<CSEConfigConstantOnly>();
78 Config = std::make_unique<CSEConfigFull>();
92 bool GISelCSEInfo::isUniqueMachineInstValid(
102 bool Removed = CSEMap.RemoveNode(UMI);
104 assert(Removed &&
"Invalidation called on invalid UMI");
111 auto *Node = CSEMap.FindNodeOrInsertPos(
ID, InsertPos);
113 if (!isUniqueMachineInstValid(*Node)) {
114 invalidateUniqueMachineInstr(Node);
118 if (Node->MI->getParent() !=
MBB)
129 CSEMap.InsertNode(UMI, InsertPos);
131 MaybeNewNode = CSEMap.GetOrInsertNode(UMI);
132 if (MaybeNewNode != UMI) {
136 assert(InstrMapping.count(UMI->MI) == 0 &&
137 "This instruction should not be in the map");
138 InstrMapping[UMI->MI] = MaybeNewNode;
147 void GISelCSEInfo::insertInstr(
MachineInstr *
MI,
void *InsertPos) {
151 auto *Node = getUniqueInstrForMI(
MI);
152 insertNode(Node, InsertPos);
159 if (
auto *Inst = getNodeIfExists(
ID,
MBB, InsertPos)) {
168 if (OpcodeHitTable.
count(Opc))
169 OpcodeHitTable[Opc] += 1;
171 OpcodeHitTable[Opc] = 1;
185 auto *UMI = InstrMapping.lookup(
MI);
189 invalidateUniqueMachineInstr(UMI);
190 InstrMapping.erase(
MI);
197 insertNode(UMI,
nullptr);
206 if (
auto *UMI = InstrMapping.lookup(
MI)) {
207 invalidateUniqueMachineInstr(UMI);
208 InstrMapping.erase(
MI);
214 while (!TemporaryInsts.
empty()) {
221 assert(CSEOpt.get() &&
"CSEConfig not set");
222 return CSEOpt->shouldCSEOpc(Opc);
236 for (
auto &
MBB : MF) {
251 InstrMapping.clear();
252 UniqueInstrAllocator.
Reset();
253 TemporaryInsts.
clear();
258 OpcodeHitTable.
clear();
267 for (
auto &It : InstrMapping) {
272 CSEMap.FindNodeOrInsertPos(TmpID, InsertPos);
273 if (FoundNode != It.second)
275 "CSEMap mismatch, InstrMapping has MIs without "
276 "corresponding Nodes in CSEMap");
282 if (!InstrMapping.count(UMI.MI))
284 "Node in CSE without InstrMapping", UMI.MI);
286 if (InstrMapping[UMI.MI] != &UMI)
288 "Mismatch in CSE mapping");
297 dbgs() <<
"CSEInfo::CSE Hit for Opc " << It.first <<
" : " << It.second
307 for (
auto &
Op :
MI->operands())
321 uint64_t Val = Ty.getUniqueRAWLLTData();
376 if (
const auto *RB = RCOrRB.dyn_cast<
const RegisterBank *>())
394 }
else if (MO.
isImm())
395 ID.AddInteger(MO.
getImm());
411 if (!AlreadyComputed || Recompute) {
415 AlreadyComputed =
true;
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
void handleRecordedInst(MachineInstr *MI)
Use this callback to inform CSE about a newly fully created instruction.
This class represents lattice values for constants.
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)
The actual analysis pass wrapper.
void Reset()
Deallocate all but the current slab and reset the current pointer to the beginning of it,...
void handleRemoveInst(MachineInstr *MI)
Remove this inst from the CSE map.
const GISelInstProfileBuilder & addNodeIDMBB(const MachineBasicBlock *MBB) const
static ErrorSuccess success()
Create a success value.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const GISelInstProfileBuilder & addNodeIDMachineOperand(const MachineOperand &MO) const
void setMF(MachineFunction &MFunc)
const GISelInstProfileBuilder & addNodeID(const MachineInstr *MI) const
bool isCImm() const
isCImm - Test if this is a MO_CImmediate operand.
void changedInstr(MachineInstr &MI) override
This instruction was mutated in some way.
const GISelInstProfileBuilder & addNodeIDRegType(const LLT Ty) const
bool shouldCSE(unsigned Opc) const
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
GISelCSEInfo & get(std::unique_ptr< CSEConfigBase > CSEOpt, bool ReCompute=false)
Takes a CSEConfigBase object that defines what opcodes get CSEd.
A class that wraps MachineInstrs and derives from FoldingSetNode in order to be uniqued in a CSEMap.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const GISelInstProfileBuilder & addNodeIDOpcode(unsigned Opc) const
void initializeGISelCSEAnalysisWrapperPassPass(PassRegistry &)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
const GISelInstProfileBuilder & addNodeIDReg(Register Reg) const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
separate const offset from Split GEPs to a variadic base and a constant offset for better CSE
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class implements the register bank concept.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
void recordNewInstruction(MachineInstr *MI)
Records a newly created inst in a list and lazily insert it to the CSEMap.
Represent the analysis usage information of a pass.
void erasingInstr(MachineInstr &MI) override
An instruction is about to be erased.
MachineOperand class - Representation of each machine instruction operand.
void analyze(MachineFunction &MF)
Flag
These should be considered private to the implementation of the MCInstrDesc class.
const GISelInstProfileBuilder & addNodeIDRegNum(Register Reg) const
const GISelInstProfileBuilder & addNodeIDImmediate(int64_t Imm) const
Analysis containing CSE Info
void createdInstr(MachineInstr &MI) override
An instruction has been created and inserted into the function.
INITIALIZE_PASS_BEGIN(GISelCSEAnalysisWrapperPass, DEBUG_TYPE, "Analysis containing CSE Info", false, true) INITIALIZE_PASS_END(GISelCSEAnalysisWrapperPass
virtual bool shouldCSEOpc(unsigned Opc) override
------— CSEConfigFull -------— ///
bool isReg() const
isReg - Tests if this is a MO_Register operand.
const ConstantInt * getCImm() const
Representation of each machine instruction.
GISelCSEAnalysisWrapperPass()
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
const ConstantFP * getFPImm() const
unsigned getPredicate() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Register getReg() const
getReg - Returns the register number.
const RegClassOrRegBank & getRegClassOrRegBank(Register Reg) const
Return the register bank or register class of Reg.
MachineInstr * pop_back_val()
void setCSEConfig(std::unique_ptr< CSEConfigBase > Opt)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::unique_ptr< CSEConfigBase > getStandardCSEConfigForOpt(CodeGenOpt::Level Level)
void countOpcodeHit(unsigned Opc)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
void remove(const MachineInstr *I)
Remove I from the worklist if it exists.
void handleRecordedInsts()
Use this callback to insert all the recorded instructions.
A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...
Wrapper class representing virtual and physical registers.
std::error_code make_error_code(BitcodeError E)
void insert(MachineInstr *I)
Add the specified instruction to the worklist if it isn't already in it.
const GISelInstProfileBuilder & addNodeIDFlag(unsigned Flag) const
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
void setPreservesAll()
Set by analyses that do not transform their input at all.
Lightweight error class with error context and mandatory checking.
virtual bool shouldCSEOpc(unsigned Opc) override
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void setMF(MachineFunction &MF)
-----— GISelCSEInfo ----------—//
bool isFPImm() const
isFPImm - Tests if this is a MO_FPImmediate operand.
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
void changingInstr(MachineInstr &MI) override
This instruction is about to be mutated in some way.