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;
125 for (
unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
132 bool OnlyOneUse = MRI->hasOneNonDBGUse(Reg);
156 if (!MRI->constrainRegClass(SrcReg, RC))
158 DEBUG(
dbgs() <<
"Coalescing: " << *DefMI);
162 MRI->clearKillFlags(SrcReg);
175 MachineCSE::isPhysDefTriviallyDead(
unsigned Reg,
178 unsigned LookAheadLeft = LookAheadLimit;
179 while (LookAheadLeft) {
181 while (I != E && I->isDebugValue())
188 bool SeenDef =
false;
189 for (
unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
221 bool &PhysUseDef)
const{
227 unsigned Reg = MO.
getReg();
233 if (!MRI->isConstantPhysReg(Reg, *MBB->
getParent()))
246 unsigned Reg = MO.
getReg();
252 if (PhysRefs.
count(Reg))
257 if (!MO.
isDead() && !isPhysDefTriviallyDead(Reg, I, MBB->
end()))
262 for (
unsigned i = 0, e = PhysDefs.
size(); i != e; ++i)
266 return !PhysRefs.
empty();
272 bool &NonLocal)
const {
279 bool CrossMBB =
false;
284 for (
unsigned i = 0, e = PhysDefs.
size(); i != e; ++i) {
285 if (MRI->isAllocatable(PhysDefs[i]) || MRI->isReserved(PhysDefs[i]))
295 unsigned LookAheadLeft = LookAheadLimit;
296 while (LookAheadLeft) {
298 while (I != E && I != EE && I->isDebugValue())
302 assert(CrossMBB &&
"Reaching end-of-MBB without finding MI?");
314 for (
unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
322 unsigned MOReg = MO.
getReg();
325 if (PhysRefs.
count(MOReg))
365 bool MachineCSE::isProfitableToCSE(
unsigned CSReg,
unsigned Reg,
371 bool MayIncreasePressure =
true;
374 MayIncreasePressure =
false;
376 for (
MachineInstr &MI : MRI->use_nodbg_instructions(CSReg)) {
379 for (
MachineInstr &MI : MRI->use_nodbg_instructions(Reg)) {
380 if (!CSUses.
count(&MI)) {
381 MayIncreasePressure =
true;
386 if (!MayIncreasePressure)
return true;
391 if (
TII->isAsCheapAsAMove(MI)) {
400 bool HasVRegUse =
false;
410 bool HasNonCopyUse =
false;
411 for (
MachineInstr &MI : MRI->use_nodbg_instructions(Reg)) {
414 HasNonCopyUse =
true;
426 for (
MachineInstr &MI : MRI->use_nodbg_instructions(CSReg)) {
427 HasPHI |= MI.
isPHI();
438 ScopeType *Scope =
new ScopeType(VNT);
439 ScopeMap[MBB] = Scope;
445 assert(SI != ScopeMap.end());
451 bool Changed =
false;
460 if (!isCSECandidate(MI))
463 bool FoundCSE = VNT.count(MI);
466 if (PerformTrivialCopyPropagation(MI, MBB)) {
474 FoundCSE = VNT.count(MI);
479 bool Commuted =
false;
484 FoundCSE = VNT.count(NewMI);
489 }
else if (!FoundCSE)
491 (void)
TII->commuteInstruction(MI);
498 bool CrossMBBPhysDef =
false;
501 bool PhysUseDef =
false;
502 if (FoundCSE && hasLivePhysRegDefUses(MI, MBB, PhysRefs,
503 PhysDefs, PhysUseDef)) {
512 unsigned CSVN = VNT.lookup(MI);
514 if (PhysRegDefsReach(CSMI, MI, PhysRefs, PhysDefs, CrossMBBPhysDef))
520 VNT.insert(MI, CurrVN++);
526 unsigned CSVN = VNT.lookup(MI);
529 DEBUG(
dbgs() <<
"*** Found a common subexpression: " << *CSMI);
536 for (
unsigned i = 0, e = MI->
getNumOperands(); NumDefs && i != e; ++i) {
540 unsigned OldReg = MO.
getReg();
553 if (OldReg == NewReg) {
560 "Do not CSE physical register defs!");
562 if (!isProfitableToCSE(NewReg, OldReg, CSMI, MI)) {
563 DEBUG(
dbgs() <<
"*** Not profitable, avoid CSE!\n");
571 if (!MRI->constrainRegClass(NewReg, OldRC)) {
572 DEBUG(
dbgs() <<
"*** Not the same register class, avoid CSE!\n");
577 CSEPairs.
push_back(std::make_pair(OldReg, NewReg));
583 for (
unsigned i = 0, e = CSEPairs.
size(); i != e; ++i) {
584 unsigned OldReg = CSEPairs[i].first;
585 unsigned NewReg = CSEPairs[i].second;
588 assert(Def !=
nullptr &&
"CSEd register has no unique definition?");
591 MRI->replaceRegWith(OldReg, NewReg);
592 MRI->clearKillFlags(NewReg);
597 for (
unsigned i = 0, e = ImplicitDefsToUpdate.
size(); i != e; ++i)
612 for (
auto ImplicitDef : ImplicitDefs)
614 ImplicitDef,
true, TRI))
619 for (
auto ImplicitDef : ImplicitDefs)
620 MRI->clearKillFlags(ImplicitDef);
623 if (CrossMBBPhysDef) {
626 while (!PhysDefs.
empty()) {
636 if (!PhysRefs.
empty())
642 VNT.insert(MI, CurrVN++);
646 ImplicitDefsToUpdate.
clear();
647 ImplicitDefs.clear();
659 if (OpenChildren[Node])
663 ExitScope(Node->getBlock());
667 unsigned Left = --OpenChildren[Parent];
670 ExitScope(Parent->getBlock());
687 const std::vector<MachineDomTreeNode*> &Children = Node->
getChildren();
688 unsigned NumChildren = Children.size();
689 OpenChildren[Node] = NumChildren;
690 for (
unsigned i = 0; i != NumChildren; ++i) {
694 }
while (!WorkList.
empty());
697 bool Changed =
false;
698 for (
unsigned i = 0, e = Scopes.
size(); i != e; ++i) {
702 Changed |= ProcessBlock(MBB);
704 ExitScopeIfDone(Node, OpenChildren);
717 AA = &getAnalysis<AliasAnalysis>();
718 DT = &getAnalysis<MachineDominatorTree>();
719 LookAheadLimit =
TII->getMachineCSELookAheadLimit();
720 return PerformCSE(DT->getRootNode());
void push_back(const T &Elt)
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
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...
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)
isVirtualRegister - 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.
void addLiveIn(unsigned Reg)
Adds the specified register as a live in.
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
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 LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
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
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
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...
unsigned getNumOperands() const
Access to explicit operands of the instruction.
char & MachineCSEID
MachineCSE - This pass performs global CSE on machine instructions.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
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
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.
bundle_iterator< MachineInstr, instr_iterator > iterator
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.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
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.
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore...
const std::vector< DomTreeNodeBase< NodeT > * > & getChildren() const
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
bool isInvariantLoad(AliasAnalysis *AA) const
Return true if this instruction is loading from a location whose value is invariant across the functi...
#define INITIALIZE_AG_DEPENDENCY(depName)
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)
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
machine Machine Common Subexpression false
DomTreeNodeBase< NodeT > * getIDom() const
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
isSuccessor - Return true if the specified MBB is a successor of this block.
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.
static bool clobbersPhysReg(const uint32_t *RegMask, unsigned PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
StringRef getName() const
getName - Return the name of the corresponding LLVM basic block, or "(null)".
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.
bundle_iterator< const MachineInstr, const_instr_iterator > const_iterator
bool isLiveIn(unsigned Reg) const
isLiveIn - Return true if the specified register is in the live in set.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
bool isCall(QueryType Type=AnyInBundle) const
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.
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
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
unsigned pred_size() const