Go to the documentation of this file.
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:
70 return Opc == TargetOpcode::G_CONSTANT || Opc == TargetOpcode::G_FCONSTANT ||
71 Opc == TargetOpcode::G_IMPLICIT_DEF;
74 std::unique_ptr<CSEConfigBase>
76 std::unique_ptr<CSEConfigBase> Config;
78 Config = std::make_unique<CSEConfigConstantOnly>();
80 Config = std::make_unique<CSEConfigFull>();
94 bool GISelCSEInfo::isUniqueMachineInstValid(
104 bool Removed = CSEMap.RemoveNode(UMI);
106 assert(Removed &&
"Invalidation called on invalid UMI");
113 auto *Node = CSEMap.FindNodeOrInsertPos(
ID, InsertPos);
115 if (!isUniqueMachineInstValid(*Node)) {
116 invalidateUniqueMachineInstr(Node);
120 if (Node->MI->getParent() !=
MBB)
131 CSEMap.InsertNode(UMI, InsertPos);
133 MaybeNewNode = CSEMap.GetOrInsertNode(UMI);
134 if (MaybeNewNode != UMI) {
138 assert(InstrMapping.count(UMI->MI) == 0 &&
139 "This instruction should not be in the map");
140 InstrMapping[UMI->MI] = MaybeNewNode;
149 void GISelCSEInfo::insertInstr(
MachineInstr *
MI,
void *InsertPos) {
153 auto *Node = getUniqueInstrForMI(
MI);
154 insertNode(Node, InsertPos);
161 if (
auto *Inst = getNodeIfExists(
ID,
MBB, InsertPos)) {
170 if (OpcodeHitTable.
count(Opc))
171 OpcodeHitTable[Opc] += 1;
173 OpcodeHitTable[Opc] = 1;
187 auto *UMI = InstrMapping.lookup(
MI);
191 invalidateUniqueMachineInstr(UMI);
192 InstrMapping.erase(
MI);
199 insertNode(UMI,
nullptr);
208 if (
auto *UMI = InstrMapping.lookup(
MI)) {
209 invalidateUniqueMachineInstr(UMI);
210 InstrMapping.erase(
MI);
216 while (!TemporaryInsts.
empty()) {
223 assert(CSEOpt.get() &&
"CSEConfig not set");
224 return CSEOpt->shouldCSEOpc(Opc);
238 for (
auto &
MBB : MF) {
253 InstrMapping.clear();
254 UniqueInstrAllocator.
Reset();
255 TemporaryInsts.
clear();
260 OpcodeHitTable.
clear();
268 return OS.
str().c_str();
278 for (
auto &It : InstrMapping) {
283 CSEMap.FindNodeOrInsertPos(TmpID, InsertPos);
284 if (FoundNode != It.second)
286 "CSEMap mismatch, InstrMapping has MIs without "
287 "corresponding Nodes in CSEMap:\n%s",
294 if (!InstrMapping.count(UMI.MI))
296 "Node in CSE without InstrMapping:\n%s",
299 if (InstrMapping[UMI.MI] != &UMI)
301 "Mismatch in CSE mapping:\n%s\n%s",
312 dbgs() <<
"CSEInfo::CSE Hit for Opc " << It.first <<
" : " << It.second
322 for (
auto &
Op :
MI->operands())
391 if (
const auto *RB = RCOrRB.dyn_cast<
const RegisterBank *>())
409 }
else if (MO.
isImm())
426 if (!AlreadyComputed || Recompute) {
430 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 is an optimization pass for GlobalISel generic memory operations.
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.
A raw_ostream that writes to an std::string.
const GISelInstProfileBuilder & addNodeIDMBB(const MachineBasicBlock *MBB) const
Reg
All possible values of the reg field in the ModR/M byte.
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.
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 const char * stringify(const MachineInstr *MI, std::string &S)
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
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())
uint64_t getUniqueRAWLLTData() const
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.
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
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.
std::string & str()
Returns the string's reference.
void changingInstr(MachineInstr &MI) override
This instruction is about to be mutated in some way.