diff --git a/bolt/include/bolt/Passes/ZeroIdiom.h b/bolt/include/bolt/Passes/ZeroIdiom.h --- a/bolt/include/bolt/Passes/ZeroIdiom.h +++ b/bolt/include/bolt/Passes/ZeroIdiom.h @@ -22,7 +22,13 @@ /// Pass for converting eligible instructions into zero idiom. class ZeroIdiomPass : public BinaryFunctionPass { - void runOnFunction(BinaryFunction &Function, DataflowInfoManager &Info); + void runOnFunction(BinaryFunction &Function, DataflowInfoManager &Info, + BinaryContext::IndependentCodeEmitter &Emitter); + + static std::atomic ReplacedInsts; + static std::atomic ModifiedFunctions; + static std::atomic ReplacedDynamicCount; + static std::atomic SavedBytes; public: explicit ZeroIdiomPass(const cl::opt &PrintPass) diff --git a/bolt/lib/Passes/ZeroIdiom.cpp b/bolt/lib/Passes/ZeroIdiom.cpp --- a/bolt/lib/Passes/ZeroIdiom.cpp +++ b/bolt/lib/Passes/ZeroIdiom.cpp @@ -20,18 +20,35 @@ namespace llvm { namespace bolt { -void ZeroIdiomPass::runOnFunction(BinaryFunction &BF, - DataflowInfoManager &Info) { +std::atomic ZeroIdiomPass::ReplacedInsts{0}; +std::atomic ZeroIdiomPass::ModifiedFunctions{0}; +std::atomic ZeroIdiomPass::ReplacedDynamicCount{0}; +std::atomic ZeroIdiomPass::SavedBytes{0}; + +void ZeroIdiomPass::runOnFunction( + BinaryFunction &BF, DataflowInfoManager &Info, + BinaryContext::IndependentCodeEmitter &Emitter) { BinaryContext &BC = BF.getBinaryContext(); LivenessAnalysis &LA = Info.getLivenessAnalysis(); + MCCodeEmitter *MCE = Emitter.MCE.get(); + bool Modified = false; for (BinaryBasicBlock &BB : BF) { for (MCInst &Inst : BB) { if (LA.isAlive(ProgramPoint(&Inst), BC.MIB->getFlagsReg())) continue; - BC.MIB->replaceZeroIdiom(Inst); + const uint64_t SizeBefore = BC.computeInstructionSize(Inst, MCE); + if (BC.MIB->replaceZeroIdiom(Inst)) { + Modified = true; + ++ReplacedInsts; + ReplacedDynamicCount += BB.getExecutionCount(); + const uint64_t SizeAfter = BC.computeInstructionSize(Inst, MCE); + SavedBytes += (SizeBefore - SizeAfter); + } } } + if (Modified) + ++ModifiedFunctions; } void ZeroIdiomPass::runOnFunctions(BinaryContext &BC) { @@ -46,12 +63,22 @@ ParallelUtilities::WorkFuncWithAllocTy WorkFun = [&](BinaryFunction &BF, MCPlusBuilder::AllocatorIdTy AllocId) { DataflowInfoManager Info(BF, RA.get(), nullptr, AllocId); - runOnFunction(BF, Info); + BinaryContext::IndependentCodeEmitter MCE = + BC.createIndependentMCCodeEmitter(); + runOnFunction(BF, Info, MCE); }; ParallelUtilities::runOnEachFunctionWithUniqueAllocId( BC, ParallelUtilities::SchedulingPolicy::SP_INST_LINEAR, WorkFun, nullptr, "ZeroIdiom"); + + if (!ReplacedInsts) + return; + + outs() << "BOLT-INFO: zero-idiom replaced " << ReplacedInsts + << " instructions (exec count " << ReplacedDynamicCount << ") in " + << ModifiedFunctions << " functions saving " << SavedBytes + << " bytes\n"; } } // end namespace bolt