Index: lib/CodeGen/MachineCSE.cpp =================================================================== --- lib/CodeGen/MachineCSE.cpp +++ lib/CodeGen/MachineCSE.cpp @@ -85,6 +85,7 @@ void releaseMemory() override { ScopeMap.clear(); Exps.clear(); + ProfitableSet.clear(); } private: @@ -100,6 +101,7 @@ ScopedHTType VNT; SmallVector Exps; unsigned CurrVN = 0; + SmallSet ProfitableSet; bool PerformTrivialCopyPropagation(MachineInstr *MI, MachineBasicBlock *MBB); @@ -118,6 +120,7 @@ bool isCSECandidate(MachineInstr *MI); bool isProfitableToCSE(unsigned CSReg, unsigned Reg, MachineInstr *CSMI, MachineInstr *MI); + bool isMIProfitableToCSE(unsigned Reg, MachineInstr *CSMI, MachineInstr *MI); void EnterScope(MachineBasicBlock *MBB); void ExitScope(MachineBasicBlock *MBB); bool ProcessBlock(MachineBasicBlock *MBB); @@ -402,31 +405,8 @@ return true; } -/// isProfitableToCSE - Return true if it's profitable to eliminate MI with a -/// common expression that defines Reg. -bool MachineCSE::isProfitableToCSE(unsigned CSReg, unsigned Reg, - MachineInstr *CSMI, MachineInstr *MI) { - // FIXME: Heuristics that works around the lack the live range splitting. - - // If CSReg is used at all uses of Reg, CSE should not increase register - // pressure of CSReg. - bool MayIncreasePressure = true; - if (TargetRegisterInfo::isVirtualRegister(CSReg) && - TargetRegisterInfo::isVirtualRegister(Reg)) { - MayIncreasePressure = false; - SmallPtrSet CSUses; - for (MachineInstr &MI : MRI->use_nodbg_instructions(CSReg)) { - CSUses.insert(&MI); - } - for (MachineInstr &MI : MRI->use_nodbg_instructions(Reg)) { - if (!CSUses.count(&MI)) { - MayIncreasePressure = true; - break; - } - } - } - if (!MayIncreasePressure) return true; - +/// isMIProfitableToCSE - Check if MI is profitable for CSE. +bool MachineCSE::isMIProfitableToCSE(unsigned Reg, MachineInstr *CSMI, MachineInstr *MI) { // Heuristics #1: Don't CSE "cheap" computation if the def is not local or in // an immediate predecessor. We don't want to increase register pressure and // end up causing other computation to be spilled. @@ -459,6 +439,33 @@ if (!HasNonCopyUse) return false; } + return true; +} + +/// isProfitableToCSE - Return true if it's profitable to eliminate MI with a +/// common expression that defines Reg. +bool MachineCSE::isProfitableToCSE(unsigned CSReg, unsigned Reg, + MachineInstr *CSMI, MachineInstr *MI) { + // FIXME: Heuristics that works around the lack the live range splitting. + + // If CSReg is used at all uses of Reg, CSE should not increase register + // pressure of CSReg. + bool MayIncreasePressure = true; + if (TargetRegisterInfo::isVirtualRegister(CSReg) && + TargetRegisterInfo::isVirtualRegister(Reg)) { + MayIncreasePressure = false; + SmallPtrSet CSUses; + for (MachineInstr &MI : MRI->use_nodbg_instructions(CSReg)) { + CSUses.insert(&MI); + } + for (MachineInstr &MI : MRI->use_nodbg_instructions(Reg)) { + if (!CSUses.count(&MI)) { + MayIncreasePressure = true; + break; + } + } + } + if (!MayIncreasePressure) return true; // Heuristics #3: If the common subexpression is used by PHIs, do not reuse // it unless the defined value is already used in the BB of the new use. @@ -596,12 +603,21 @@ TargetRegisterInfo::isVirtualRegister(NewReg) && "Do not CSE physical register defs!"); - if (!isProfitableToCSE(NewReg, OldReg, CSMI, MI)) { - LLVM_DEBUG(dbgs() << "*** Not profitable, avoid CSE!\n"); + if (!isMIProfitableToCSE(OldReg, CSMI, MI)) { + LLVM_DEBUG(dbgs() << "*** MI Not profitable, avoid CSE!\n"); DoCSE = false; break; } + if (!ProfitableSet.count(CSMI)) { + if (!isProfitableToCSE(NewReg, OldReg, CSMI, MI)) { + LLVM_DEBUG(dbgs() << "*** Not profitable, avoid CSE!\n"); + DoCSE = false; + break; + } + ProfitableSet.insert(CSMI); + } + // Don't perform CSE if the result of the new instruction cannot exist // within the constraints (register class, bank, or low-level type) of // the old instruction.