32 #define DEBUG_TYPE "machine-cse"
34 STATISTIC(NumCoalesces,
"Number of copies coalesced");
35 STATISTIC(NumCSEs,
"Number of common subexpression eliminated");
37 "Number of physreg referencing common subexpr eliminated");
39 "Number of cross-MBB physreg referencing CS eliminated");
40 STATISTIC(NumCommutes,
"Number of copies coalesced after commuting");
66 void releaseMemory()
override {
72 unsigned LookAheadLimit;
77 typedef ScopedHTType::ScopeTy ScopeType;
85 bool isPhysDefTriviallyDead(
unsigned Reg,
92 bool &PhysUseDef)
const;
96 bool &NonLocal)
const;
98 bool isProfitableToCSE(
unsigned CSReg,
unsigned Reg,
112 "Machine Common Subexpression Elimination",
false,
false)
124 bool Changed =
false;
126 if (!MO.isReg() || !MO.isUse())
128 unsigned Reg = MO.getReg();
131 bool OnlyOneUse =
MRI->hasOneNonDBGUse(Reg);
155 if (!
MRI->constrainRegClass(SrcReg, RC))
157 DEBUG(
dbgs() <<
"Coalescing: " << *DefMI);
161 MRI->clearKillFlags(SrcReg);
174 MachineCSE::isPhysDefTriviallyDead(
unsigned Reg,
177 unsigned LookAheadLeft = LookAheadLimit;
178 while (LookAheadLeft) {
186 bool SeenDef =
false;
188 if (MO.isRegMask() && MO.clobbersPhysReg(Reg))
190 if (!MO.isReg() || !MO.getReg())
192 if (!TRI->regsOverlap(MO.getReg(),
Reg))
218 bool &PhysUseDef)
const{
221 if (!MO.isReg() || MO.isDef())
223 unsigned Reg = MO.getReg();
229 if (!
MRI->isConstantPhysReg(Reg))
239 if (!MO.isReg() || !MO.isDef())
241 unsigned Reg = MO.getReg();
247 if (PhysRefs.
count(Reg))
252 if (!MO.isDead() && !isPhysDefTriviallyDead(Reg, I, MBB->
end()))
257 for (
unsigned i = 0, e = PhysDefs.
size();
i != e; ++
i)
261 return !PhysRefs.
empty();
267 bool &NonLocal)
const {
274 bool CrossMBB =
false;
279 for (
unsigned i = 0, e = PhysDefs.
size(); i != e; ++
i) {
280 if (
MRI->isAllocatable(PhysDefs[i]) ||
MRI->isReserved(PhysDefs[i]))
290 unsigned LookAheadLeft = LookAheadLimit;
291 while (LookAheadLeft) {
293 while (I != E && I != EE && I->isDebugValue())
297 assert(CrossMBB &&
"Reaching end-of-MBB without finding MI?");
314 if (!MO.isReg() || !MO.isDef())
316 unsigned MOReg = MO.getReg();
319 if (PhysRefs.
count(MOReg))
357 if (MI->
getOpcode() == TargetOpcode::LOAD_STACK_GUARD)
365 bool MachineCSE::isProfitableToCSE(
unsigned CSReg,
unsigned Reg,
371 bool MayIncreasePressure =
true;
374 MayIncreasePressure =
false;
380 if (!CSUses.
count(&MI)) {
381 MayIncreasePressure =
true;
386 if (!MayIncreasePressure)
return true;
391 if (
TII->isAsCheapAsAMove(*MI)) {
400 bool HasVRegUse =
false;
402 if (MO.isReg() && MO.isUse() &&
409 bool HasNonCopyUse =
false;
413 HasNonCopyUse =
true;
426 HasPHI |= MI.
isPHI();
437 ScopeType *Scope =
new ScopeType(VNT);
438 ScopeMap[
MBB] = Scope;
444 assert(SI != ScopeMap.end());
450 bool Changed =
false;
459 if (!isCSECandidate(MI))
462 bool FoundCSE = VNT.count(MI);
465 if (PerformTrivialCopyPropagation(MI, MBB)) {
473 FoundCSE = VNT.count(MI);
478 bool Commuted =
false;
482 FoundCSE = VNT.count(NewMI);
485 NewMI->eraseFromParent();
487 }
else if (!FoundCSE)
489 (void)
TII->commuteInstruction(*MI);
496 bool CrossMBBPhysDef =
false;
499 bool PhysUseDef =
false;
500 if (FoundCSE && hasLivePhysRegDefUses(MI, MBB, PhysRefs,
501 PhysDefs, PhysUseDef)) {
510 unsigned CSVN = VNT.lookup(MI);
512 if (PhysRegDefsReach(CSMI, MI, PhysRefs, PhysDefs, CrossMBBPhysDef))
518 VNT.insert(MI, CurrVN++);
524 unsigned CSVN = VNT.lookup(MI);
527 DEBUG(
dbgs() <<
"*** Found a common subexpression: " << *CSMI);
534 for (
unsigned i = 0, e = MI->
getNumOperands(); NumDefs && i != e; ++
i) {
538 unsigned OldReg = MO.
getReg();
551 if (OldReg == NewReg) {
558 "Do not CSE physical register defs!");
560 if (!isProfitableToCSE(NewReg, OldReg, CSMI, MI)) {
561 DEBUG(
dbgs() <<
"*** Not profitable, avoid CSE!\n");
569 if (!
MRI->constrainRegClass(NewReg, OldRC)) {
570 DEBUG(
dbgs() <<
"*** Not the same register class, avoid CSE!\n");
575 CSEPairs.
push_back(std::make_pair(OldReg, NewReg));
581 for (std::pair<unsigned, unsigned> &CSEPair : CSEPairs) {
582 unsigned OldReg = CSEPair.first;
583 unsigned NewReg = CSEPair.second;
586 assert(Def !=
nullptr &&
"CSEd register has no unique definition?");
589 MRI->replaceRegWith(OldReg, NewReg);
590 MRI->clearKillFlags(NewReg);
595 for (
unsigned ImplicitDefToUpdate : ImplicitDefsToUpdate)
610 for (
auto ImplicitDef : ImplicitDefs)
612 ImplicitDef,
true, TRI))
617 for (
auto ImplicitDef : ImplicitDefs)
618 MRI->clearKillFlags(ImplicitDef);
621 if (CrossMBBPhysDef) {
624 while (!PhysDefs.
empty()) {
634 if (!PhysRefs.
empty())
640 VNT.insert(MI, CurrVN++);
644 ImplicitDefsToUpdate.clear();
645 ImplicitDefs.clear();
657 if (OpenChildren[Node])
661 ExitScope(Node->getBlock());
665 unsigned Left = --OpenChildren[Parent];
668 ExitScope(Parent->getBlock());
685 const std::vector<MachineDomTreeNode*> &Children = Node->
getChildren();
686 OpenChildren[Node] = Children.
size();
689 }
while (!WorkList.
empty());
692 bool Changed =
false;
698 ExitScopeIfDone(Node, OpenChildren);
711 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
712 DT = &getAnalysis<MachineDominatorTree>();
713 LookAheadLimit =
TII->getMachineCSELookAheadLimit();
714 return PerformCSE(DT->getRootNode());
void push_back(const T &Elt)
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
const std::vector< DomTreeNodeBase< NodeT > * > & getChildren() const
STATISTIC(NumFunctions,"Total number of functions")
unsigned getNumImplicitDefs() const
Return the number of implicit defs this instruct has.
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
void initializeMachineCSEPass(PassRegistry &)
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
void setIsDead(bool Val=true)
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
iterator_range< mop_iterator > operands()
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
Special DenseMapInfo traits to compare MachineInstr* by value of the instruction rather than by point...
bool isDereferenceableInvariantLoad(AliasAnalysis *AA) const
Return true if this load instruction never traps and points to a memory location whose value doesn't ...
DomTreeNodeBase< NodeT > * getIDom() const
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
LLVM_NODISCARD bool empty() const
char & MachineLoopInfoID
MachineLoopInfo - This pass is a loop analysis pass.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
Reg
All possible values of the reg field in the ModR/M byte.
RecyclingAllocator - This class wraps an Allocator, adding the functionality of recycling deleted obj...
LLVM_NODISCARD bool empty() const
unsigned getNumOperands() const
Access to explicit operands of the instruction.
char & MachineCSEID
MachineCSE - This pass performs global CSE on machine instructions.
Base class for the actual dominator tree node.
bool isCopyLike() const
Return true if the instruction behaves like a copy.
AnalysisUsage & addPreservedID(const void *ID)
COFF::MachineTypes Machine
static bool ProcessBlock(BasicBlock &BB, DominatorTree &DT, LoopInfo &LI, AAResults &AA)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
const MachineBasicBlock * getParent() const
TargetInstrInfo - Interface to description of machine instruction set.
bool isDebugValue() const
bool isImplicitDef() const
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template paramaters.
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
unsigned const MachineRegisterInfo * MRI
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
machine Machine Common Subexpression Elimination
void clearRegisterDeads(unsigned Reg)
Clear all dead flags on operands defining register Reg.
const MachineOperand & getOperand(unsigned i) const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
MCRegAliasIterator enumerates all registers aliasing Reg.
Represent the analysis usage information of a pass.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore...
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
unsigned getSubReg() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
pred_iterator pred_begin()
void setIsKill(bool Val=true)
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
machine Machine Common Subexpression false
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
LLVM_NODISCARD T pop_back_val()
void setPreservesCFG()
This function should be called by the pass, iff they do not:
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
StringRef getName() const
Return the name of the corresponding LLVM basic block, or "(null)".
IterT skipDebugInstructionsForward(IterT It, IterT End)
Increment It until it points to a non-debug instruction or to End and return the resulting iterator...
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool isCall(QueryType Type=AnyInBundle) const
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
unsigned getReg() const
getReg - Returns the register number.
bool isCommutable(QueryType Type=IgnoreBundle) const
Return true if this may be a 2- or 3-address instruction (of the form "X = op Y, Z, ..."), which produces the same result if Y and Z are exchanged.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
INITIALIZE_PASS_BEGIN(MachineCSE,"machine-cse","Machine Common Subexpression Elimination", false, false) INITIALIZE_PASS_END(MachineCSE
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
unsigned pred_size() const