52#define DEBUG_TYPE "machine-cse"
54STATISTIC(NumCoalesces,
"Number of copies coalesced");
55STATISTIC(NumCSEs,
"Number of common subexpression eliminated");
56STATISTIC(NumPREs,
"Number of partial redundant expression"
57 " transformed to fully redundant");
59 "Number of physreg referencing common subexpr eliminated");
61 "Number of cross-MBB physreg referencing CS eliminated");
62STATISTIC(NumCommutes,
"Number of copies coalesced after commuting");
67 cl::desc(
"Threshold for the size of CSUses"));
71 cl::desc(
"Override the profitability heuristics for Machine CSE"));
84 : DT(DT), MBFI(MBFI) {}
85 bool run(MachineFunction &MF);
90 ScopedHashTableVal<MachineInstr *, unsigned>>;
92 ScopedHashTable<MachineInstr *, unsigned, MachineInstrExpressionTrait,
97 unsigned LookAheadLimit = 0;
98 DenseMap<MachineBasicBlock *, ScopeType *> ScopeMap;
99 DenseMap<MachineInstr *, MachineBasicBlock *, MachineInstrExpressionTrait>
105 bool PerformTrivialCopyPropagation(MachineInstr *
MI, MachineBasicBlock *
MBB);
106 bool isPhysDefTriviallyDead(MCRegister
Reg,
109 bool hasLivePhysRegDefUses(
const MachineInstr *
MI,
110 const MachineBasicBlock *
MBB,
111 SmallSet<MCRegister, 8> &PhysRefs,
112 PhysDefVector &PhysDefs,
bool &PhysUseDef)
const;
113 bool PhysRegDefsReach(MachineInstr *CSMI, MachineInstr *
MI,
114 const SmallSet<MCRegister, 8> &PhysRefs,
115 const PhysDefVector &PhysDefs,
bool &NonLocal)
const;
116 bool isCSECandidate(MachineInstr *
MI);
119 void EnterScope(MachineBasicBlock *
MBB);
120 void ExitScope(MachineBasicBlock *
MBB);
121 bool ProcessBlockCSE(MachineBasicBlock *
MBB);
123 DenseMap<MachineDomTreeNode *, unsigned> &OpenChildren);
126 bool isPRECandidate(MachineInstr *
MI, SmallSet<MCRegister, 8> &PhysRefs);
127 bool ProcessBlockPRE(MachineDominatorTree *MDT, MachineBasicBlock *
MBB);
128 bool PerformSimplePRE(MachineDominatorTree *DT);
131 bool isProfitableToHoistInto(MachineBasicBlock *CandidateBB,
132 MachineBasicBlock *
MBB, MachineBasicBlock *MBB1);
133 void releaseMemory();
140 MachineCSELegacy() : MachineFunctionPass(ID) {}
142 bool runOnMachineFunction(MachineFunction &MF)
override;
144 void getAnalysisUsage(AnalysisUsage &AU)
const override {
148 AU.
addRequired<MachineBlockFrequencyInfoWrapperPass>();
151 MachineFunctionProperties getRequiredProperties()
const override {
152 return MachineFunctionProperties().setIsSSA();
157char MachineCSELegacy::ID = 0;
162 "Machine Common Subexpression Elimination",
false,
false)
171bool MachineCSEImpl::PerformTrivialCopyPropagation(
MachineInstr *
MI,
175 Register Reg = MO.getReg();
176 if (!Reg.isVirtual())
178 bool OnlyOneUse = MRI->hasOneNonDBGUse(Reg);
179 MachineInstr *DefMI = MRI->getVRegDef(Reg);
180 if (!DefMI || !DefMI->isCopy())
182 Register SrcReg = DefMI->getOperand(1).getReg();
183 if (!SrcReg.isVirtual())
197 if (DefMI->getOperand(1).getSubReg())
199 if (!MRI->constrainRegAttrs(SrcReg, Reg))
201 LLVM_DEBUG(dbgs() <<
"Coalescing: " << *DefMI);
202 LLVM_DEBUG(dbgs() <<
"*** to: " << *MI);
206 MRI->clearKillFlags(SrcReg);
212 DefMI->changeDebugValuesDefReg(SrcReg);
214 DefMI->eraseFromParent();
223bool MachineCSEImpl::isPhysDefTriviallyDead(
226 unsigned LookAheadLeft = LookAheadLimit;
227 while (LookAheadLeft) {
235 bool SeenDef =
false;
236 for (
const MachineOperand &MO :
I->operands()) {
237 if (MO.isRegMask() && MO.clobbersPhysReg(
Reg))
239 if (!MO.isReg() || !MO.getReg())
241 if (!
TRI->regsOverlap(MO.getReg(),
Reg))
272 return TRI.isCallerPreservedPhysReg(
Reg, MF) ||
TII.isIgnorableUse(MO) ||
280bool MachineCSEImpl::hasLivePhysRegDefUses(
const MachineInstr *
MI,
281 const MachineBasicBlock *
MBB,
282 SmallSet<MCRegister, 8> &PhysRefs,
283 PhysDefVector &PhysDefs,
284 bool &PhysUseDef)
const {
286 for (
const MachineOperand &MO :
MI->all_uses()) {
295 for (MCRegAliasIterator AI(
Reg,
TRI,
true); AI.isValid(); ++AI)
304 const MachineOperand &MO = MOP.value();
319 PhysDefs.emplace_back(MOP.index(),
Reg);
323 for (
const auto &Def : PhysDefs)
324 for (MCRegAliasIterator AI(
Def.second,
TRI,
true); AI.isValid(); ++AI)
327 return !PhysRefs.
empty();
330bool MachineCSEImpl::PhysRegDefsReach(MachineInstr *CSMI, MachineInstr *
MI,
331 const SmallSet<MCRegister, 8> &PhysRefs,
332 const PhysDefVector &PhysDefs,
333 bool &NonLocal)
const {
337 const MachineBasicBlock *
MBB =
MI->getParent();
338 const MachineBasicBlock *CSMBB = CSMI->
getParent();
340 bool CrossMBB =
false;
345 for (
const auto &PhysDef : PhysDefs) {
356 unsigned LookAheadLeft = LookAheadLimit;
357 while (LookAheadLeft) {
359 while (
I !=
E &&
I != EE &&
I->isDebugInstr())
363 assert(CrossMBB &&
"Reaching end-of-MBB without finding MI?");
375 for (
const MachineOperand &MO :
I->operands()) {
396bool MachineCSEImpl::isCSECandidate(MachineInstr *
MI) {
397 if (
MI->isPosition() ||
MI->isPHI() ||
MI->isImplicitDef() ||
MI->isKill() ||
398 MI->isInlineAsm() ||
MI->isDebugInstr() ||
MI->isJumpTableDebugInfo() ||
403 if (
MI->isCopyLike())
407 if (
MI->mayStore() ||
MI->isCall() ||
MI->isTerminator() ||
408 MI->mayRaiseFPException() ||
MI->hasUnmodeledSideEffects())
415 if (!
MI->isDereferenceableInvariantLoad())
424 if (
MI->getOpcode() == TargetOpcode::LOAD_STACK_GUARD)
434 MachineBasicBlock *CSBB,
443 bool MayIncreasePressure =
true;
445 MayIncreasePressure =
false;
446 SmallPtrSet<MachineInstr*, 8> CSUses;
453 MayIncreasePressure =
true;
457 if (!MayIncreasePressure)
460 MayIncreasePressure =
true;
465 if (!MayIncreasePressure)
return true;
471 MachineBasicBlock *BB =
MI->getParent();
478 bool HasVRegUse =
false;
479 for (
const MachineOperand &MO :
MI->all_uses()) {
486 bool HasNonCopyUse =
false;
489 if (!
MI.isCopyLike()) {
490 HasNonCopyUse =
true;
502 HasPHI |=
UseMI.isPHI();
503 if (
UseMI.getParent() ==
MI->getParent())
510void MachineCSEImpl::EnterScope(MachineBasicBlock *
MBB) {
512 ScopeType *
Scope =
new ScopeType(VNT);
516void MachineCSEImpl::ExitScope(MachineBasicBlock *
MBB) {
518 auto SI = ScopeMap.find(
MBB);
519 assert(SI != ScopeMap.end());
524bool MachineCSEImpl::ProcessBlockCSE(MachineBasicBlock *
MBB) {
528 SmallVector<unsigned, 2> ImplicitDefsToUpdate;
531 if (!isCSECandidate(&
MI))
534 bool FoundCSE = VNT.
count(&
MI);
537 if (PerformTrivialCopyPropagation(&
MI,
MBB)) {
550 bool Commuted =
false;
551 if (!FoundCSE &&
MI.isCommutable()) {
552 if (MachineInstr *NewMI =
TII->commuteInstruction(
MI)) {
554 FoundCSE = VNT.
count(NewMI);
557 NewMI->eraseFromParent();
559 }
else if (!FoundCSE)
561 (void)
TII->commuteInstruction(
MI);
568 bool CrossMBBPhysDef =
false;
569 SmallSet<MCRegister, 8> PhysRefs;
570 PhysDefVector PhysDefs;
571 bool PhysUseDef =
false;
573 hasLivePhysRegDefUses(&
MI,
MBB, PhysRefs, PhysDefs, PhysUseDef)) {
583 MachineInstr *CSMI = Exps[CSVN];
584 if (PhysRegDefsReach(CSMI, &
MI, PhysRefs, PhysDefs, CrossMBBPhysDef))
597 MachineInstr *CSMI = Exps[CSVN];
599 LLVM_DEBUG(
dbgs() <<
"*** Found a common subexpression: " << *CSMI);
610 if (
MI.isConvergent() &&
MI.getParent() != CSMI->
getParent()) {
611 LLVM_DEBUG(
dbgs() <<
"*** Convergent MI and subexpression exist in "
612 "different BBs, avoid CSE!\n");
620 unsigned NumDefs =
MI.getNumDefs();
622 for (
unsigned i = 0, e =
MI.getNumOperands(); NumDefs && i != e; ++i) {
623 MachineOperand &MO =
MI.getOperand(i);
639 if (OldReg == NewReg) {
645 "Do not CSE physical register defs!");
647 if (!isProfitableToCSE(NewReg, OldReg, CSMI->
getParent(), &
MI)) {
658 dbgs() <<
"*** Not the same register constraints, avoid CSE!\n");
669 for (
const std::pair<Register, Register> &CSEPair : CSEPairs) {
674 assert(Def !=
nullptr &&
"CSEd register has no unique definition?");
675 Def->clearRegisterDeads(NewReg);
683 for (
unsigned ImplicitDefToUpdate : ImplicitDefsToUpdate)
685 for (
const auto &PhysDef : PhysDefs)
686 if (!
MI.getOperand(PhysDef.first).isDead())
701 for (
auto ImplicitDef : ImplicitDefs)
702 if (MachineOperand *MO =
II->findRegisterUseOperand(
703 ImplicitDef,
TRI,
true))
708 for (
auto ImplicitDef : ImplicitDefs)
712 if (CrossMBBPhysDef) {
715 while (!PhysDefs.empty()) {
716 auto LiveIn = PhysDefs.pop_back_val();
723 MI.eraseFromParent();
725 if (!PhysRefs.
empty())
735 ImplicitDefsToUpdate.clear();
736 ImplicitDefs.clear();
745void MachineCSEImpl::ExitScopeIfDone(
747 DenseMap<MachineDomTreeNode *, unsigned> &OpenChildren) {
748 if (OpenChildren[Node])
752 ExitScope(
Node->getBlock());
756 unsigned Left = --OpenChildren[Parent];
759 ExitScope(Parent->getBlock());
767 DenseMap<MachineDomTreeNode*, unsigned> OpenChildren;
776 size_t WorkListSize = WorkList.
size();
778 OpenChildren[
Node] = WorkList.
size() - WorkListSize;
779 }
while (!WorkList.
empty());
784 MachineBasicBlock *
MBB =
Node->getBlock();
788 ExitScopeIfDone(Node, OpenChildren);
797bool MachineCSEImpl::isPRECandidate(MachineInstr *
MI,
798 SmallSet<MCRegister, 8> &PhysRefs) {
799 if (!isCSECandidate(
MI) ||
800 MI->isNotDuplicable() ||
803 MI->getNumDefs() != 1 ||
804 MI->getNumExplicitDefs() != 1)
807 for (
const MachineOperand &MO :
MI->operands()) {
819bool MachineCSEImpl::ProcessBlockPRE(MachineDominatorTree *DT,
820 MachineBasicBlock *
MBB) {
823 SmallSet<MCRegister, 8> PhysRefs;
824 if (!isPRECandidate(&
MI, PhysRefs))
831 auto *MBB1 = It->second;
834 "MBB cannot properly dominate MBB1 while DFS through dominators tree!");
836 if (!CMBB->isLegalToHoistInto())
839 if (!isProfitableToHoistInto(CMBB,
MBB, MBB1))
846 if (BB !=
nullptr && BB1 !=
nullptr &&
856 if (
MI.isConvergent() && CMBB !=
MBB)
862 PhysDefVector PhysDefs;
863 if (!PhysRefs.
empty() &&
864 !PhysRegDefsReach(&*(CMBB->getFirstTerminator()), &
MI, PhysRefs,
869 "First operand of instr with one explicit def must be this def");
872 if (!isProfitableToCSE(NewReg, VReg, CMBB, &
MI))
874 MachineInstr &NewMI =
875 TII->duplicate(*CMBB, CMBB->getFirstTerminator(),
MI);
899bool MachineCSEImpl::PerformSimplePRE(MachineDominatorTree *DT) {
909 MachineBasicBlock *
MBB =
Node->getBlock();
912 }
while (!BBs.
empty());
917bool MachineCSEImpl::isProfitableToHoistInto(MachineBasicBlock *CandidateBB,
918 MachineBasicBlock *
MBB,
919 MachineBasicBlock *MBB1) {
924 "CandidateBB should dominate MBB1");
929void MachineCSEImpl::releaseMemory() {
935bool MachineCSEImpl::run(MachineFunction &MF) {
939 LookAheadLimit =
TII->getMachineCSELookAheadLimit();
940 bool ChangedPRE, ChangedCSE;
941 ChangedPRE = PerformSimplePRE(DT);
944 return ChangedPRE || ChangedCSE;
954 MachineCSEImpl Impl(&MDT, &MBFI);
969 getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
971 getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
972 MachineCSEImpl Impl(&MDT, &MBFI);
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 & addRequired()
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.
LLVM_ABI 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.
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,...
LLVM_ABI void clearKillFlags(Register Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
bool reservedRegsFrozen() const
reservedRegsFrozen - Returns true after freezeReservedRegs() was called to ensure the set of reserved...
bool isAllocatable(MCRegister PhysReg) const
isAllocatable - Returns true when PhysReg belongs to an allocatable register class and it hasn't been...
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
LLVM_ABI bool isConstantPhysReg(MCRegister PhysReg) const
Returns true if PhysReg is unallocatable and constant throughout the function.
LLVM_ABI Register cloneVirtualRegister(Register VReg, StringRef Name="")
Create and return a new virtual register in the function with the same attributes as the given regist...
LLVM_ABI bool constrainRegAttrs(Register Reg, Register ConstrainingReg, unsigned MinNumRegs=0)
Constrain the register class or the register bank of the virtual register Reg (and low-level type) to...
LLVM_ABI void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
LLVM_ABI MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
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)
DXILDebugInfoMap run(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 raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
DomTreeNodeBase< MachineBasicBlock > MachineDomTreeNode
LLVM_ABI bool isPotentiallyReachable(const Instruction *From, const Instruction *To, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet=nullptr, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr, const CycleInfo *CI=nullptr)
Determine whether instruction 'To' is reachable from 'From', without passing through any blocks in Ex...
LLVM_ABI char & MachineCSELegacyID
MachineCSE - This pass performs global CSE on machine instructions.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.