51#define DEBUG_TYPE "machine-cse"
53STATISTIC(NumCoalesces,
"Number of copies coalesced");
54STATISTIC(NumCSEs,
"Number of common subexpression eliminated");
55STATISTIC(NumPREs,
"Number of partial redundant expression"
56 " transformed to fully redundant");
58 "Number of physreg referencing common subexpr eliminated");
60 "Number of cross-MBB physreg referencing CS eliminated");
61STATISTIC(NumCommutes,
"Number of copies coalesced after commuting");
66 cl::desc(
"Threshold for the size of CSUses"));
70 cl::desc(
"Override the profitability heuristics for Machine CSE"));
83 : DT(DT), MBFI(MBFI) {}
84 bool run(MachineFunction &MF);
89 ScopedHashTableVal<MachineInstr *, unsigned>>;
91 ScopedHashTable<MachineInstr *, unsigned, MachineInstrExpressionTrait,
96 unsigned LookAheadLimit = 0;
97 DenseMap<MachineBasicBlock *, ScopeType *> ScopeMap;
98 DenseMap<MachineInstr *, MachineBasicBlock *, MachineInstrExpressionTrait>
104 bool PerformTrivialCopyPropagation(MachineInstr *
MI, MachineBasicBlock *
MBB);
105 bool isPhysDefTriviallyDead(MCRegister
Reg,
108 bool hasLivePhysRegDefUses(
const MachineInstr *
MI,
109 const MachineBasicBlock *
MBB,
110 SmallSet<MCRegister, 8> &PhysRefs,
111 PhysDefVector &PhysDefs,
bool &PhysUseDef)
const;
112 bool PhysRegDefsReach(MachineInstr *CSMI, MachineInstr *
MI,
113 const SmallSet<MCRegister, 8> &PhysRefs,
114 const PhysDefVector &PhysDefs,
bool &NonLocal)
const;
115 bool isCSECandidate(MachineInstr *
MI);
118 void EnterScope(MachineBasicBlock *
MBB);
119 void ExitScope(MachineBasicBlock *
MBB);
120 bool ProcessBlockCSE(MachineBasicBlock *
MBB);
122 DenseMap<MachineDomTreeNode *, unsigned> &OpenChildren);
125 bool isPRECandidate(MachineInstr *
MI, SmallSet<MCRegister, 8> &PhysRefs);
126 bool ProcessBlockPRE(MachineDominatorTree *MDT, MachineBasicBlock *
MBB);
127 bool PerformSimplePRE(MachineDominatorTree *DT);
130 bool isProfitableToHoistInto(MachineBasicBlock *CandidateBB,
131 MachineBasicBlock *
MBB, MachineBasicBlock *MBB1);
132 void releaseMemory();
139 MachineCSELegacy() : MachineFunctionPass(ID) {
143 bool runOnMachineFunction(MachineFunction &MF)
override;
145 void getAnalysisUsage(AnalysisUsage &AU)
const override {
151 AU.
addRequired<MachineBlockFrequencyInfoWrapperPass>();
152 AU.
addPreserved<MachineBlockFrequencyInfoWrapperPass>();
155 MachineFunctionProperties getRequiredProperties()
const override {
156 return MachineFunctionProperties().setIsSSA();
161char MachineCSELegacy::ID = 0;
166 "Machine Common Subexpression Elimination",
false,
false)
175bool MachineCSEImpl::PerformTrivialCopyPropagation(
MachineInstr *
MI,
179 Register Reg = MO.getReg();
180 if (!Reg.isVirtual())
182 bool OnlyOneUse = MRI->hasOneNonDBGUse(Reg);
183 MachineInstr *DefMI = MRI->getVRegDef(Reg);
184 if (!DefMI || !DefMI->isCopy())
186 Register SrcReg = DefMI->getOperand(1).getReg();
187 if (!SrcReg.isVirtual())
201 if (DefMI->getOperand(1).getSubReg())
203 if (!MRI->constrainRegAttrs(SrcReg, Reg))
205 LLVM_DEBUG(dbgs() <<
"Coalescing: " << *DefMI);
206 LLVM_DEBUG(dbgs() <<
"*** to: " << *MI);
210 MRI->clearKillFlags(SrcReg);
216 DefMI->changeDebugValuesDefReg(SrcReg);
218 DefMI->eraseFromParent();
227bool MachineCSEImpl::isPhysDefTriviallyDead(
230 unsigned LookAheadLeft = LookAheadLimit;
231 while (LookAheadLeft) {
239 bool SeenDef =
false;
240 for (
const MachineOperand &MO :
I->operands()) {
241 if (MO.isRegMask() && MO.clobbersPhysReg(
Reg))
243 if (!MO.isReg() || !MO.getReg())
245 if (!
TRI->regsOverlap(MO.getReg(),
Reg))
276 return TRI.isCallerPreservedPhysReg(
Reg, MF) ||
TII.isIgnorableUse(MO) ||
277 (
MRI.reservedRegsFrozen() &&
MRI.isConstantPhysReg(
Reg));
284bool MachineCSEImpl::hasLivePhysRegDefUses(
const MachineInstr *
MI,
285 const MachineBasicBlock *
MBB,
286 SmallSet<MCRegister, 8> &PhysRefs,
287 PhysDefVector &PhysDefs,
288 bool &PhysUseDef)
const {
290 for (
const MachineOperand &MO :
MI->all_uses()) {
299 for (MCRegAliasIterator AI(
Reg,
TRI,
true); AI.isValid(); ++AI)
308 const MachineOperand &MO = MOP.value();
323 PhysDefs.emplace_back(MOP.index(),
Reg);
327 for (
const auto &Def : PhysDefs)
328 for (MCRegAliasIterator AI(
Def.second,
TRI,
true); AI.isValid(); ++AI)
331 return !PhysRefs.
empty();
334bool MachineCSEImpl::PhysRegDefsReach(MachineInstr *CSMI, MachineInstr *
MI,
335 const SmallSet<MCRegister, 8> &PhysRefs,
336 const PhysDefVector &PhysDefs,
337 bool &NonLocal)
const {
341 const MachineBasicBlock *
MBB =
MI->getParent();
342 const MachineBasicBlock *CSMBB = CSMI->
getParent();
344 bool CrossMBB =
false;
349 for (
const auto &PhysDef : PhysDefs) {
350 if (
MRI->isAllocatable(PhysDef.second) ||
MRI->isReserved(PhysDef.second))
360 unsigned LookAheadLeft = LookAheadLimit;
361 while (LookAheadLeft) {
363 while (
I !=
E &&
I != EE &&
I->isDebugInstr())
367 assert(CrossMBB &&
"Reaching end-of-MBB without finding MI?");
379 for (
const MachineOperand &MO :
I->operands()) {
400bool MachineCSEImpl::isCSECandidate(MachineInstr *
MI) {
401 if (
MI->isPosition() ||
MI->isPHI() ||
MI->isImplicitDef() ||
MI->isKill() ||
402 MI->isInlineAsm() ||
MI->isDebugInstr() ||
MI->isJumpTableDebugInfo() ||
407 if (
MI->isCopyLike())
411 if (
MI->mayStore() ||
MI->isCall() ||
MI->isTerminator() ||
412 MI->mayRaiseFPException() ||
MI->hasUnmodeledSideEffects())
419 if (!
MI->isDereferenceableInvariantLoad())
428 if (
MI->getOpcode() == TargetOpcode::LOAD_STACK_GUARD)
438 MachineBasicBlock *CSBB,
447 bool MayIncreasePressure =
true;
449 MayIncreasePressure =
false;
450 SmallPtrSet<MachineInstr*, 8> CSUses;
452 for (MachineInstr &
MI :
MRI->use_nodbg_instructions(CSReg)) {
457 MayIncreasePressure =
true;
461 if (!MayIncreasePressure)
462 for (MachineInstr &
MI :
MRI->use_nodbg_instructions(
Reg)) {
464 MayIncreasePressure =
true;
469 if (!MayIncreasePressure)
return true;
475 MachineBasicBlock *BB =
MI->getParent();
482 bool HasVRegUse =
false;
483 for (
const MachineOperand &MO :
MI->all_uses()) {
490 bool HasNonCopyUse =
false;
491 for (MachineInstr &
MI :
MRI->use_nodbg_instructions(
Reg)) {
493 if (!
MI.isCopyLike()) {
494 HasNonCopyUse =
true;
505 for (MachineInstr &
UseMI :
MRI->use_nodbg_instructions(CSReg)) {
506 HasPHI |=
UseMI.isPHI();
507 if (
UseMI.getParent() ==
MI->getParent())
514void MachineCSEImpl::EnterScope(MachineBasicBlock *
MBB) {
516 ScopeType *
Scope =
new ScopeType(VNT);
520void MachineCSEImpl::ExitScope(MachineBasicBlock *
MBB) {
522 DenseMap<MachineBasicBlock*, ScopeType*>::iterator
SI = ScopeMap.find(
MBB);
523 assert(SI != ScopeMap.end());
528bool MachineCSEImpl::ProcessBlockCSE(MachineBasicBlock *
MBB) {
532 SmallVector<unsigned, 2> ImplicitDefsToUpdate;
535 if (!isCSECandidate(&
MI))
538 bool FoundCSE = VNT.
count(&
MI);
541 if (PerformTrivialCopyPropagation(&
MI,
MBB)) {
554 bool Commuted =
false;
555 if (!FoundCSE &&
MI.isCommutable()) {
556 if (MachineInstr *NewMI =
TII->commuteInstruction(
MI)) {
558 FoundCSE = VNT.
count(NewMI);
561 NewMI->eraseFromParent();
563 }
else if (!FoundCSE)
565 (void)
TII->commuteInstruction(
MI);
572 bool CrossMBBPhysDef =
false;
573 SmallSet<MCRegister, 8> PhysRefs;
574 PhysDefVector PhysDefs;
575 bool PhysUseDef =
false;
577 hasLivePhysRegDefUses(&
MI,
MBB, PhysRefs, PhysDefs, PhysUseDef)) {
587 MachineInstr *CSMI = Exps[CSVN];
588 if (PhysRegDefsReach(CSMI, &
MI, PhysRefs, PhysDefs, CrossMBBPhysDef))
601 MachineInstr *CSMI = Exps[CSVN];
603 LLVM_DEBUG(
dbgs() <<
"*** Found a common subexpression: " << *CSMI);
614 if (
MI.isConvergent() &&
MI.getParent() != CSMI->
getParent()) {
615 LLVM_DEBUG(
dbgs() <<
"*** Convergent MI and subexpression exist in "
616 "different BBs, avoid CSE!\n");
624 unsigned NumDefs =
MI.getNumDefs();
626 for (
unsigned i = 0, e =
MI.getNumOperands(); NumDefs && i != e; ++i) {
627 MachineOperand &MO =
MI.getOperand(i);
643 if (OldReg == NewReg) {
649 "Do not CSE physical register defs!");
651 if (!isProfitableToCSE(NewReg, OldReg, CSMI->
getParent(), &
MI)) {
660 if (!
MRI->constrainRegAttrs(NewReg, OldReg)) {
662 dbgs() <<
"*** Not the same register constraints, avoid CSE!\n");
673 for (
const std::pair<Register, Register> &CSEPair : CSEPairs) {
677 MachineInstr *
Def =
MRI->getUniqueVRegDef(NewReg);
678 assert(Def !=
nullptr &&
"CSEd register has no unique definition?");
679 Def->clearRegisterDeads(NewReg);
681 MRI->replaceRegWith(OldReg, NewReg);
682 MRI->clearKillFlags(NewReg);
687 for (
unsigned ImplicitDefToUpdate : ImplicitDefsToUpdate)
689 for (
const auto &PhysDef : PhysDefs)
690 if (!
MI.getOperand(PhysDef.first).isDead())
705 for (
auto ImplicitDef : ImplicitDefs)
706 if (MachineOperand *MO =
II->findRegisterUseOperand(
707 ImplicitDef,
TRI,
true))
712 for (
auto ImplicitDef : ImplicitDefs)
713 MRI->clearKillFlags(ImplicitDef);
716 if (CrossMBBPhysDef) {
719 while (!PhysDefs.empty()) {
720 auto LiveIn = PhysDefs.pop_back_val();
727 MI.eraseFromParent();
729 if (!PhysRefs.
empty())
739 ImplicitDefsToUpdate.clear();
740 ImplicitDefs.clear();
749void MachineCSEImpl::ExitScopeIfDone(
751 DenseMap<MachineDomTreeNode *, unsigned> &OpenChildren) {
752 if (OpenChildren[Node])
756 ExitScope(
Node->getBlock());
760 unsigned Left = --OpenChildren[Parent];
763 ExitScope(Parent->getBlock());
771 DenseMap<MachineDomTreeNode*, unsigned> OpenChildren;
780 OpenChildren[
Node] =
Node->getNumChildren();
782 }
while (!WorkList.
empty());
787 MachineBasicBlock *
MBB =
Node->getBlock();
791 ExitScopeIfDone(Node, OpenChildren);
800bool MachineCSEImpl::isPRECandidate(MachineInstr *
MI,
801 SmallSet<MCRegister, 8> &PhysRefs) {
802 if (!isCSECandidate(
MI) ||
803 MI->isNotDuplicable() ||
806 MI->getNumDefs() != 1 ||
807 MI->getNumExplicitDefs() != 1)
810 for (
const MachineOperand &MO :
MI->operands()) {
822bool MachineCSEImpl::ProcessBlockPRE(MachineDominatorTree *DT,
823 MachineBasicBlock *
MBB) {
826 SmallSet<MCRegister, 8> PhysRefs;
827 if (!isPRECandidate(&
MI, PhysRefs))
834 auto *MBB1 = It->second;
837 "MBB cannot properly dominate MBB1 while DFS through dominators tree!");
839 if (!CMBB->isLegalToHoistInto())
842 if (!isProfitableToHoistInto(CMBB,
MBB, MBB1))
849 if (BB !=
nullptr && BB1 !=
nullptr &&
859 if (
MI.isConvergent() && CMBB !=
MBB)
865 PhysDefVector PhysDefs;
866 if (!PhysRefs.
empty() &&
867 !PhysRegDefsReach(&*(CMBB->getFirstTerminator()), &
MI, PhysRefs,
872 "First operand of instr with one explicit def must be this def");
875 if (!isProfitableToCSE(NewReg, VReg, CMBB, &
MI))
877 MachineInstr &NewMI =
878 TII->duplicate(*CMBB, CMBB->getFirstTerminator(),
MI);
902bool MachineCSEImpl::PerformSimplePRE(MachineDominatorTree *DT) {
912 MachineBasicBlock *
MBB =
Node->getBlock();
915 }
while (!BBs.
empty());
920bool MachineCSEImpl::isProfitableToHoistInto(MachineBasicBlock *CandidateBB,
921 MachineBasicBlock *
MBB,
922 MachineBasicBlock *MBB1) {
927 "CandidateBB should dominate MBB1");
932void MachineCSEImpl::releaseMemory() {
938bool MachineCSEImpl::run(MachineFunction &MF) {
942 LookAheadLimit =
TII->getMachineCSELookAheadLimit();
943 bool ChangedPRE, ChangedCSE;
944 ChangedPRE = PerformSimplePRE(DT);
947 return ChangedPRE || ChangedCSE;
957 MachineCSEImpl Impl(&MDT, &MBFI);
975 getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
977 getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
978 MachineCSEImpl Impl(&MDT, &MBFI);
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
const HexagonInstrInfo * TII
static bool isCallerPreservedOrConstPhysReg(MCRegister Reg, const MachineOperand &MO, const MachineFunction &MF, const TargetRegisterInfo &TRI, const TargetInstrInfo &TII)
static cl::opt< int > CSUsesThreshold("csuses-threshold", cl::Hidden, cl::init(1024), cl::desc("Threshold for the size of CSUses"))
static cl::opt< bool > AggressiveMachineCSE("aggressive-machine-cse", cl::Hidden, cl::init(false), cl::desc("Override the profitability heuristics for Machine CSE"))
Register const TargetRegisterInfo * TRI
Promote Memory to Register
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addPreservedID(const void *ID)
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
DomTreeNodeBase< NodeT > * getRootNode()
getRootNode - This returns the entry node for the CFG of the function.
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B) const
Find nearest common dominator basic block for basic block A and B.
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
bool isAsCheapAsAMove(const MachineInstr &MI) const override
Wrapper class representing physical registers. Should be passed by value.
An RAII based helper class to modify MachineFunctionProperties when running pass.
unsigned pred_size() const
MachineInstrBundleIterator< const MachineInstr > const_iterator
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
pred_iterator pred_begin()
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
LLVM_ABI BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const
getblockFreq - Return block frequency.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *B) const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
const MachineOperand & getOperand(unsigned i) const
void setDebugLoc(DebugLoc DL)
Replace current source information with new such.
Analysis pass that exposes the MachineLoopInfo for a machine function.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
void setIsDead(bool Val=true)
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
void setIsKill(bool Val=true)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
size_type count(const K &Key) const
Return 1 if the specified key is in the table, 0 otherwise.
void insert(const K &Key, const V &Val)
V lookup(const K &Key) const
ScopedHashTableScope< MachineInstr *, unsigned, MachineInstrExpressionTrait, AllocatorTy > ScopeTy
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
Scope
Defines the scope in which this symbol should be visible: Default â Visible in the public interface o...
NodeAddr< DefNode * > Def
NodeAddr< NodeBase * > Node
This is an optimization pass for GlobalISel generic memory operations.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
IterT skipDebugInstructionsForward(IterT It, IterT End, bool SkipPseudoOp=true)
Increment It until it points to a non-debug instruction or to End and return the resulting iterator.
LLVM_ABI char & MachineLoopInfoID
MachineLoopInfo - This pass is a loop analysis pass.
LLVM_ABI void initializeMachineCSELegacyPass(PassRegistry &)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
DomTreeNodeBase< MachineBasicBlock > MachineDomTreeNode
LLVM_ABI char & MachineCSELegacyID
MachineCSE - This pass performs global CSE on machine instructions.
LLVM_ABI bool isPotentiallyReachable(const Instruction *From, const Instruction *To, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet=nullptr, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr)
Determine whether instruction 'To' is reachable from 'From', without passing through any blocks in Ex...