Go to the documentation of this file.
28 assert(
A->getParent() ==
B->getParent() &&
29 "Iterators should be in same block");
32 for (; &*
I !=
A && &*
I !=
B; ++
I)
39 void *&NodeInsertPos) {
41 assert(CSEInfo &&
"Can't get here without setting CSEInfo");
44 CSEInfo->getMachineInstrIfExists(
ID, CurMBB, NodeInsertPos);
53 }
else if (!dominates(
MI, CurrPos)) {
61 bool CSEMIRBuilder::canPerformCSEForOpc(
unsigned Opc)
const {
68 void CSEMIRBuilder::profileDstOp(
const DstOp &
Op,
70 switch (
Op.getDstOpKind()) {
72 B.addNodeIDRegType(
Op.getRegClass());
76 B.addNodeIDReg(
Op.getReg());
80 B.addNodeIDRegType(
Op.getLLTTy(*
getMRI()));
85 void CSEMIRBuilder::profileSrcOp(
const SrcOp &
Op,
87 switch (
Op.getSrcOpKind()) {
89 B.addNodeIDImmediate(
static_cast<int64_t
>(
Op.getImm()));
92 B.addNodeIDImmediate(
static_cast<int64_t
>(
Op.getPredicate()));
95 B.addNodeIDRegType(
Op.getReg());
101 unsigned Opc)
const {
105 B.addNodeIDOpcode(Opc);
108 void CSEMIRBuilder::profileEverything(
unsigned Opc,
ArrayRef<DstOp> DstOps,
113 profileMBBOpcode(
B, Opc);
115 profileDstOps(DstOps,
B);
117 profileSrcOps(SrcOps,
B);
120 B.addNodeIDFlag(*Flags);
124 void *NodeInsertPos) {
126 "Attempting to CSE illegal op");
128 getCSEInfo()->insertInstr(MIBInstr, NodeInsertPos);
133 if (DstOps.
size() == 1)
145 assert(checkCopyToDefsPossible(DstOps) &&
146 "Impossible return a single MIB with copies to multiple defs");
147 if (DstOps.
size() == 1) {
177 case TargetOpcode::G_ADD:
178 case TargetOpcode::G_PTR_ADD:
179 case TargetOpcode::G_AND:
180 case TargetOpcode::G_ASHR:
181 case TargetOpcode::G_LSHR:
182 case TargetOpcode::G_MUL:
183 case TargetOpcode::G_OR:
184 case TargetOpcode::G_SHL:
185 case TargetOpcode::G_SUB:
186 case TargetOpcode::G_XOR:
187 case TargetOpcode::G_UDIV:
188 case TargetOpcode::G_SDIV:
189 case TargetOpcode::G_UREM:
190 case TargetOpcode::G_SREM:
191 case TargetOpcode::G_SMIN:
192 case TargetOpcode::G_SMAX:
193 case TargetOpcode::G_UMIN:
194 case TargetOpcode::G_UMAX: {
196 assert(SrcOps.
size() == 2 &&
"Invalid sources");
198 LLT SrcTy = SrcOps[0].getLLTTy(*
getMRI());
200 if (Opc == TargetOpcode::G_PTR_ADD &&
218 case TargetOpcode::G_FADD:
219 case TargetOpcode::G_FSUB:
220 case TargetOpcode::G_FMUL:
221 case TargetOpcode::G_FDIV:
222 case TargetOpcode::G_FREM:
223 case TargetOpcode::G_FMINNUM:
224 case TargetOpcode::G_FMAXNUM:
225 case TargetOpcode::G_FMINNUM_IEEE:
226 case TargetOpcode::G_FMAXNUM_IEEE:
227 case TargetOpcode::G_FMINIMUM:
228 case TargetOpcode::G_FMAXIMUM:
229 case TargetOpcode::G_FCOPYSIGN: {
231 assert(SrcOps.
size() == 2 &&
"Invalid sources");
238 case TargetOpcode::G_SEXT_INREG: {
239 assert(DstOps.
size() == 1 &&
"Invalid dst ops");
240 assert(SrcOps.
size() == 2 &&
"Invalid src ops");
241 const DstOp &Dst = DstOps[0];
242 const SrcOp &Src0 = SrcOps[0];
243 const SrcOp &Src1 = SrcOps[1];
249 case TargetOpcode::G_SITOFP:
250 case TargetOpcode::G_UITOFP: {
252 assert(SrcOps.
size() == 1 &&
"Invalid sources");
259 case TargetOpcode::G_CTLZ: {
260 assert(SrcOps.
size() == 1 &&
"Expected one source");
261 assert(DstOps.
size() == 1 &&
"Expected one dest");
265 if (MaybeCsts->size() == 1)
269 LLT VecTy = DstOps[0].getLLTTy(*
getMRI());
270 for (
unsigned Cst : *MaybeCsts)
276 bool CanCopy = checkCopyToDefsPossible(DstOps);
277 if (!canPerformCSEForOpc(Opc))
290 void *InsertPos =
nullptr;
291 profileEverything(Opc, DstOps, SrcOps,
Flag, ProfBuilder);
295 return generateCopiesIfRequired(DstOps, MIB);
300 return memoizeMI(NewMIB, InsertPos);
305 constexpr
unsigned Opc = TargetOpcode::G_CONSTANT;
306 if (!canPerformCSEForOpc(Opc))
316 void *InsertPos =
nullptr;
317 profileMBBOpcode(ProfBuilder, Opc);
318 profileDstOp(Res, ProfBuilder);
323 return generateCopiesIfRequired({Res}, MIB);
327 return memoizeMI(NewMIB, InsertPos);
332 constexpr
unsigned Opc = TargetOpcode::G_FCONSTANT;
333 if (!canPerformCSEForOpc(Opc))
343 void *InsertPos =
nullptr;
344 profileMBBOpcode(ProfBuilder, Opc);
345 profileDstOp(Res, ProfBuilder);
350 return generateCopiesIfRequired({Res}, MIB);
353 return memoizeMI(NewMIB, InsertPos);
This is an optimization pass for GlobalISel generic memory operations.
void handleRemoveInst(MachineInstr *MI)
Remove this inst from the CSE map.
static const DILocation * getMergedLocation(const DILocation *LocA, const DILocation *LocB)
When two instructions are combined into a single instruction we also need to combine the original loc...
GISelCSEInfo * getCSEInfo()
MachineInstrBuilder buildSplatVector(const DstOp &Res, const SrcOp &Src)
Build and insert Res = G_BUILD_VECTOR with Src replicated to fill the number of elements.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
MachineRegisterInfo * getMRI()
Getter for MRI.
const GISelInstProfileBuilder & addNodeIDMachineOperand(const MachineOperand &MO) const
LLT getScalarType() const
Optional< APFloat > ConstantFoldFPBinOp(unsigned Opcode, const Register Op1, const Register Op2, const MachineRegisterInfo &MRI)
bool shouldCSE(unsigned Opc) const
MachineInstrBuilder buildBuildVector(const DstOp &Res, ArrayRef< Register > Ops)
Build and insert Res = G_BUILD_VECTOR Op0, ...
const DebugLoc & getDebugLoc()
Get the current instruction's debug location.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
This is the shared class of boolean and integer constants.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const DataLayout & getDataLayout() const
Optional< APInt > ConstantFoldExtOp(unsigned Opcode, const Register Op1, uint64_t Imm, const MachineRegisterInfo &MRI)
Flag
These should be considered private to the implementation of the MCInstrDesc class.
MachineFunction & getMF()
Getter for the function we currently build.
ConstantFP - Floating Point Values [float, double].
Optional< APFloat > ConstantFoldIntToFloat(unsigned Opcode, LLT DstTy, Register Src, const MachineRegisterInfo &MRI)
virtual void changingInstr(MachineInstr &MI)=0
This instruction is about to be mutated in some way.
MachineInstrBuilder buildFConstant(const DstOp &Res, const ConstantFP &Val) override
Build and insert Res = G_FCONSTANT Val.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Register getReg(unsigned Idx) const
Get the register for the operand index.
MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val) override
Build and insert Res = G_CONSTANT Val.
unsigned getAddressSpace() const
virtual void changedInstr(MachineInstr &MI)=0
This instruction was mutated in some way.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
virtual MachineInstrBuilder buildFConstant(const DstOp &Res, const ConstantFP &Val)
Build and insert Res = G_FCONSTANT Val.
void setInsertPt(MachineBasicBlock &MBB, MachineBasicBlock::iterator II)
Set the insertion point before the specified position.
Representation of each machine instruction.
MachineBasicBlock::iterator getInsertPt()
Current insertion point for new instructions.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MachineBasicBlock & getMBB() const
Getter for the basic block we currently build.
GISelChangeObserver * Observer
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineInstrBundleIterator< MachineInstr > iterator
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
void countOpcodeHit(unsigned Opc)
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
static MachineOperand CreateCImm(const ConstantInt *CI)
Abstract class that contains various methods for clients to notify about changes.
Optional< SmallVector< unsigned > > ConstantFoldCTLZ(Register Src, const MachineRegisterInfo &MRI)
Tries to constant fold a G_CTLZ operation on Src.
MachineInstrBuilder buildBuildVectorConstant(const DstOp &Res, ArrayRef< APInt > Ops)
Build and insert Res = G_BUILD_VECTOR Op0, ...
void setDebugLoc(DebugLoc DL)
Replace current source information with new such.
LLT getLLTTy(const MachineRegisterInfo &MRI) const
size_t size() const
size - Get the array size.
SmallVector< APInt > ConstantFoldVectorBinop(unsigned Opcode, const Register Op1, const Register Op2, const MachineRegisterInfo &MRI)
Tries to constant fold a vector binop with sources Op1 and Op2.
MachineIRBuilderState & getState()
Getter for the State.
LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
MachineInstrBuilder buildInstr(unsigned Opc, ArrayRef< DstOp > DstOps, ArrayRef< SrcOp > SrcOps, Optional< unsigned > Flag=None) override
static MachineOperand CreateFPImm(const ConstantFP *CFP)
reference emplace_back(ArgTypes &&... Args)
Optional< APInt > ConstantFoldBinOp(unsigned Opcode, const Register Op1, const Register Op2, const MachineRegisterInfo &MRI)