49 #define DEBUG_TYPE "machine-cse" 51 STATISTIC(NumCoalesces,
"Number of copies coalesced");
52 STATISTIC(NumCSEs,
"Number of common subexpression eliminated");
54 "Number of physreg referencing common subexpr eliminated");
56 "Number of cross-MBB physreg referencing CS eliminated");
57 STATISTIC(NumCommutes,
"Number of copies coalesced after commuting");
86 void releaseMemory()
override {
97 using ScopeType = ScopedHTType::ScopeTy;
99 unsigned LookAheadLimit = 0;
105 bool PerformTrivialCopyPropagation(MachineInstr *
MI,
107 bool isPhysDefTriviallyDead(
unsigned Reg,
110 bool hasLivePhysRegDefUses(
const MachineInstr *
MI,
114 bool &PhysUseDef)
const;
115 bool PhysRegDefsReach(MachineInstr *CSMI, MachineInstr *
MI,
118 bool &NonLocal)
const;
119 bool isCSECandidate(MachineInstr *
MI);
120 bool isProfitableToCSE(
unsigned CSReg,
unsigned Reg,
121 MachineInstr *CSMI, MachineInstr *
MI);
137 "Machine Common Subexpression Elimination",
false,
false)
149 bool Changed =
false;
151 if (!MO.isReg() || !MO.isUse())
153 unsigned Reg = MO.getReg();
202 MachineCSE::isPhysDefTriviallyDead(
unsigned Reg,
205 unsigned LookAheadLeft = LookAheadLimit;
206 while (LookAheadLeft) {
214 bool SeenDef =
false;
216 if (MO.isRegMask() && MO.clobbersPhysReg(Reg))
218 if (!MO.isReg() || !MO.getReg())
261 bool &PhysUseDef)
const{
264 if (!MO.isReg() || MO.isDef())
266 unsigned Reg = MO.getReg();
282 if (!MO.isReg() || !MO.isDef())
284 unsigned Reg = MO.getReg();
290 if (PhysRefs.
count(Reg))
295 if (!MO.isDead() && !isPhysDefTriviallyDead(Reg, I, MBB->
end()))
300 for (
unsigned i = 0, e = PhysDefs.
size(); i != e; ++i)
304 return !PhysRefs.
empty();
310 bool &NonLocal)
const {
317 bool CrossMBB =
false;
322 for (
unsigned i = 0, e = PhysDefs.
size(); i != e; ++i) {
333 unsigned LookAheadLeft = LookAheadLimit;
334 while (LookAheadLeft) {
336 while (I != E && I != EE && I->isDebugInstr())
340 assert(CrossMBB &&
"Reaching end-of-MBB without finding MI?");
357 if (!MO.isReg() || !MO.isDef())
359 unsigned MOReg = MO.getReg();
362 if (PhysRefs.
count(MOReg))
400 if (MI->
getOpcode() == TargetOpcode::LOAD_STACK_GUARD)
408 bool MachineCSE::isProfitableToCSE(
unsigned CSReg,
unsigned Reg,
414 bool MayIncreasePressure =
true;
417 MayIncreasePressure =
false;
423 if (!CSUses.
count(&MI)) {
424 MayIncreasePressure =
true;
429 if (!MayIncreasePressure)
return true;
443 bool HasVRegUse =
false;
445 if (MO.isReg() && MO.isUse() &&
452 bool HasNonCopyUse =
false;
456 HasNonCopyUse =
true;
468 HasPHI |=
UseMI.isPHI();
478 ScopeType *Scope =
new ScopeType(VNT);
479 ScopeMap[MBB] = Scope;
485 assert(SI != ScopeMap.end());
491 bool Changed =
false;
500 if (!isCSECandidate(MI))
503 bool FoundCSE = VNT.count(MI);
506 if (PerformTrivialCopyPropagation(MI, MBB)) {
514 FoundCSE = VNT.count(MI);
519 bool Commuted =
false;
523 FoundCSE = VNT.count(NewMI);
526 NewMI->eraseFromParent();
528 }
else if (!FoundCSE)
537 bool CrossMBBPhysDef =
false;
540 bool PhysUseDef =
false;
541 if (FoundCSE && hasLivePhysRegDefUses(MI, MBB, PhysRefs,
542 PhysDefs, PhysUseDef)) {
551 unsigned CSVN = VNT.lookup(MI);
553 if (PhysRegDefsReach(CSMI, MI, PhysRefs, PhysDefs, CrossMBBPhysDef))
559 VNT.insert(MI, CurrVN++);
565 unsigned CSVN = VNT.lookup(MI);
568 LLVM_DEBUG(
dbgs() <<
"*** Found a common subexpression: " << *CSMI);
574 for (
unsigned i = 0, e = MI->
getNumOperands(); NumDefs && i != e; ++i) {
578 unsigned OldReg = MO.
getReg();
591 if (OldReg == NewReg) {
598 "Do not CSE physical register defs!");
600 if (!isProfitableToCSE(NewReg, OldReg, CSMI, MI)) {
611 dbgs() <<
"*** Not the same register constraints, avoid CSE!\n");
616 CSEPairs.
push_back(std::make_pair(OldReg, NewReg));
622 for (std::pair<unsigned, unsigned> &CSEPair : CSEPairs) {
623 unsigned OldReg = CSEPair.first;
624 unsigned NewReg = CSEPair.second;
627 assert(Def !=
nullptr &&
"CSEd register has no unique definition?");
636 for (
unsigned ImplicitDefToUpdate : ImplicitDefsToUpdate)
651 for (
auto ImplicitDef : ImplicitDefs)
653 ImplicitDef,
true, TRI))
654 MO->setIsKill(
false);
658 for (
auto ImplicitDef : ImplicitDefs)
662 if (CrossMBBPhysDef) {
665 while (!PhysDefs.
empty()) {
675 if (!PhysRefs.
empty())
681 VNT.insert(MI, CurrVN++);
685 ImplicitDefsToUpdate.
clear();
686 ImplicitDefs.
clear();
698 if (OpenChildren[Node])
702 ExitScope(Node->getBlock());
706 unsigned Left = --OpenChildren[Parent];
709 ExitScope(Parent->getBlock());
726 const std::vector<MachineDomTreeNode*> &Children = Node->
getChildren();
727 OpenChildren[Node] = Children.
size();
730 }
while (!WorkList.
empty());
733 bool Changed =
false;
739 ExitScopeIfDone(Node, OpenChildren);
752 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
753 DT = &getAnalysis<MachineDominatorTree>();
Machine Common Subexpression Elimination
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...
bool isCall(QueryType Type=AnyInBundle) const
bool isAllocatable(unsigned PhysReg) const
isAllocatable - Returns true when PhysReg belongs to an allocatable register class and it hasn't been...
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
This class represents lattice values for constants.
INITIALIZE_PASS_BEGIN(MachineCSE, DEBUG_TYPE, "Machine Common Subexpression Elimination", false, false) INITIALIZE_PASS_END(MachineCSE
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
void push_back(const T &Elt)
void initializeMachineCSEPass(PassRegistry &)
unsigned getReg() const
getReg - Returns the register number.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
MachineInstr * commuteInstruction(MachineInstr &MI, bool NewMI=false, unsigned OpIdx1=CommuteAnyOperandIndex, unsigned OpIdx2=CommuteAnyOperandIndex) const
This method commutes the operands of the given machine instruction MI.
unsigned getSubReg() const
bool constrainRegAttrs(unsigned Reg, unsigned ConstrainingReg, unsigned MinNumRegs=0)
Constrain the register class or the register bank of the virtual register Reg (and low-level type) to...
STATISTIC(NumFunctions, "Total number of functions")
unsigned const TargetRegisterInfo * TRI
void setIsDead(bool Val=true)
bool reservedRegsFrozen() const
reservedRegsFrozen - Returns true after freezeReservedRegs() was called to ensure the set of reserved...
iterator_range< mop_iterator > operands()
bool isCopyLike() const
Return true if the instruction behaves like a copy.
Special DenseMapInfo traits to compare MachineInstr* by value of the instruction rather than by point...
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
virtual unsigned getMachineCSELookAheadLimit() const
Return the value to use for the MachineCSE's LookAheadLimit, which is a heuristic used for CSE'ing ph...
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
LLVM_NODISCARD bool empty() const
char & MachineLoopInfoID
MachineLoopInfo - This pass is a loop analysis pass.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
unsigned getNumOperands() const
Retuns the total number of operands.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
RecyclingAllocator - This class wraps an Allocator, adding the functionality of recycling deleted obj...
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
char & MachineCSEID
MachineCSE - This pass performs global CSE on machine instructions.
void clearKillFlags(unsigned Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
void changeDebugValuesDefReg(unsigned Reg)
Find all DBG_VALUEs immediately following this instruction that point to a register def in this instr...
Base class for the actual dominator tree node.
const std::vector< DomTreeNodeBase * > & getChildren() const
AnalysisUsage & addPreservedID(const void *ID)
COFF::MachineTypes Machine
virtual const TargetInstrInfo * getInstrInfo() const
static bool ProcessBlock(BasicBlock &BB, DominatorTree &DT, LoopInfo &LI, AAResults &AA)
bool isDereferenceableInvariantLoad(AliasAnalysis *AA) const
Return true if this load instruction never traps and points to a memory location whose value doesn't ...
TargetInstrInfo - Interface to description of machine instruction set.
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
unsigned const MachineRegisterInfo * MRI
StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
void clearRegisterDeads(unsigned Reg)
Clear all dead flags on operands defining register Reg.
MachineInstrBuilder & UseMI
DomTreeNodeBase * getIDom() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
bool isImplicitDef() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
pred_iterator pred_begin()
bool isDebugInstr() const
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
bool isConstantPhysReg(unsigned PhysReg) const
Returns true if PhysReg is unallocatable and constant throughout the function.
virtual bool isAsCheapAsAMove(const MachineInstr &MI) const
Return true if the instruction is as cheap as a move instruction.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
bool regsOverlap(unsigned regA, unsigned regB) const
Returns true if the two registers are equal or alias each other.
MachineDomTreeNode * getRootNode() const
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...
MachineInstrBuilder MachineInstrBuilder & DefMI
LLVM_NODISCARD T pop_back_val()
void setPreservesCFG()
This function should be called by the pass, iff they do not:
unsigned pred_size() const
MachineInstr * getUniqueVRegDef(unsigned Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
void replaceRegWith(unsigned FromReg, unsigned ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
IterT skipDebugInstructionsForward(IterT It, IterT End)
Increment It until it points to a non-debug instruction or to End and return the resulting iterator...
const MachineBasicBlock * getParent() const
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.
LLVM_NODISCARD bool empty() const
unsigned getNumDefs() const
Returns the total number of definitions.
virtual bool isCallerPreservedPhysReg(unsigned PhysReg, const MachineFunction &MF) const
Physical registers that may be modified within a function but are guaranteed to be restored before an...
bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
bool hasOneNonDBGUse(unsigned RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug instruction using the specified regis...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
static bool isCallerPreservedOrConstPhysReg(unsigned Reg, const MachineFunction &MF, const TargetRegisterInfo &TRI)
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore...
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
const MachineOperand & getOperand(unsigned i) const
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(unsigned Reg) const
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
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.
bool isReserved(unsigned PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.