From: Adrian Prantl Date: Wed, 6 Aug 2014 18:41:24 +0000 (+0000) Subject: Improve performance of calculateDbgValueHistory. X-Git-Tag: v01.01.07.01~5338 X-Git-Url: https://git.ti.com/gitweb?p=opencl%2Fllvm.git;a=commitdiff_plain;h=6cdc37478647dd9534427c3243502ae407a649b5;hp=6e62bbdafc5f0b173bf873b846da101bbb44a735 Improve performance of calculateDbgValueHistory. In r210492 the logic of calculateDbgValueHistory was changed to end register variable live ranges at the end of MBB conditionally on the fact that the register was or not clobbered by the function body. This requires an initial scan of all the operands of the function to collect all clobbered registers. In a second pass over all instructions, we compare this set with the set of clobbered registers for the current MachineInstruction. This modification incurred a compilation time regression on some benchmarks: the debug info emission phase takes ~10% more time. While a small performance hit is unavoidable due to the initial scan requirement, we can improve the situation by avoiding to create too many temporary sets and just use lambdas to work directly on the result of the initial scan. Fixes Patch by Frederic Riss! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214987 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp b/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp index 143b0135c8..998c396924 100644 --- a/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp +++ b/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp @@ -112,15 +112,23 @@ static void clobberRegisterUses(RegDescribedVarsMap &RegVars, unsigned RegNo, RegVars.erase(I); } -// \brief Collect all registers clobbered by @MI and insert them to @Regs. -static void collectClobberedRegisters(const MachineInstr &MI, +// \brief Collect all registers clobbered by @MI and apply the functor +// @Func to their RegNo. +// @Func should be a functor with a void(unsigned) signature. We're +// not using std::function here for performance reasons. It has a +// small but measurable impact. By using a functor instead of a +// std::set& here, we can avoid the overhead of constructing +// temporaries in calculateDbgValueHistory, which has a significant +// performance impact. +template +static void applyToClobberedRegisters(const MachineInstr &MI, const TargetRegisterInfo *TRI, - std::set &Regs) { + Callable Func) { for (const MachineOperand &MO : MI.operands()) { if (!MO.isReg() || !MO.isDef() || !MO.getReg()) continue; for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid(); ++AI) - Regs.insert(*AI); + Func(*AI); } } @@ -146,7 +154,7 @@ static const MachineInstr *getFirstEpilogueInst(const MachineBasicBlock &MBB) { } // \brief Collect registers that are modified in the function body (their -// contents is changed only in the prologue and epilogue). +// contents is changed outside of the prologue and epilogue). static void collectChangingRegs(const MachineFunction *MF, const TargetRegisterInfo *TRI, std::set &Regs) { @@ -157,7 +165,7 @@ static void collectChangingRegs(const MachineFunction *MF, if (&MI == FirstEpilogueInst) break; if (!MI.getFlag(MachineInstr::FrameSetup)) - collectClobberedRegisters(MI, TRI, Regs); + applyToClobberedRegisters(MI, TRI, [&](unsigned r) { Regs.insert(r); }); } } } @@ -174,12 +182,10 @@ void calculateDbgValueHistory(const MachineFunction *MF, if (!MI.isDebugValue()) { // Not a DBG_VALUE instruction. It may clobber registers which describe // some variables. - std::set MIClobberedRegs; - collectClobberedRegisters(MI, TRI, MIClobberedRegs); - for (unsigned RegNo : MIClobberedRegs) { + applyToClobberedRegisters(MI, TRI, [&](unsigned RegNo) { if (ChangingRegs.count(RegNo)) clobberRegisterUses(RegVars, RegNo, Result, MI); - } + }); continue; }