12cab237bSDimitry Andric //===- MachineCSE.cpp - Machine Common Subexpression Elimination Pass -----===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This pass performs global common subexpression elimination on machine
11f22ef01cSRoman Divacky // instructions using a scoped hash table based value numbering scheme. It
12f22ef01cSRoman Divacky // must be run while the machine function is still in SSA form.
13f22ef01cSRoman Divacky //
14f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
15f22ef01cSRoman Divacky
16f22ef01cSRoman Divacky #include "llvm/ADT/DenseMap.h"
17f22ef01cSRoman Divacky #include "llvm/ADT/ScopedHashTable.h"
182cab237bSDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
192754fe60SDimitry Andric #include "llvm/ADT/SmallSet.h"
202cab237bSDimitry Andric #include "llvm/ADT/SmallVector.h"
21f22ef01cSRoman Divacky #include "llvm/ADT/Statistic.h"
22139f7f9bSDimitry Andric #include "llvm/Analysis/AliasAnalysis.h"
232cab237bSDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
24139f7f9bSDimitry Andric #include "llvm/CodeGen/MachineDominators.h"
252cab237bSDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
262cab237bSDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
27139f7f9bSDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
282cab237bSDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
29139f7f9bSDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
30db17bf38SDimitry Andric #include "llvm/CodeGen/Passes.h"
312cab237bSDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
322cab237bSDimitry Andric #include "llvm/CodeGen/TargetOpcodes.h"
332cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
342cab237bSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
352cab237bSDimitry Andric #include "llvm/MC/MCInstrDesc.h"
362cab237bSDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
372cab237bSDimitry Andric #include "llvm/Pass.h"
382cab237bSDimitry Andric #include "llvm/Support/Allocator.h"
39f22ef01cSRoman Divacky #include "llvm/Support/Debug.h"
402754fe60SDimitry Andric #include "llvm/Support/RecyclingAllocator.h"
41ff0cc061SDimitry Andric #include "llvm/Support/raw_ostream.h"
422cab237bSDimitry Andric #include <cassert>
432cab237bSDimitry Andric #include <iterator>
442cab237bSDimitry Andric #include <utility>
452cab237bSDimitry Andric #include <vector>
462cab237bSDimitry Andric
47f22ef01cSRoman Divacky using namespace llvm;
48f22ef01cSRoman Divacky
4991bc56edSDimitry Andric #define DEBUG_TYPE "machine-cse"
5091bc56edSDimitry Andric
51f22ef01cSRoman Divacky STATISTIC(NumCoalesces, "Number of copies coalesced");
52f22ef01cSRoman Divacky STATISTIC(NumCSEs, "Number of common subexpression eliminated");
532754fe60SDimitry Andric STATISTIC(NumPhysCSEs,
542754fe60SDimitry Andric "Number of physreg referencing common subexpr eliminated");
55dff0c46cSDimitry Andric STATISTIC(NumCrossBBCSEs,
56dff0c46cSDimitry Andric "Number of cross-MBB physreg referencing CS eliminated");
572754fe60SDimitry Andric STATISTIC(NumCommutes, "Number of copies coalesced after commuting");
58f22ef01cSRoman Divacky
59f22ef01cSRoman Divacky namespace {
602cab237bSDimitry Andric
61f22ef01cSRoman Divacky class MachineCSE : public MachineFunctionPass {
62f22ef01cSRoman Divacky const TargetInstrInfo *TII;
63f22ef01cSRoman Divacky const TargetRegisterInfo *TRI;
64f22ef01cSRoman Divacky AliasAnalysis *AA;
65f22ef01cSRoman Divacky MachineDominatorTree *DT;
66f22ef01cSRoman Divacky MachineRegisterInfo *MRI;
672cab237bSDimitry Andric
68f22ef01cSRoman Divacky public:
69f22ef01cSRoman Divacky static char ID; // Pass identification
702cab237bSDimitry Andric
MachineCSE()712cab237bSDimitry Andric MachineCSE() : MachineFunctionPass(ID) {
722754fe60SDimitry Andric initializeMachineCSEPass(*PassRegistry::getPassRegistry());
732754fe60SDimitry Andric }
74f22ef01cSRoman Divacky
7591bc56edSDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override;
76f22ef01cSRoman Divacky
getAnalysisUsage(AnalysisUsage & AU) const7791bc56edSDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override {
78f22ef01cSRoman Divacky AU.setPreservesCFG();
79f22ef01cSRoman Divacky MachineFunctionPass::getAnalysisUsage(AU);
807d523365SDimitry Andric AU.addRequired<AAResultsWrapperPass>();
81e580952dSDimitry Andric AU.addPreservedID(MachineLoopInfoID);
82f22ef01cSRoman Divacky AU.addRequired<MachineDominatorTree>();
83f22ef01cSRoman Divacky AU.addPreserved<MachineDominatorTree>();
84f22ef01cSRoman Divacky }
85f22ef01cSRoman Divacky
releaseMemory()8691bc56edSDimitry Andric void releaseMemory() override {
8714837164SDimitry Andric ScopeMap.clear();
8814837164SDimitry Andric Exps.clear();
8914837164SDimitry Andric }
9014837164SDimitry Andric
91f22ef01cSRoman Divacky private:
922cab237bSDimitry Andric using AllocatorTy = RecyclingAllocator<BumpPtrAllocator,
932cab237bSDimitry Andric ScopedHashTableVal<MachineInstr *, unsigned>>;
942cab237bSDimitry Andric using ScopedHTType =
952cab237bSDimitry Andric ScopedHashTable<MachineInstr *, unsigned, MachineInstrExpressionTrait,
962cab237bSDimitry Andric AllocatorTy>;
972cab237bSDimitry Andric using ScopeType = ScopedHTType::ScopeTy;
982cab237bSDimitry Andric
992cab237bSDimitry Andric unsigned LookAheadLimit = 0;
100f22ef01cSRoman Divacky DenseMap<MachineBasicBlock *, ScopeType *> ScopeMap;
1012754fe60SDimitry Andric ScopedHTType VNT;
102f22ef01cSRoman Divacky SmallVector<MachineInstr *, 64> Exps;
1032cab237bSDimitry Andric unsigned CurrVN = 0;
104f22ef01cSRoman Divacky
10539d628a0SDimitry Andric bool PerformTrivialCopyPropagation(MachineInstr *MI,
10639d628a0SDimitry Andric MachineBasicBlock *MBB);
107f22ef01cSRoman Divacky bool isPhysDefTriviallyDead(unsigned Reg,
108f22ef01cSRoman Divacky MachineBasicBlock::const_iterator I,
109f22ef01cSRoman Divacky MachineBasicBlock::const_iterator E) const;
1102754fe60SDimitry Andric bool hasLivePhysRegDefUses(const MachineInstr *MI,
111f22ef01cSRoman Divacky const MachineBasicBlock *MBB,
112dff0c46cSDimitry Andric SmallSet<unsigned,8> &PhysRefs,
113f785676fSDimitry Andric SmallVectorImpl<unsigned> &PhysDefs,
1143861d79fSDimitry Andric bool &PhysUseDef) const;
1152754fe60SDimitry Andric bool PhysRegDefsReach(MachineInstr *CSMI, MachineInstr *MI,
116dff0c46cSDimitry Andric SmallSet<unsigned,8> &PhysRefs,
117f785676fSDimitry Andric SmallVectorImpl<unsigned> &PhysDefs,
118dff0c46cSDimitry Andric bool &NonLocal) const;
119f22ef01cSRoman Divacky bool isCSECandidate(MachineInstr *MI);
120f22ef01cSRoman Divacky bool isProfitableToCSE(unsigned CSReg, unsigned Reg,
121f22ef01cSRoman Divacky MachineInstr *CSMI, MachineInstr *MI);
122f22ef01cSRoman Divacky void EnterScope(MachineBasicBlock *MBB);
123f22ef01cSRoman Divacky void ExitScope(MachineBasicBlock *MBB);
124f22ef01cSRoman Divacky bool ProcessBlock(MachineBasicBlock *MBB);
125f22ef01cSRoman Divacky void ExitScopeIfDone(MachineDomTreeNode *Node,
1267ae0e2c9SDimitry Andric DenseMap<MachineDomTreeNode*, unsigned> &OpenChildren);
127f22ef01cSRoman Divacky bool PerformCSE(MachineDomTreeNode *Node);
128f22ef01cSRoman Divacky };
1292cab237bSDimitry Andric
130f22ef01cSRoman Divacky } // end anonymous namespace
131f22ef01cSRoman Divacky
132f22ef01cSRoman Divacky char MachineCSE::ID = 0;
1332cab237bSDimitry Andric
134dff0c46cSDimitry Andric char &llvm::MachineCSEID = MachineCSE::ID;
1352cab237bSDimitry Andric
136302affcbSDimitry Andric INITIALIZE_PASS_BEGIN(MachineCSE, DEBUG_TYPE,
1372754fe60SDimitry Andric "Machine Common Subexpression Elimination", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)1382754fe60SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
1397d523365SDimitry Andric INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
140302affcbSDimitry Andric INITIALIZE_PASS_END(MachineCSE, DEBUG_TYPE,
1412754fe60SDimitry Andric "Machine Common Subexpression Elimination", false, false)
142f22ef01cSRoman Divacky
14339d628a0SDimitry Andric /// The source register of a COPY machine instruction can be propagated to all
14439d628a0SDimitry Andric /// its users, and this propagation could increase the probability of finding
14539d628a0SDimitry Andric /// common subexpressions. If the COPY has only one user, the COPY itself can
14639d628a0SDimitry Andric /// be removed.
14739d628a0SDimitry Andric bool MachineCSE::PerformTrivialCopyPropagation(MachineInstr *MI,
148f22ef01cSRoman Divacky MachineBasicBlock *MBB) {
149f22ef01cSRoman Divacky bool Changed = false;
1504d0b32cdSDimitry Andric for (MachineOperand &MO : MI->operands()) {
151f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isUse())
152f22ef01cSRoman Divacky continue;
153f22ef01cSRoman Divacky unsigned Reg = MO.getReg();
1542754fe60SDimitry Andric if (!TargetRegisterInfo::isVirtualRegister(Reg))
155f22ef01cSRoman Divacky continue;
15639d628a0SDimitry Andric bool OnlyOneUse = MRI->hasOneNonDBGUse(Reg);
157f22ef01cSRoman Divacky MachineInstr *DefMI = MRI->getVRegDef(Reg);
158ffd1746dSEd Schouten if (!DefMI->isCopy())
159ffd1746dSEd Schouten continue;
160e580952dSDimitry Andric unsigned SrcReg = DefMI->getOperand(1).getReg();
161ffd1746dSEd Schouten if (!TargetRegisterInfo::isVirtualRegister(SrcReg))
162ffd1746dSEd Schouten continue;
16391bc56edSDimitry Andric if (DefMI->getOperand(0).getSubReg())
164ffd1746dSEd Schouten continue;
16591bc56edSDimitry Andric // FIXME: We should trivially coalesce subregister copies to expose CSE
16691bc56edSDimitry Andric // opportunities on instructions with truncated operands (see
16791bc56edSDimitry Andric // cse-add-with-overflow.ll). This can be done here as follows:
16891bc56edSDimitry Andric // if (SrcSubReg)
16991bc56edSDimitry Andric // RC = TRI->getMatchingSuperRegClass(MRI->getRegClass(SrcReg), RC,
17091bc56edSDimitry Andric // SrcSubReg);
17191bc56edSDimitry Andric // MO.substVirtReg(SrcReg, SrcSubReg, *TRI);
17291bc56edSDimitry Andric //
17391bc56edSDimitry Andric // The 2-addr pass has been updated to handle coalesced subregs. However,
17491bc56edSDimitry Andric // some machine-specific code still can't handle it.
17591bc56edSDimitry Andric // To handle it properly we also need a way find a constrained subregister
17691bc56edSDimitry Andric // class given a super-reg class and subreg index.
17791bc56edSDimitry Andric if (DefMI->getOperand(1).getSubReg())
17891bc56edSDimitry Andric continue;
1794ba319b5SDimitry Andric if (!MRI->constrainRegAttrs(SrcReg, Reg))
180ffd1746dSEd Schouten continue;
1814ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Coalescing: " << *DefMI);
1824ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "*** to: " << *MI);
183*b5893f02SDimitry Andric
184*b5893f02SDimitry Andric // Update matching debug values.
185*b5893f02SDimitry Andric DefMI->changeDebugValuesDefReg(SrcReg);
186*b5893f02SDimitry Andric
18739d628a0SDimitry Andric // Propagate SrcReg of copies to MI.
188ffd1746dSEd Schouten MO.setReg(SrcReg);
189ffd1746dSEd Schouten MRI->clearKillFlags(SrcReg);
19039d628a0SDimitry Andric // Coalesce single use copies.
19139d628a0SDimitry Andric if (OnlyOneUse) {
192ffd1746dSEd Schouten DefMI->eraseFromParent();
193ffd1746dSEd Schouten ++NumCoalesces;
19439d628a0SDimitry Andric }
195ffd1746dSEd Schouten Changed = true;
196f22ef01cSRoman Divacky }
197f22ef01cSRoman Divacky
198f22ef01cSRoman Divacky return Changed;
199f22ef01cSRoman Divacky }
200f22ef01cSRoman Divacky
201f22ef01cSRoman Divacky bool
isPhysDefTriviallyDead(unsigned Reg,MachineBasicBlock::const_iterator I,MachineBasicBlock::const_iterator E) const202f22ef01cSRoman Divacky MachineCSE::isPhysDefTriviallyDead(unsigned Reg,
203f22ef01cSRoman Divacky MachineBasicBlock::const_iterator I,
204f22ef01cSRoman Divacky MachineBasicBlock::const_iterator E) const {
205f22ef01cSRoman Divacky unsigned LookAheadLeft = LookAheadLimit;
206f22ef01cSRoman Divacky while (LookAheadLeft) {
207f22ef01cSRoman Divacky // Skip over dbg_value's.
208d88c1a5aSDimitry Andric I = skipDebugInstructionsForward(I, E);
209f22ef01cSRoman Divacky
210f22ef01cSRoman Divacky if (I == E)
211302affcbSDimitry Andric // Reached end of block, we don't know if register is dead or not.
212302affcbSDimitry Andric return false;
213f22ef01cSRoman Divacky
214f22ef01cSRoman Divacky bool SeenDef = false;
2154d0b32cdSDimitry Andric for (const MachineOperand &MO : I->operands()) {
216dff0c46cSDimitry Andric if (MO.isRegMask() && MO.clobbersPhysReg(Reg))
217dff0c46cSDimitry Andric SeenDef = true;
218f22ef01cSRoman Divacky if (!MO.isReg() || !MO.getReg())
219f22ef01cSRoman Divacky continue;
220f22ef01cSRoman Divacky if (!TRI->regsOverlap(MO.getReg(), Reg))
221f22ef01cSRoman Divacky continue;
222f22ef01cSRoman Divacky if (MO.isUse())
223f22ef01cSRoman Divacky // Found a use!
224f22ef01cSRoman Divacky return false;
225f22ef01cSRoman Divacky SeenDef = true;
226f22ef01cSRoman Divacky }
227f22ef01cSRoman Divacky if (SeenDef)
228f22ef01cSRoman Divacky // See a def of Reg (or an alias) before encountering any use, it's
229f22ef01cSRoman Divacky // trivially dead.
230f22ef01cSRoman Divacky return true;
231f22ef01cSRoman Divacky
232f22ef01cSRoman Divacky --LookAheadLeft;
233f22ef01cSRoman Divacky ++I;
234f22ef01cSRoman Divacky }
235f22ef01cSRoman Divacky return false;
236f22ef01cSRoman Divacky }
237f22ef01cSRoman Divacky
isCallerPreservedOrConstPhysReg(unsigned Reg,const MachineFunction & MF,const TargetRegisterInfo & TRI)238*b5893f02SDimitry Andric static bool isCallerPreservedOrConstPhysReg(unsigned Reg,
239*b5893f02SDimitry Andric const MachineFunction &MF,
240*b5893f02SDimitry Andric const TargetRegisterInfo &TRI) {
241*b5893f02SDimitry Andric // MachineRegisterInfo::isConstantPhysReg directly called by
242*b5893f02SDimitry Andric // MachineRegisterInfo::isCallerPreservedOrConstPhysReg expects the
243*b5893f02SDimitry Andric // reserved registers to be frozen. That doesn't cause a problem post-ISel as
244*b5893f02SDimitry Andric // most (if not all) targets freeze reserved registers right after ISel.
245*b5893f02SDimitry Andric //
246*b5893f02SDimitry Andric // It does cause issues mid-GlobalISel, however, hence the additional
247*b5893f02SDimitry Andric // reservedRegsFrozen check.
248*b5893f02SDimitry Andric const MachineRegisterInfo &MRI = MF.getRegInfo();
249*b5893f02SDimitry Andric return TRI.isCallerPreservedPhysReg(Reg, MF) ||
250*b5893f02SDimitry Andric (MRI.reservedRegsFrozen() && MRI.isConstantPhysReg(Reg));
251*b5893f02SDimitry Andric }
252*b5893f02SDimitry Andric
2532754fe60SDimitry Andric /// hasLivePhysRegDefUses - Return true if the specified instruction read/write
254f22ef01cSRoman Divacky /// physical registers (except for dead defs of physical registers). It also
255ffd1746dSEd Schouten /// returns the physical register def by reference if it's the only one and the
256ffd1746dSEd Schouten /// instruction does not uses a physical register.
hasLivePhysRegDefUses(const MachineInstr * MI,const MachineBasicBlock * MBB,SmallSet<unsigned,8> & PhysRefs,SmallVectorImpl<unsigned> & PhysDefs,bool & PhysUseDef) const2572754fe60SDimitry Andric bool MachineCSE::hasLivePhysRegDefUses(const MachineInstr *MI,
258f22ef01cSRoman Divacky const MachineBasicBlock *MBB,
259dff0c46cSDimitry Andric SmallSet<unsigned,8> &PhysRefs,
260f785676fSDimitry Andric SmallVectorImpl<unsigned> &PhysDefs,
2613861d79fSDimitry Andric bool &PhysUseDef) const{
2623861d79fSDimitry Andric // First, add all uses to PhysRefs.
2634d0b32cdSDimitry Andric for (const MachineOperand &MO : MI->operands()) {
2643861d79fSDimitry Andric if (!MO.isReg() || MO.isDef())
265f22ef01cSRoman Divacky continue;
266f22ef01cSRoman Divacky unsigned Reg = MO.getReg();
267f22ef01cSRoman Divacky if (!Reg)
268f22ef01cSRoman Divacky continue;
269f22ef01cSRoman Divacky if (TargetRegisterInfo::isVirtualRegister(Reg))
270f22ef01cSRoman Divacky continue;
2712cab237bSDimitry Andric // Reading either caller preserved or constant physregs is ok.
272*b5893f02SDimitry Andric if (!isCallerPreservedOrConstPhysReg(Reg, *MI->getMF(), *TRI))
2737ae0e2c9SDimitry Andric for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
2747ae0e2c9SDimitry Andric PhysRefs.insert(*AI);
2753861d79fSDimitry Andric }
2763861d79fSDimitry Andric
2773861d79fSDimitry Andric // Next, collect all defs into PhysDefs. If any is already in PhysRefs
2783861d79fSDimitry Andric // (which currently contains only uses), set the PhysUseDef flag.
2793861d79fSDimitry Andric PhysUseDef = false;
28091bc56edSDimitry Andric MachineBasicBlock::const_iterator I = MI; I = std::next(I);
2814d0b32cdSDimitry Andric for (const MachineOperand &MO : MI->operands()) {
2823861d79fSDimitry Andric if (!MO.isReg() || !MO.isDef())
2833861d79fSDimitry Andric continue;
2843861d79fSDimitry Andric unsigned Reg = MO.getReg();
2853861d79fSDimitry Andric if (!Reg)
2863861d79fSDimitry Andric continue;
2873861d79fSDimitry Andric if (TargetRegisterInfo::isVirtualRegister(Reg))
2883861d79fSDimitry Andric continue;
2893861d79fSDimitry Andric // Check against PhysRefs even if the def is "dead".
2903861d79fSDimitry Andric if (PhysRefs.count(Reg))
2913861d79fSDimitry Andric PhysUseDef = true;
2923861d79fSDimitry Andric // If the def is dead, it's ok. But the def may not marked "dead". That's
2933861d79fSDimitry Andric // common since this pass is run before livevariables. We can scan
2943861d79fSDimitry Andric // forward a few instructions and check if it is obviously dead.
2953861d79fSDimitry Andric if (!MO.isDead() && !isPhysDefTriviallyDead(Reg, I, MBB->end()))
296dff0c46cSDimitry Andric PhysDefs.push_back(Reg);
297f22ef01cSRoman Divacky }
298f22ef01cSRoman Divacky
2993861d79fSDimitry Andric // Finally, add all defs to PhysRefs as well.
3003861d79fSDimitry Andric for (unsigned i = 0, e = PhysDefs.size(); i != e; ++i)
3013861d79fSDimitry Andric for (MCRegAliasIterator AI(PhysDefs[i], TRI, true); AI.isValid(); ++AI)
3023861d79fSDimitry Andric PhysRefs.insert(*AI);
3033861d79fSDimitry Andric
3042754fe60SDimitry Andric return !PhysRefs.empty();
305f22ef01cSRoman Divacky }
306f22ef01cSRoman Divacky
PhysRegDefsReach(MachineInstr * CSMI,MachineInstr * MI,SmallSet<unsigned,8> & PhysRefs,SmallVectorImpl<unsigned> & PhysDefs,bool & NonLocal) const3072754fe60SDimitry Andric bool MachineCSE::PhysRegDefsReach(MachineInstr *CSMI, MachineInstr *MI,
308dff0c46cSDimitry Andric SmallSet<unsigned,8> &PhysRefs,
309f785676fSDimitry Andric SmallVectorImpl<unsigned> &PhysDefs,
310dff0c46cSDimitry Andric bool &NonLocal) const {
311f22ef01cSRoman Divacky // For now conservatively returns false if the common subexpression is
312dff0c46cSDimitry Andric // not in the same basic block as the given instruction. The only exception
313dff0c46cSDimitry Andric // is if the common subexpression is in the sole predecessor block.
314dff0c46cSDimitry Andric const MachineBasicBlock *MBB = MI->getParent();
315dff0c46cSDimitry Andric const MachineBasicBlock *CSMBB = CSMI->getParent();
316dff0c46cSDimitry Andric
317dff0c46cSDimitry Andric bool CrossMBB = false;
318dff0c46cSDimitry Andric if (CSMBB != MBB) {
319dff0c46cSDimitry Andric if (MBB->pred_size() != 1 || *MBB->pred_begin() != CSMBB)
320f22ef01cSRoman Divacky return false;
321dff0c46cSDimitry Andric
322dff0c46cSDimitry Andric for (unsigned i = 0, e = PhysDefs.size(); i != e; ++i) {
3233861d79fSDimitry Andric if (MRI->isAllocatable(PhysDefs[i]) || MRI->isReserved(PhysDefs[i]))
324dff0c46cSDimitry Andric // Avoid extending live range of physical registers if they are
325dff0c46cSDimitry Andric //allocatable or reserved.
326dff0c46cSDimitry Andric return false;
327dff0c46cSDimitry Andric }
328dff0c46cSDimitry Andric CrossMBB = true;
329dff0c46cSDimitry Andric }
33091bc56edSDimitry Andric MachineBasicBlock::const_iterator I = CSMI; I = std::next(I);
331f22ef01cSRoman Divacky MachineBasicBlock::const_iterator E = MI;
332dff0c46cSDimitry Andric MachineBasicBlock::const_iterator EE = CSMBB->end();
333f22ef01cSRoman Divacky unsigned LookAheadLeft = LookAheadLimit;
334f22ef01cSRoman Divacky while (LookAheadLeft) {
335f22ef01cSRoman Divacky // Skip over dbg_value's.
3364ba319b5SDimitry Andric while (I != E && I != EE && I->isDebugInstr())
337f22ef01cSRoman Divacky ++I;
338f22ef01cSRoman Divacky
339dff0c46cSDimitry Andric if (I == EE) {
340dff0c46cSDimitry Andric assert(CrossMBB && "Reaching end-of-MBB without finding MI?");
341dff0c46cSDimitry Andric (void)CrossMBB;
342dff0c46cSDimitry Andric CrossMBB = false;
343dff0c46cSDimitry Andric NonLocal = true;
344dff0c46cSDimitry Andric I = MBB->begin();
345dff0c46cSDimitry Andric EE = MBB->end();
346dff0c46cSDimitry Andric continue;
347dff0c46cSDimitry Andric }
348dff0c46cSDimitry Andric
349f22ef01cSRoman Divacky if (I == E)
350f22ef01cSRoman Divacky return true;
3512754fe60SDimitry Andric
3524d0b32cdSDimitry Andric for (const MachineOperand &MO : I->operands()) {
353dff0c46cSDimitry Andric // RegMasks go on instructions like calls that clobber lots of physregs.
354dff0c46cSDimitry Andric // Don't attempt to CSE across such an instruction.
355dff0c46cSDimitry Andric if (MO.isRegMask())
356dff0c46cSDimitry Andric return false;
3572754fe60SDimitry Andric if (!MO.isReg() || !MO.isDef())
3582754fe60SDimitry Andric continue;
3592754fe60SDimitry Andric unsigned MOReg = MO.getReg();
3602754fe60SDimitry Andric if (TargetRegisterInfo::isVirtualRegister(MOReg))
3612754fe60SDimitry Andric continue;
3622754fe60SDimitry Andric if (PhysRefs.count(MOReg))
363f22ef01cSRoman Divacky return false;
3642754fe60SDimitry Andric }
365f22ef01cSRoman Divacky
366f22ef01cSRoman Divacky --LookAheadLeft;
367f22ef01cSRoman Divacky ++I;
368f22ef01cSRoman Divacky }
369f22ef01cSRoman Divacky
370f22ef01cSRoman Divacky return false;
371f22ef01cSRoman Divacky }
372f22ef01cSRoman Divacky
isCSECandidate(MachineInstr * MI)373f22ef01cSRoman Divacky bool MachineCSE::isCSECandidate(MachineInstr *MI) {
37491bc56edSDimitry Andric if (MI->isPosition() || MI->isPHI() || MI->isImplicitDef() || MI->isKill() ||
3754ba319b5SDimitry Andric MI->isInlineAsm() || MI->isDebugInstr())
376f22ef01cSRoman Divacky return false;
377f22ef01cSRoman Divacky
378f22ef01cSRoman Divacky // Ignore copies.
379e580952dSDimitry Andric if (MI->isCopyLike())
380f22ef01cSRoman Divacky return false;
381f22ef01cSRoman Divacky
382f22ef01cSRoman Divacky // Ignore stuff that we obviously can't move.
383dff0c46cSDimitry Andric if (MI->mayStore() || MI->isCall() || MI->isTerminator() ||
3842754fe60SDimitry Andric MI->hasUnmodeledSideEffects())
385f22ef01cSRoman Divacky return false;
386f22ef01cSRoman Divacky
387dff0c46cSDimitry Andric if (MI->mayLoad()) {
388f22ef01cSRoman Divacky // Okay, this instruction does a load. As a refinement, we allow the target
389f22ef01cSRoman Divacky // to decide whether the loaded value is actually a constant. If so, we can
390f22ef01cSRoman Divacky // actually use it as a load.
391d88c1a5aSDimitry Andric if (!MI->isDereferenceableInvariantLoad(AA))
392f22ef01cSRoman Divacky // FIXME: we should be able to hoist loads with no other side effects if
393f22ef01cSRoman Divacky // there are no other instructions which can change memory in this loop.
394f22ef01cSRoman Divacky // This is a trivial form of alias analysis.
395f22ef01cSRoman Divacky return false;
396f22ef01cSRoman Divacky }
3973ca95b02SDimitry Andric
3983ca95b02SDimitry Andric // Ignore stack guard loads, otherwise the register that holds CSEed value may
3993ca95b02SDimitry Andric // be spilled and get loaded back with corrupted data.
4003ca95b02SDimitry Andric if (MI->getOpcode() == TargetOpcode::LOAD_STACK_GUARD)
4013ca95b02SDimitry Andric return false;
4023ca95b02SDimitry Andric
403f22ef01cSRoman Divacky return true;
404f22ef01cSRoman Divacky }
405f22ef01cSRoman Divacky
406f22ef01cSRoman Divacky /// isProfitableToCSE - Return true if it's profitable to eliminate MI with a
407f22ef01cSRoman Divacky /// common expression that defines Reg.
isProfitableToCSE(unsigned CSReg,unsigned Reg,MachineInstr * CSMI,MachineInstr * MI)408f22ef01cSRoman Divacky bool MachineCSE::isProfitableToCSE(unsigned CSReg, unsigned Reg,
409f22ef01cSRoman Divacky MachineInstr *CSMI, MachineInstr *MI) {
410f22ef01cSRoman Divacky // FIXME: Heuristics that works around the lack the live range splitting.
411f22ef01cSRoman Divacky
4127ae0e2c9SDimitry Andric // If CSReg is used at all uses of Reg, CSE should not increase register
4137ae0e2c9SDimitry Andric // pressure of CSReg.
4147ae0e2c9SDimitry Andric bool MayIncreasePressure = true;
4157ae0e2c9SDimitry Andric if (TargetRegisterInfo::isVirtualRegister(CSReg) &&
4167ae0e2c9SDimitry Andric TargetRegisterInfo::isVirtualRegister(Reg)) {
4177ae0e2c9SDimitry Andric MayIncreasePressure = false;
4187ae0e2c9SDimitry Andric SmallPtrSet<MachineInstr*, 8> CSUses;
41991bc56edSDimitry Andric for (MachineInstr &MI : MRI->use_nodbg_instructions(CSReg)) {
42091bc56edSDimitry Andric CSUses.insert(&MI);
4217ae0e2c9SDimitry Andric }
42291bc56edSDimitry Andric for (MachineInstr &MI : MRI->use_nodbg_instructions(Reg)) {
42391bc56edSDimitry Andric if (!CSUses.count(&MI)) {
4247ae0e2c9SDimitry Andric MayIncreasePressure = true;
4257ae0e2c9SDimitry Andric break;
4267ae0e2c9SDimitry Andric }
4277ae0e2c9SDimitry Andric }
4287ae0e2c9SDimitry Andric }
4297ae0e2c9SDimitry Andric if (!MayIncreasePressure) return true;
4307ae0e2c9SDimitry Andric
4312754fe60SDimitry Andric // Heuristics #1: Don't CSE "cheap" computation if the def is not local or in
4322754fe60SDimitry Andric // an immediate predecessor. We don't want to increase register pressure and
4332754fe60SDimitry Andric // end up causing other computation to be spilled.
4343ca95b02SDimitry Andric if (TII->isAsCheapAsAMove(*MI)) {
435f22ef01cSRoman Divacky MachineBasicBlock *CSBB = CSMI->getParent();
436f22ef01cSRoman Divacky MachineBasicBlock *BB = MI->getParent();
4372754fe60SDimitry Andric if (CSBB != BB && !CSBB->isSuccessor(BB))
438f22ef01cSRoman Divacky return false;
439f22ef01cSRoman Divacky }
440f22ef01cSRoman Divacky
441f22ef01cSRoman Divacky // Heuristics #2: If the expression doesn't not use a vr and the only use
442f22ef01cSRoman Divacky // of the redundant computation are copies, do not cse.
443f22ef01cSRoman Divacky bool HasVRegUse = false;
4444d0b32cdSDimitry Andric for (const MachineOperand &MO : MI->operands()) {
4452754fe60SDimitry Andric if (MO.isReg() && MO.isUse() &&
446f22ef01cSRoman Divacky TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
447f22ef01cSRoman Divacky HasVRegUse = true;
448f22ef01cSRoman Divacky break;
449f22ef01cSRoman Divacky }
450f22ef01cSRoman Divacky }
451f22ef01cSRoman Divacky if (!HasVRegUse) {
452f22ef01cSRoman Divacky bool HasNonCopyUse = false;
45391bc56edSDimitry Andric for (MachineInstr &MI : MRI->use_nodbg_instructions(Reg)) {
454f22ef01cSRoman Divacky // Ignore copies.
45591bc56edSDimitry Andric if (!MI.isCopyLike()) {
456f22ef01cSRoman Divacky HasNonCopyUse = true;
457f22ef01cSRoman Divacky break;
458f22ef01cSRoman Divacky }
459f22ef01cSRoman Divacky }
460f22ef01cSRoman Divacky if (!HasNonCopyUse)
461f22ef01cSRoman Divacky return false;
462f22ef01cSRoman Divacky }
463f22ef01cSRoman Divacky
464f22ef01cSRoman Divacky // Heuristics #3: If the common subexpression is used by PHIs, do not reuse
465f22ef01cSRoman Divacky // it unless the defined value is already used in the BB of the new use.
466f22ef01cSRoman Divacky bool HasPHI = false;
4674ba319b5SDimitry Andric for (MachineInstr &UseMI : MRI->use_nodbg_instructions(CSReg)) {
4684ba319b5SDimitry Andric HasPHI |= UseMI.isPHI();
4694ba319b5SDimitry Andric if (UseMI.getParent() == MI->getParent())
4704ba319b5SDimitry Andric return true;
471f22ef01cSRoman Divacky }
472f22ef01cSRoman Divacky
4734ba319b5SDimitry Andric return !HasPHI;
474f22ef01cSRoman Divacky }
475f22ef01cSRoman Divacky
EnterScope(MachineBasicBlock * MBB)476f22ef01cSRoman Divacky void MachineCSE::EnterScope(MachineBasicBlock *MBB) {
4774ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Entering: " << MBB->getName() << '\n');
478f22ef01cSRoman Divacky ScopeType *Scope = new ScopeType(VNT);
479f22ef01cSRoman Divacky ScopeMap[MBB] = Scope;
480f22ef01cSRoman Divacky }
481f22ef01cSRoman Divacky
ExitScope(MachineBasicBlock * MBB)482f22ef01cSRoman Divacky void MachineCSE::ExitScope(MachineBasicBlock *MBB) {
4834ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Exiting: " << MBB->getName() << '\n');
484f22ef01cSRoman Divacky DenseMap<MachineBasicBlock*, ScopeType*>::iterator SI = ScopeMap.find(MBB);
485f22ef01cSRoman Divacky assert(SI != ScopeMap.end());
486f22ef01cSRoman Divacky delete SI->second;
4873861d79fSDimitry Andric ScopeMap.erase(SI);
488f22ef01cSRoman Divacky }
489f22ef01cSRoman Divacky
ProcessBlock(MachineBasicBlock * MBB)490f22ef01cSRoman Divacky bool MachineCSE::ProcessBlock(MachineBasicBlock *MBB) {
491f22ef01cSRoman Divacky bool Changed = false;
492f22ef01cSRoman Divacky
493f22ef01cSRoman Divacky SmallVector<std::pair<unsigned, unsigned>, 8> CSEPairs;
4947ae0e2c9SDimitry Andric SmallVector<unsigned, 2> ImplicitDefsToUpdate;
49539d628a0SDimitry Andric SmallVector<unsigned, 2> ImplicitDefs;
496f22ef01cSRoman Divacky for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E; ) {
497f22ef01cSRoman Divacky MachineInstr *MI = &*I;
498f22ef01cSRoman Divacky ++I;
499f22ef01cSRoman Divacky
500f22ef01cSRoman Divacky if (!isCSECandidate(MI))
501f22ef01cSRoman Divacky continue;
502f22ef01cSRoman Divacky
503f22ef01cSRoman Divacky bool FoundCSE = VNT.count(MI);
504f22ef01cSRoman Divacky if (!FoundCSE) {
50539d628a0SDimitry Andric // Using trivial copy propagation to find more CSE opportunities.
50639d628a0SDimitry Andric if (PerformTrivialCopyPropagation(MI, MBB)) {
5073b0f4066SDimitry Andric Changed = true;
5083b0f4066SDimitry Andric
509f22ef01cSRoman Divacky // After coalescing MI itself may become a copy.
510e580952dSDimitry Andric if (MI->isCopyLike())
511f22ef01cSRoman Divacky continue;
51239d628a0SDimitry Andric
51339d628a0SDimitry Andric // Try again to see if CSE is possible.
514f22ef01cSRoman Divacky FoundCSE = VNT.count(MI);
515f22ef01cSRoman Divacky }
516f22ef01cSRoman Divacky }
517f22ef01cSRoman Divacky
5182754fe60SDimitry Andric // Commute commutable instructions.
5192754fe60SDimitry Andric bool Commuted = false;
520dff0c46cSDimitry Andric if (!FoundCSE && MI->isCommutable()) {
5213ca95b02SDimitry Andric if (MachineInstr *NewMI = TII->commuteInstruction(*MI)) {
5222754fe60SDimitry Andric Commuted = true;
5232754fe60SDimitry Andric FoundCSE = VNT.count(NewMI);
5243b0f4066SDimitry Andric if (NewMI != MI) {
5252754fe60SDimitry Andric // New instruction. It doesn't need to be kept.
5262754fe60SDimitry Andric NewMI->eraseFromParent();
5273b0f4066SDimitry Andric Changed = true;
5283b0f4066SDimitry Andric } else if (!FoundCSE)
5292754fe60SDimitry Andric // MI was changed but it didn't help, commute it back!
5303ca95b02SDimitry Andric (void)TII->commuteInstruction(*MI);
5312754fe60SDimitry Andric }
5322754fe60SDimitry Andric }
5332754fe60SDimitry Andric
5342754fe60SDimitry Andric // If the instruction defines physical registers and the values *may* be
535f22ef01cSRoman Divacky // used, then it's not safe to replace it with a common subexpression.
5362754fe60SDimitry Andric // It's also not safe if the instruction uses physical registers.
537dff0c46cSDimitry Andric bool CrossMBBPhysDef = false;
5382754fe60SDimitry Andric SmallSet<unsigned, 8> PhysRefs;
539dff0c46cSDimitry Andric SmallVector<unsigned, 2> PhysDefs;
5403861d79fSDimitry Andric bool PhysUseDef = false;
5413861d79fSDimitry Andric if (FoundCSE && hasLivePhysRegDefUses(MI, MBB, PhysRefs,
5423861d79fSDimitry Andric PhysDefs, PhysUseDef)) {
543f22ef01cSRoman Divacky FoundCSE = false;
544f22ef01cSRoman Divacky
545dff0c46cSDimitry Andric // ... Unless the CS is local or is in the sole predecessor block
546dff0c46cSDimitry Andric // and it also defines the physical register which is not clobbered
547dff0c46cSDimitry Andric // in between and the physical register uses were not clobbered.
5483861d79fSDimitry Andric // This can never be the case if the instruction both uses and
5493861d79fSDimitry Andric // defines the same physical register, which was detected above.
5503861d79fSDimitry Andric if (!PhysUseDef) {
551f22ef01cSRoman Divacky unsigned CSVN = VNT.lookup(MI);
552f22ef01cSRoman Divacky MachineInstr *CSMI = Exps[CSVN];
553dff0c46cSDimitry Andric if (PhysRegDefsReach(CSMI, MI, PhysRefs, PhysDefs, CrossMBBPhysDef))
554f22ef01cSRoman Divacky FoundCSE = true;
555f22ef01cSRoman Divacky }
5563861d79fSDimitry Andric }
557f22ef01cSRoman Divacky
558f22ef01cSRoman Divacky if (!FoundCSE) {
559f22ef01cSRoman Divacky VNT.insert(MI, CurrVN++);
560f22ef01cSRoman Divacky Exps.push_back(MI);
561f22ef01cSRoman Divacky continue;
562f22ef01cSRoman Divacky }
563f22ef01cSRoman Divacky
564f22ef01cSRoman Divacky // Found a common subexpression, eliminate it.
565f22ef01cSRoman Divacky unsigned CSVN = VNT.lookup(MI);
566f22ef01cSRoman Divacky MachineInstr *CSMI = Exps[CSVN];
5674ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Examining: " << *MI);
5684ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "*** Found a common subexpression: " << *CSMI);
569f22ef01cSRoman Divacky
570f22ef01cSRoman Divacky // Check if it's profitable to perform this CSE.
571f22ef01cSRoman Divacky bool DoCSE = true;
5724ba319b5SDimitry Andric unsigned NumDefs = MI->getNumDefs();
5737ae0e2c9SDimitry Andric
574f22ef01cSRoman Divacky for (unsigned i = 0, e = MI->getNumOperands(); NumDefs && i != e; ++i) {
575f22ef01cSRoman Divacky MachineOperand &MO = MI->getOperand(i);
576f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isDef())
577f22ef01cSRoman Divacky continue;
578f22ef01cSRoman Divacky unsigned OldReg = MO.getReg();
579f22ef01cSRoman Divacky unsigned NewReg = CSMI->getOperand(i).getReg();
5807ae0e2c9SDimitry Andric
5817ae0e2c9SDimitry Andric // Go through implicit defs of CSMI and MI, if a def is not dead at MI,
5827ae0e2c9SDimitry Andric // we should make sure it is not dead at CSMI.
5837ae0e2c9SDimitry Andric if (MO.isImplicit() && !MO.isDead() && CSMI->getOperand(i).isDead())
5847ae0e2c9SDimitry Andric ImplicitDefsToUpdate.push_back(i);
58539d628a0SDimitry Andric
58639d628a0SDimitry Andric // Keep track of implicit defs of CSMI and MI, to clear possibly
58739d628a0SDimitry Andric // made-redundant kill flags.
58839d628a0SDimitry Andric if (MO.isImplicit() && !MO.isDead() && OldReg == NewReg)
58939d628a0SDimitry Andric ImplicitDefs.push_back(OldReg);
59039d628a0SDimitry Andric
5917ae0e2c9SDimitry Andric if (OldReg == NewReg) {
5927ae0e2c9SDimitry Andric --NumDefs;
593f22ef01cSRoman Divacky continue;
5947ae0e2c9SDimitry Andric }
5956122f3e6SDimitry Andric
596f22ef01cSRoman Divacky assert(TargetRegisterInfo::isVirtualRegister(OldReg) &&
597f22ef01cSRoman Divacky TargetRegisterInfo::isVirtualRegister(NewReg) &&
598f22ef01cSRoman Divacky "Do not CSE physical register defs!");
5996122f3e6SDimitry Andric
600f22ef01cSRoman Divacky if (!isProfitableToCSE(NewReg, OldReg, CSMI, MI)) {
6014ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "*** Not profitable, avoid CSE!\n");
602f22ef01cSRoman Divacky DoCSE = false;
603f22ef01cSRoman Divacky break;
604f22ef01cSRoman Divacky }
6056122f3e6SDimitry Andric
6064ba319b5SDimitry Andric // Don't perform CSE if the result of the new instruction cannot exist
6074ba319b5SDimitry Andric // within the constraints (register class, bank, or low-level type) of
6084ba319b5SDimitry Andric // the old instruction.
6094ba319b5SDimitry Andric if (!MRI->constrainRegAttrs(NewReg, OldReg)) {
6104ba319b5SDimitry Andric LLVM_DEBUG(
6114ba319b5SDimitry Andric dbgs() << "*** Not the same register constraints, avoid CSE!\n");
6126122f3e6SDimitry Andric DoCSE = false;
6136122f3e6SDimitry Andric break;
6146122f3e6SDimitry Andric }
6156122f3e6SDimitry Andric
616f22ef01cSRoman Divacky CSEPairs.push_back(std::make_pair(OldReg, NewReg));
617f22ef01cSRoman Divacky --NumDefs;
618f22ef01cSRoman Divacky }
619f22ef01cSRoman Divacky
620f22ef01cSRoman Divacky // Actually perform the elimination.
621f22ef01cSRoman Divacky if (DoCSE) {
6224d0b32cdSDimitry Andric for (std::pair<unsigned, unsigned> &CSEPair : CSEPairs) {
6234d0b32cdSDimitry Andric unsigned OldReg = CSEPair.first;
6244d0b32cdSDimitry Andric unsigned NewReg = CSEPair.second;
625ff0cc061SDimitry Andric // OldReg may have been unused but is used now, clear the Dead flag
626ff0cc061SDimitry Andric MachineInstr *Def = MRI->getUniqueVRegDef(NewReg);
627ff0cc061SDimitry Andric assert(Def != nullptr && "CSEd register has no unique definition?");
628ff0cc061SDimitry Andric Def->clearRegisterDeads(NewReg);
629ff0cc061SDimitry Andric // Replace with NewReg and clear kill flags which may be wrong now.
630ff0cc061SDimitry Andric MRI->replaceRegWith(OldReg, NewReg);
631ff0cc061SDimitry Andric MRI->clearKillFlags(NewReg);
632f22ef01cSRoman Divacky }
633dff0c46cSDimitry Andric
6347ae0e2c9SDimitry Andric // Go through implicit defs of CSMI and MI, if a def is not dead at MI,
6357ae0e2c9SDimitry Andric // we should make sure it is not dead at CSMI.
6364d0b32cdSDimitry Andric for (unsigned ImplicitDefToUpdate : ImplicitDefsToUpdate)
6374d0b32cdSDimitry Andric CSMI->getOperand(ImplicitDefToUpdate).setIsDead(false);
6387ae0e2c9SDimitry Andric
63939d628a0SDimitry Andric // Go through implicit defs of CSMI and MI, and clear the kill flags on
64039d628a0SDimitry Andric // their uses in all the instructions between CSMI and MI.
64139d628a0SDimitry Andric // We might have made some of the kill flags redundant, consider:
6422cab237bSDimitry Andric // subs ... implicit-def %nzcv <- CSMI
6432cab237bSDimitry Andric // csinc ... implicit killed %nzcv <- this kill flag isn't valid anymore
6442cab237bSDimitry Andric // subs ... implicit-def %nzcv <- MI, to be eliminated
6452cab237bSDimitry Andric // csinc ... implicit killed %nzcv
64639d628a0SDimitry Andric // Since we eliminated MI, and reused a register imp-def'd by CSMI
6472cab237bSDimitry Andric // (here %nzcv), that register, if it was killed before MI, should have
64839d628a0SDimitry Andric // that kill flag removed, because it's lifetime was extended.
64939d628a0SDimitry Andric if (CSMI->getParent() == MI->getParent()) {
65039d628a0SDimitry Andric for (MachineBasicBlock::iterator II = CSMI, IE = MI; II != IE; ++II)
65139d628a0SDimitry Andric for (auto ImplicitDef : ImplicitDefs)
65239d628a0SDimitry Andric if (MachineOperand *MO = II->findRegisterUseOperand(
65339d628a0SDimitry Andric ImplicitDef, /*isKill=*/true, TRI))
65439d628a0SDimitry Andric MO->setIsKill(false);
65539d628a0SDimitry Andric } else {
65639d628a0SDimitry Andric // If the instructions aren't in the same BB, bail out and clear the
65739d628a0SDimitry Andric // kill flag on all uses of the imp-def'd register.
65839d628a0SDimitry Andric for (auto ImplicitDef : ImplicitDefs)
65939d628a0SDimitry Andric MRI->clearKillFlags(ImplicitDef);
66039d628a0SDimitry Andric }
66139d628a0SDimitry Andric
662dff0c46cSDimitry Andric if (CrossMBBPhysDef) {
663dff0c46cSDimitry Andric // Add physical register defs now coming in from a predecessor to MBB
664dff0c46cSDimitry Andric // livein list.
665dff0c46cSDimitry Andric while (!PhysDefs.empty()) {
666dff0c46cSDimitry Andric unsigned LiveIn = PhysDefs.pop_back_val();
667dff0c46cSDimitry Andric if (!MBB->isLiveIn(LiveIn))
668dff0c46cSDimitry Andric MBB->addLiveIn(LiveIn);
669dff0c46cSDimitry Andric }
670dff0c46cSDimitry Andric ++NumCrossBBCSEs;
671dff0c46cSDimitry Andric }
672dff0c46cSDimitry Andric
673f22ef01cSRoman Divacky MI->eraseFromParent();
674f22ef01cSRoman Divacky ++NumCSEs;
6752754fe60SDimitry Andric if (!PhysRefs.empty())
676ffd1746dSEd Schouten ++NumPhysCSEs;
6772754fe60SDimitry Andric if (Commuted)
6782754fe60SDimitry Andric ++NumCommutes;
6793b0f4066SDimitry Andric Changed = true;
680f22ef01cSRoman Divacky } else {
681f22ef01cSRoman Divacky VNT.insert(MI, CurrVN++);
682f22ef01cSRoman Divacky Exps.push_back(MI);
683f22ef01cSRoman Divacky }
684f22ef01cSRoman Divacky CSEPairs.clear();
6857ae0e2c9SDimitry Andric ImplicitDefsToUpdate.clear();
68639d628a0SDimitry Andric ImplicitDefs.clear();
687f22ef01cSRoman Divacky }
688f22ef01cSRoman Divacky
689f22ef01cSRoman Divacky return Changed;
690f22ef01cSRoman Divacky }
691f22ef01cSRoman Divacky
692f22ef01cSRoman Divacky /// ExitScopeIfDone - Destroy scope for the MBB that corresponds to the given
693f22ef01cSRoman Divacky /// dominator tree node if its a leaf or all of its children are done. Walk
694f22ef01cSRoman Divacky /// up the dominator tree to destroy ancestors which are now done.
695f22ef01cSRoman Divacky void
ExitScopeIfDone(MachineDomTreeNode * Node,DenseMap<MachineDomTreeNode *,unsigned> & OpenChildren)696f22ef01cSRoman Divacky MachineCSE::ExitScopeIfDone(MachineDomTreeNode *Node,
6977ae0e2c9SDimitry Andric DenseMap<MachineDomTreeNode*, unsigned> &OpenChildren) {
698f22ef01cSRoman Divacky if (OpenChildren[Node])
699f22ef01cSRoman Divacky return;
700f22ef01cSRoman Divacky
701f22ef01cSRoman Divacky // Pop scope.
702f22ef01cSRoman Divacky ExitScope(Node->getBlock());
703f22ef01cSRoman Divacky
704f22ef01cSRoman Divacky // Now traverse upwards to pop ancestors whose offsprings are all done.
7057ae0e2c9SDimitry Andric while (MachineDomTreeNode *Parent = Node->getIDom()) {
706f22ef01cSRoman Divacky unsigned Left = --OpenChildren[Parent];
707f22ef01cSRoman Divacky if (Left != 0)
708f22ef01cSRoman Divacky break;
709f22ef01cSRoman Divacky ExitScope(Parent->getBlock());
710f22ef01cSRoman Divacky Node = Parent;
711f22ef01cSRoman Divacky }
712f22ef01cSRoman Divacky }
713f22ef01cSRoman Divacky
PerformCSE(MachineDomTreeNode * Node)714f22ef01cSRoman Divacky bool MachineCSE::PerformCSE(MachineDomTreeNode *Node) {
715f22ef01cSRoman Divacky SmallVector<MachineDomTreeNode*, 32> Scopes;
716f22ef01cSRoman Divacky SmallVector<MachineDomTreeNode*, 8> WorkList;
717f22ef01cSRoman Divacky DenseMap<MachineDomTreeNode*, unsigned> OpenChildren;
718f22ef01cSRoman Divacky
71914837164SDimitry Andric CurrVN = 0;
72014837164SDimitry Andric
721f22ef01cSRoman Divacky // Perform a DFS walk to determine the order of visit.
722f22ef01cSRoman Divacky WorkList.push_back(Node);
723f22ef01cSRoman Divacky do {
724f22ef01cSRoman Divacky Node = WorkList.pop_back_val();
725f22ef01cSRoman Divacky Scopes.push_back(Node);
726f22ef01cSRoman Divacky const std::vector<MachineDomTreeNode*> &Children = Node->getChildren();
7274d0b32cdSDimitry Andric OpenChildren[Node] = Children.size();
7284d0b32cdSDimitry Andric for (MachineDomTreeNode *Child : Children)
729f22ef01cSRoman Divacky WorkList.push_back(Child);
730f22ef01cSRoman Divacky } while (!WorkList.empty());
731f22ef01cSRoman Divacky
732f22ef01cSRoman Divacky // Now perform CSE.
733f22ef01cSRoman Divacky bool Changed = false;
7344d0b32cdSDimitry Andric for (MachineDomTreeNode *Node : Scopes) {
735f22ef01cSRoman Divacky MachineBasicBlock *MBB = Node->getBlock();
736f22ef01cSRoman Divacky EnterScope(MBB);
737f22ef01cSRoman Divacky Changed |= ProcessBlock(MBB);
738f22ef01cSRoman Divacky // If it's a leaf node, it's done. Traverse upwards to pop ancestors.
7397ae0e2c9SDimitry Andric ExitScopeIfDone(Node, OpenChildren);
740f22ef01cSRoman Divacky }
741f22ef01cSRoman Divacky
742f22ef01cSRoman Divacky return Changed;
743f22ef01cSRoman Divacky }
744f22ef01cSRoman Divacky
runOnMachineFunction(MachineFunction & MF)745f22ef01cSRoman Divacky bool MachineCSE::runOnMachineFunction(MachineFunction &MF) {
7462cab237bSDimitry Andric if (skipFunction(MF.getFunction()))
74791bc56edSDimitry Andric return false;
74891bc56edSDimitry Andric
74939d628a0SDimitry Andric TII = MF.getSubtarget().getInstrInfo();
75039d628a0SDimitry Andric TRI = MF.getSubtarget().getRegisterInfo();
751f22ef01cSRoman Divacky MRI = &MF.getRegInfo();
7527d523365SDimitry Andric AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
753f22ef01cSRoman Divacky DT = &getAnalysis<MachineDominatorTree>();
754ff0cc061SDimitry Andric LookAheadLimit = TII->getMachineCSELookAheadLimit();
755f22ef01cSRoman Divacky return PerformCSE(DT->getRootNode());
756f22ef01cSRoman Divacky }
757