diff --git a/bolt/include/bolt/Passes/BinaryPasses.h b/bolt/include/bolt/Passes/BinaryPasses.h --- a/bolt/include/bolt/Passes/BinaryPasses.h +++ b/bolt/include/bolt/Passes/BinaryPasses.h @@ -213,6 +213,16 @@ void runOnFunctions(BinaryContext &BC) override; }; +/// Clean the state of the MC representation before sending it to emission +class CleanMCState : public BinaryFunctionPass { +public: + explicit CleanMCState(const cl::opt &PrintPass) + : BinaryFunctionPass(PrintPass) {} + + const char *getName() const override { return "clean-mc-state"; } + void runOnFunctions(BinaryContext &BC) override; +}; + /// An optimization to simplify conditional tail calls by removing /// unnecessary branches. /// diff --git a/bolt/lib/Passes/BinaryPasses.cpp b/bolt/lib/Passes/BinaryPasses.cpp --- a/bolt/lib/Passes/BinaryPasses.cpp +++ b/bolt/lib/Passes/BinaryPasses.cpp @@ -626,6 +626,30 @@ BC.MIB->setOffset(*Item.first, Item.second); } +// Check for dirty state in MCSymbol objects that might be a consequence +// of running calculateEmittedSize() in parallel, during split functions +// pass. If an inconsistent state is found (symbol already registered or +// already defined), clean it. +void CleanMCState::runOnFunctions(BinaryContext &BC) { + MCContext &Ctx = *BC.Ctx; + for (const auto &SymMapEntry : Ctx.getSymbols()) { + const MCSymbol *S = SymMapEntry.second; + if (S->isDefined()) { + LLVM_DEBUG(dbgs() << "BOLT-DEBUG: Symbol \"" << S->getName() + << "\" is already defined\n"); + const_cast(S)->setUndefined(); + } + if (S->isRegistered()) { + LLVM_DEBUG(dbgs() << "BOLT-DEBUG: Symbol \"" << S->getName() + << "\" is already registered\n"); + const_cast(S)->setIsRegistered(false); + } + LLVM_DEBUG(if (S->isVariable()) { + dbgs() << "BOLT-DEBUG: Symbol \"" << S->getName() << "\" is variable\n"; + }); + } +} + // This peephole fixes jump instructions that jump to another basic // block with a single jump instruction, e.g. // diff --git a/bolt/lib/Rewrite/BinaryPassManager.cpp b/bolt/lib/Rewrite/BinaryPassManager.cpp --- a/bolt/lib/Rewrite/BinaryPassManager.cpp +++ b/bolt/lib/Rewrite/BinaryPassManager.cpp @@ -488,6 +488,10 @@ Manager.registerPass(std::make_unique(NeverPrint)); + // Check for dirty state of MCSymbols caused by running calculateEmittedSize + // in parallel and restore them + Manager.registerPass(std::make_unique(NeverPrint)); + Manager.runPasses(); }