diff --git a/interpreter/cling/lib/Interpreter/BackendPasses.cpp b/interpreter/cling/lib/Interpreter/BackendPasses.cpp index dc37ffc6f3ce3..b30917383e80f 100644 --- a/interpreter/cling/lib/Interpreter/BackendPasses.cpp +++ b/interpreter/cling/lib/Interpreter/BackendPasses.cpp @@ -30,49 +30,6 @@ using namespace clang; using namespace llvm; using namespace llvm::legacy; -namespace { - - class InlinerKeepDeadFunc: public Inliner { - Inliner* m_Inliner; // the actual inliner - static char ID; // Pass identification, replacement for typeid - public: - InlinerKeepDeadFunc(): - Inliner(ID), m_Inliner(0) { } - InlinerKeepDeadFunc(Pass* I): - Inliner(ID), m_Inliner((Inliner*)I) { } - - using llvm::Pass::doInitialization; - bool doInitialization(CallGraph &CG) override { - // Forward out Resolver now that we are registered. - if (!m_Inliner->getResolver()) - m_Inliner->setResolver(getResolver()); - return m_Inliner->doInitialization(CG); // no Module modification - } - - InlineCost getInlineCost(CallSite CS) override { - return m_Inliner->getInlineCost(CS); - } - void getAnalysisUsage(AnalysisUsage &AU) const override { - m_Inliner->getAnalysisUsage(AU); - } - bool runOnSCC(CallGraphSCC &SCC) override { - return m_Inliner->runOnSCC(SCC); - } - - using llvm::Pass::doFinalization; - // No-op: we need to keep the inlined functions for later use. - bool doFinalization(CallGraph& /*CG*/) override { - // Module is unchanged - return false; - } - }; -} // end anonymous namespace - -// Pass registration. Luckily all known inliners depend on the same set -// of passes. -char InlinerKeepDeadFunc::ID = 0; - - BackendPasses::~BackendPasses() { //delete m_PMBuilder->Inliner; } @@ -85,8 +42,9 @@ void BackendPasses::CreatePasses(llvm::Module& M) // DON'T: we will not find our symbols... //CGOpts_.CXXCtorDtorAliases = 1; - // Default clang -O2 on Linux 64bit also has: #if 0 + // Default clang -O2 on Linux 64bit also has the following, but see + // CIFactory.cpp. CGOpts_.DisableFPElim = 0; CGOpts_.DiscardValueNames = 1; CGOpts_.OmitLeafFramePointer = 1; @@ -96,12 +54,15 @@ void BackendPasses::CreatePasses(llvm::Module& M) CGOpts_.VectorizeLoop = 1; CGOpts_.VectorizeSLP = 1; #endif + + // Better inlining is pending https://bugs.llvm.org//show_bug.cgi?id=19668 + // and its consequence https://sft.its.cern.ch/jira/browse/ROOT-7111 + // shown e.g. by roottest/cling/stl/map/badstringMap CGOpts_.setInlining(CodeGenOptions::NormalInlining); unsigned OptLevel = m_CGOpts.OptimizationLevel; - // CodeGenOptions::InliningMethod Inlining = m_CGOpts.getInlining(); - CodeGenOptions::InliningMethod Inlining = CodeGenOptions::NormalInlining; + CodeGenOptions::InliningMethod Inlining = m_CGOpts.getInlining(); // Handle disabling of LLVM optimization, where we want to preserve the // internal module before any optimization. @@ -111,9 +72,6 @@ void BackendPasses::CreatePasses(llvm::Module& M) // Inlining = CGOpts.NoInlining; } - OptLevel = 0; // we need to keep even "unused" values - until we - // feed incremental modules into the JIT. - llvm::PassManagerBuilder PMBuilder; PMBuilder.OptLevel = OptLevel; PMBuilder.SizeLevel = m_CGOpts.OptimizeSize; @@ -138,19 +96,16 @@ void BackendPasses::CreatePasses(llvm::Module& M) } case CodeGenOptions::NormalInlining: { PMBuilder.Inliner = - new InlinerKeepDeadFunc(createFunctionInliningPass(OptLevel, - m_CGOpts.OptimizeSize)); + createFunctionInliningPass(OptLevel, m_CGOpts.OptimizeSize); break; } case CodeGenOptions::OnlyAlwaysInlining: // Respect always_inline. if (OptLevel == 0) // Do not insert lifetime intrinsics at -O0. - PMBuilder.Inliner - = new InlinerKeepDeadFunc(createAlwaysInlinerPass(false)); + PMBuilder.Inliner = createAlwaysInlinerPass(false); else - PMBuilder.Inliner - = new InlinerKeepDeadFunc(createAlwaysInlinerPass()); + PMBuilder.Inliner = createAlwaysInlinerPass(); break; } diff --git a/interpreter/cling/lib/Interpreter/CIFactory.cpp b/interpreter/cling/lib/Interpreter/CIFactory.cpp index 90795306ca0dd..12f4413ce05c0 100644 --- a/interpreter/cling/lib/Interpreter/CIFactory.cpp +++ b/interpreter/cling/lib/Interpreter/CIFactory.cpp @@ -926,20 +926,28 @@ static void stringifyPreprocSetting(PreprocessorOptions& PPOpts, CodeCompleteConsumer* CCC = 0; CI->createSema(TU_Complete, CCC); - // Set CodeGen options - // want debug info + // Set CodeGen options. + CodeGenOptions& CGOpts = CI->getCodeGenOpts(); #ifdef _MSC_VER - CI->getCodeGenOpts().MSVolatile = 1; - CI->getCodeGenOpts().RelaxedAliasing = 1; - CI->getCodeGenOpts().EmitCodeView = 1; - CI->getCodeGenOpts().CXXCtorDtorAliases = 1; + CGOpts.MSVolatile = 1; + CGOpts.RelaxedAliasing = 1; + CGOpts.EmitCodeView = 1; + CGOpts.CXXCtorDtorAliases = 1; #endif - //CI->getCodeGenOpts().setDebugInfo(clang::CodeGenOptions::FullDebugInfo); - // CI->getCodeGenOpts().EmitDeclMetadata = 1; // For unloading, for later - CI->getCodeGenOpts().CXXCtorDtorAliases = 0; // aliasing the complete - // ctor to the base ctor causes - // the JIT to crash - CI->getCodeGenOpts().VerifyModule = 0; // takes too long + // Reduce amount of emitted symbols by optimizing more. + CGOpts.OptimizationLevel = 2; + // Taken from a -O2 run of clang: + CGOpts.DiscardValueNames = 1; + CGOpts.OmitLeafFramePointer = 1; + CGOpts.UnrollLoops = 1; + CGOpts.VectorizeLoop = 1; + CGOpts.VectorizeSLP = 1; + + // CGOpts.setDebugInfo(clang::CodeGenOptions::FullDebugInfo); + // CGOpts.EmitDeclMetadata = 1; // For unloading, for later + // aliasing the complete ctor to the base ctor causes the JIT to crash + CGOpts.CXXCtorDtorAliases = 0; + CGOpts.VerifyModule = 0; // takes too long if (!OnlyLex) { // -nobuiltininc diff --git a/interpreter/llvm/src/tools/clang/lib/CodeGen/CodeGenModule.cpp b/interpreter/llvm/src/tools/clang/lib/CodeGen/CodeGenModule.cpp index 709e0d69d2679..fe641c3cfb121 100644 --- a/interpreter/llvm/src/tools/clang/lib/CodeGen/CodeGenModule.cpp +++ b/interpreter/llvm/src/tools/clang/lib/CodeGen/CodeGenModule.cpp @@ -1663,10 +1663,12 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { if (llvm::GlobalValue *GV = GetGlobalValue(MangledName)) { // The value has already been used and should therefore be emitted. addDeferredDeclToEmit(GV, GD); + DeferredDecls[MangledName] = GD; } else if (MustBeEmitted(Global)) { // The value must be emitted, but cannot be emitted eagerly. assert(!MayBeEmittedEagerly(Global)); addDeferredDeclToEmit(/*GV=*/nullptr, GD); + DeferredDecls[MangledName] = GD; } else { // Otherwise, remember that we saw a deferred decl with this name. The // first use of the mangled name will cause it to move into