diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/BackendUtil.cpp | 147 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenAction.cpp | 22 | ||||
-rw-r--r-- | clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp | 29 |
3 files changed, 86 insertions, 112 deletions
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 0c09fd16da3..165b6dd55c9 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -61,9 +61,7 @@ class EmitAssemblyHelper { Timer CodeGenerationTime; - mutable legacy::PassManager *CodeGenPasses; - mutable legacy::PassManager *PerModulePasses; - mutable legacy::FunctionPassManager *PerFunctionPasses; + std::unique_ptr<raw_pwrite_stream> OS; private: TargetIRAnalysis getTargetIRAnalysis() const { @@ -73,73 +71,44 @@ private: return TargetIRAnalysis(); } - legacy::PassManager *getCodeGenPasses() const { - if (!CodeGenPasses) { - CodeGenPasses = new legacy::PassManager(); - CodeGenPasses->add( - createTargetTransformInfoWrapperPass(getTargetIRAnalysis())); - } - return CodeGenPasses; - } - - legacy::PassManager *getPerModulePasses() const { - if (!PerModulePasses) { - PerModulePasses = new legacy::PassManager(); - PerModulePasses->add( - createTargetTransformInfoWrapperPass(getTargetIRAnalysis())); - } - return PerModulePasses; - } - - legacy::FunctionPassManager *getPerFunctionPasses() const { - if (!PerFunctionPasses) { - PerFunctionPasses = new legacy::FunctionPassManager(TheModule); - PerFunctionPasses->add( - createTargetTransformInfoWrapperPass(getTargetIRAnalysis())); - } - return PerFunctionPasses; - } - /// Set LLVM command line options passed through -backend-option. void setCommandLineOpts(); - void CreatePasses(ModuleSummaryIndex *ModuleSummary); + void CreatePasses(legacy::PassManager &MPM, legacy::FunctionPassManager &FPM, + ModuleSummaryIndex *ModuleSummary); /// Generates the TargetMachine. - /// Returns Null if it is unable to create the target machine. + /// Leaves TM unchanged if it is unable to create the target machine. /// Some of our clang tests specify triples which are not built /// into clang. This is okay because these tests check the generated /// IR, and they require DataLayout which depends on the triple. /// In this case, we allow this method to fail and not report an error. /// When MustCreateTM is used, we print an error if we are unable to load /// the requested target. - TargetMachine *CreateTargetMachine(bool MustCreateTM); + void CreateTargetMachine(bool MustCreateTM); /// Add passes necessary to emit assembly or LLVM IR. /// /// \return True on success. - bool AddEmitPasses(BackendAction Action, raw_pwrite_stream &OS); + bool AddEmitPasses(legacy::PassManager &CodeGenPasses, BackendAction Action, + raw_pwrite_stream &OS); public: EmitAssemblyHelper(DiagnosticsEngine &_Diags, const CodeGenOptions &CGOpts, const clang::TargetOptions &TOpts, const LangOptions &LOpts, Module *M) : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts), - TheModule(M), CodeGenerationTime("Code Generation Time"), - CodeGenPasses(nullptr), PerModulePasses(nullptr), - PerFunctionPasses(nullptr) {} + TheModule(M), CodeGenerationTime("Code Generation Time") {} ~EmitAssemblyHelper() { - delete CodeGenPasses; - delete PerModulePasses; - delete PerFunctionPasses; if (CodeGenOpts.DisableFree) BuryPointer(std::move(TM)); } std::unique_ptr<TargetMachine> TM; - void EmitAssembly(BackendAction Action, raw_pwrite_stream *OS); + void EmitAssembly(BackendAction Action, + std::unique_ptr<raw_pwrite_stream> OS); }; // We need this wrapper to access LangOpts and CGOpts from extension functions @@ -311,7 +280,9 @@ static void addSymbolRewriterPass(const CodeGenOptions &Opts, MPM->add(createRewriteSymbolsPass(DL)); } -void EmitAssemblyHelper::CreatePasses(ModuleSummaryIndex *ModuleSummary) { +void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM, + legacy::FunctionPassManager &FPM, + ModuleSummaryIndex *ModuleSummary) { if (CodeGenOpts.DisableLLVMPasses) return; @@ -362,13 +333,11 @@ void EmitAssemblyHelper::CreatePasses(ModuleSummaryIndex *ModuleSummary) { PMBuilder.PrepareForLTO = CodeGenOpts.PrepareForLTO; PMBuilder.RerollLoops = CodeGenOpts.RerollLoops; - legacy::PassManager *MPM = getPerModulePasses(); - // If we are performing a ThinLTO importing compile, invoke the LTO // pipeline and pass down the in-memory module summary index. if (ModuleSummary) { PMBuilder.ModuleSummary = ModuleSummary; - PMBuilder.populateThinLTOPassManager(*MPM); + PMBuilder.populateThinLTOPassManager(MPM); return; } @@ -452,13 +421,12 @@ void EmitAssemblyHelper::CreatePasses(ModuleSummaryIndex *ModuleSummary) { } // Set up the per-function pass manager. - legacy::FunctionPassManager *FPM = getPerFunctionPasses(); if (CodeGenOpts.VerifyModule) - FPM->add(createVerifierPass()); + FPM.add(createVerifierPass()); // Set up the per-module pass manager. if (!CodeGenOpts.RewriteMapFiles.empty()) - addSymbolRewriterPass(CodeGenOpts, MPM); + addSymbolRewriterPass(CodeGenOpts, &MPM); if (!CodeGenOpts.DisableGCov && (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes)) { @@ -473,16 +441,16 @@ void EmitAssemblyHelper::CreatePasses(ModuleSummaryIndex *ModuleSummary) { Options.FunctionNamesInData = !CodeGenOpts.CoverageNoFunctionNamesInData; Options.ExitBlockBeforeBody = CodeGenOpts.CoverageExitBlockBeforeBody; - MPM->add(createGCOVProfilerPass(Options)); + MPM.add(createGCOVProfilerPass(Options)); if (CodeGenOpts.getDebugInfo() == codegenoptions::NoDebugInfo) - MPM->add(createStripSymbolsPass(true)); + MPM.add(createStripSymbolsPass(true)); } if (CodeGenOpts.hasProfileClangInstr()) { InstrProfOptions Options; Options.NoRedZone = CodeGenOpts.DisableRedZone; Options.InstrProfileOutput = CodeGenOpts.InstrProfileOutput; - MPM->add(createInstrProfilingLegacyPass(Options)); + MPM.add(createInstrProfilingLegacyPass(Options)); } if (CodeGenOpts.hasProfileIRInstr()) { if (!CodeGenOpts.InstrProfileOutput.empty()) @@ -494,14 +462,14 @@ void EmitAssemblyHelper::CreatePasses(ModuleSummaryIndex *ModuleSummary) { PMBuilder.PGOInstrUse = CodeGenOpts.ProfileInstrumentUsePath; if (!CodeGenOpts.SampleProfileFile.empty()) { - MPM->add(createPruneEHPass()); - MPM->add(createSampleProfileLoaderPass(CodeGenOpts.SampleProfileFile)); + MPM.add(createPruneEHPass()); + MPM.add(createSampleProfileLoaderPass(CodeGenOpts.SampleProfileFile)); PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addCleanupPassesForSampleProfiler); } - PMBuilder.populateFunctionPassManager(*FPM); - PMBuilder.populateModulePassManager(*MPM); + PMBuilder.populateFunctionPassManager(FPM); + PMBuilder.populateModulePassManager(MPM); } void EmitAssemblyHelper::setCommandLineOpts() { @@ -522,7 +490,7 @@ void EmitAssemblyHelper::setCommandLineOpts() { BackendArgs.data()); } -TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) { +void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) { // Create the TargetMachine for generating code. std::string Error; std::string Triple = TheModule->getTargetTriple(); @@ -530,7 +498,7 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) { if (!TheTarget) { if (MustCreateTM) Diags.Report(diag::err_fe_unable_to_create_target) << Error; - return nullptr; + return; } unsigned CodeModel = @@ -637,24 +605,18 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) { Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose; Options.MCOptions.ABIName = TargetOpts.ABI; - TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU, - FeaturesStr, Options, - RM, CM, OptLevel); - - return TM; + TM.reset(TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr, + Options, RM, CM, OptLevel)); } -bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action, +bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses, + BackendAction Action, raw_pwrite_stream &OS) { - - // Create the code generator passes. - legacy::PassManager *PM = getCodeGenPasses(); - // Add LibraryInfo. llvm::Triple TargetTriple(TheModule->getTargetTriple()); std::unique_ptr<TargetLibraryInfoImpl> TLII( createTLII(TargetTriple, CodeGenOpts)); - PM->add(new TargetLibraryInfoWrapperPass(*TLII)); + CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII)); // Normal mode, emit a .s or .o file by running the code generator. Note, // this also adds codegenerator level optimization passes. @@ -670,9 +632,9 @@ bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action, // "codegen" passes so that it isn't run multiple times when there is // inlining happening. if (CodeGenOpts.OptimizationLevel > 0) - PM->add(createObjCARCContractPass()); + CodeGenPasses.add(createObjCARCContractPass()); - if (TM->addPassesToEmitFile(*PM, OS, CGFT, + if (TM->addPassesToEmitFile(CodeGenPasses, OS, CGFT, /*DisableVerify=*/!CodeGenOpts.VerifyModule)) { Diags.Report(diag::err_fe_unable_to_interface_with_target); return false; @@ -682,7 +644,7 @@ bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action, } void EmitAssemblyHelper::EmitAssembly(BackendAction Action, - raw_pwrite_stream *OS) { + std::unique_ptr<raw_pwrite_stream> OS) { TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr); setCommandLineOpts(); @@ -690,8 +652,7 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action, bool UsesCodeGen = (Action != Backend_EmitNothing && Action != Backend_EmitBC && Action != Backend_EmitLL); - if (!TM) - TM.reset(CreateTargetMachine(UsesCodeGen)); + CreateTargetMachine(UsesCodeGen); if (UsesCodeGen && !TM) return; @@ -718,25 +679,37 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action, assert(ModuleSummary && "Expected non-empty module summary index"); } - CreatePasses(ModuleSummary.get()); + legacy::PassManager PerModulePasses; + PerModulePasses.add( + createTargetTransformInfoWrapperPass(getTargetIRAnalysis())); + + legacy::FunctionPassManager PerFunctionPasses(TheModule); + PerFunctionPasses.add( + createTargetTransformInfoWrapperPass(getTargetIRAnalysis())); + + CreatePasses(PerModulePasses, PerFunctionPasses, ModuleSummary.get()); + + legacy::PassManager CodeGenPasses; + CodeGenPasses.add( + createTargetTransformInfoWrapperPass(getTargetIRAnalysis())); switch (Action) { case Backend_EmitNothing: break; case Backend_EmitBC: - getPerModulePasses()->add(createBitcodeWriterPass( + PerModulePasses.add(createBitcodeWriterPass( *OS, CodeGenOpts.EmitLLVMUseLists, CodeGenOpts.EmitSummaryIndex, CodeGenOpts.EmitSummaryIndex)); break; case Backend_EmitLL: - getPerModulePasses()->add( + PerModulePasses.add( createPrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists)); break; default: - if (!AddEmitPasses(Action, *OS)) + if (!AddEmitPasses(CodeGenPasses, Action, *OS)) return; } @@ -746,24 +719,24 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action, // Run passes. For now we do all passes at once, but eventually we // would like to have the option of streaming code generation. - if (PerFunctionPasses) { + { PrettyStackTraceString CrashInfo("Per-function optimization"); - PerFunctionPasses->doInitialization(); + PerFunctionPasses.doInitialization(); for (Function &F : *TheModule) if (!F.isDeclaration()) - PerFunctionPasses->run(F); - PerFunctionPasses->doFinalization(); + PerFunctionPasses.run(F); + PerFunctionPasses.doFinalization(); } - if (PerModulePasses) { + { PrettyStackTraceString CrashInfo("Per-module optimization passes"); - PerModulePasses->run(*TheModule); + PerModulePasses.run(*TheModule); } - if (CodeGenPasses) { + { PrettyStackTraceString CrashInfo("Code generation"); - CodeGenPasses->run(*TheModule); + CodeGenPasses.run(*TheModule); } } @@ -772,10 +745,10 @@ void clang::EmitBackendOutput(DiagnosticsEngine &Diags, const clang::TargetOptions &TOpts, const LangOptions &LOpts, const llvm::DataLayout &TDesc, Module *M, BackendAction Action, - raw_pwrite_stream *OS) { + std::unique_ptr<raw_pwrite_stream> OS) { EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M); - AsmHelper.EmitAssembly(Action, OS); + AsmHelper.EmitAssembly(Action, std::move(OS)); // Verify clang's TargetInfo DataLayout against the LLVM TargetMachine's // DataLayout. diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index 163cda1b88f..49738a20f49 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -46,7 +46,7 @@ namespace clang { const CodeGenOptions &CodeGenOpts; const TargetOptions &TargetOpts; const LangOptions &LangOpts; - raw_pwrite_stream *AsmOutStream; + std::unique_ptr<raw_pwrite_stream> AsmOutStream; ASTContext *Context; Timer LLVMIRGeneration; @@ -68,11 +68,12 @@ namespace clang { const TargetOptions &TargetOpts, const LangOptions &LangOpts, bool TimePasses, const std::string &InFile, const SmallVectorImpl<std::pair<unsigned, llvm::Module *>> &LinkModules, - raw_pwrite_stream *OS, LLVMContext &C, + std::unique_ptr<raw_pwrite_stream> OS, LLVMContext &C, CoverageSourceInfo *CoverageInfo = nullptr) : Diags(Diags), Action(Action), CodeGenOpts(CodeGenOpts), - TargetOpts(TargetOpts), LangOpts(LangOpts), AsmOutStream(OS), - Context(nullptr), LLVMIRGeneration("LLVM IR Generation Time"), + TargetOpts(TargetOpts), LangOpts(LangOpts), + AsmOutStream(std::move(OS)), Context(nullptr), + LLVMIRGeneration("LLVM IR Generation Time"), Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts, CodeGenOpts, C, CoverageInfo)) { llvm::TimePassesIsEnabled = TimePasses; @@ -177,7 +178,7 @@ namespace clang { EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts, C.getTargetInfo().getDataLayout(), - getModule(), Action, AsmOutStream); + getModule(), Action, std::move(AsmOutStream)); Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext); @@ -691,7 +692,7 @@ llvm::LLVMContext *CodeGenAction::takeLLVMContext() { return VMContext; } -static raw_pwrite_stream * +static std::unique_ptr<raw_pwrite_stream> GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) { switch (Action) { case Backend_EmitAssembly: @@ -714,7 +715,7 @@ GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) { std::unique_ptr<ASTConsumer> CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { BackendAction BA = static_cast<BackendAction>(Act); - raw_pwrite_stream *OS = GetOutputStream(CI, InFile, BA); + std::unique_ptr<raw_pwrite_stream> OS = GetOutputStream(CI, InFile, BA); if (BA != Backend_EmitNothing && !OS) return nullptr; @@ -754,7 +755,7 @@ CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(), CI.getPreprocessorOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(), CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, InFile, LinkModules, - OS, *VMContext, CoverageInfo)); + std::move(OS), *VMContext, CoverageInfo)); BEConsumer = Result.get(); return std::move(Result); } @@ -786,7 +787,8 @@ void CodeGenAction::ExecuteAction() { if (getCurrentFileKind() == IK_LLVM_IR) { BackendAction BA = static_cast<BackendAction>(Act); CompilerInstance &CI = getCompilerInstance(); - raw_pwrite_stream *OS = GetOutputStream(CI, getCurrentFile(), BA); + std::unique_ptr<raw_pwrite_stream> OS = + GetOutputStream(CI, getCurrentFile(), BA); if (BA != Backend_EmitNothing && !OS) return; @@ -843,7 +845,7 @@ void CodeGenAction::ExecuteAction() { EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(), TargetOpts, CI.getLangOpts(), CI.getTarget().getDataLayout(), - TheModule.get(), BA, OS); + TheModule.get(), BA, std::move(OS)); return; } diff --git a/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp b/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp index 2aa06062a57..de40e412112 100644 --- a/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp +++ b/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp @@ -55,7 +55,7 @@ class PCHContainerGenerator : public ASTConsumer { std::unique_ptr<llvm::LLVMContext> VMContext; std::unique_ptr<llvm::Module> M; std::unique_ptr<CodeGen::CodeGenModule> Builder; - raw_pwrite_stream *OS; + std::unique_ptr<raw_pwrite_stream> OS; std::shared_ptr<PCHBuffer> Buffer; /// Visit every type and emit debug info for it. @@ -138,15 +138,15 @@ class PCHContainerGenerator : public ASTConsumer { public: PCHContainerGenerator(CompilerInstance &CI, const std::string &MainFileName, const std::string &OutputFileName, - raw_pwrite_stream *OS, + std::unique_ptr<raw_pwrite_stream> OS, std::shared_ptr<PCHBuffer> Buffer) : Diags(CI.getDiagnostics()), MainFileName(MainFileName), OutputFileName(OutputFileName), Ctx(nullptr), MMap(CI.getPreprocessor().getHeaderSearchInfo().getModuleMap()), HeaderSearchOpts(CI.getHeaderSearchOpts()), PreprocessorOpts(CI.getPreprocessorOpts()), - TargetOpts(CI.getTargetOpts()), LangOpts(CI.getLangOpts()), OS(OS), - Buffer(std::move(Buffer)) { + TargetOpts(CI.getTargetOpts()), LangOpts(CI.getLangOpts()), + OS(std::move(OS)), Buffer(std::move(Buffer)) { // The debug info output isn't affected by CodeModel and // ThreadModel, but the backend expects them to be nonempty. CodeGenOpts.CodeModel = "default"; @@ -281,20 +281,18 @@ public: DEBUG({ // Print the IR for the PCH container to the debug output. llvm::SmallString<0> Buffer; - llvm::raw_svector_ostream OS(Buffer); - clang::EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts, - Ctx.getTargetInfo().getDataLayout(), M.get(), - BackendAction::Backend_EmitLL, &OS); + clang::EmitBackendOutput( + Diags, CodeGenOpts, TargetOpts, LangOpts, + Ctx.getTargetInfo().getDataLayout(), M.get(), + BackendAction::Backend_EmitLL, + llvm::make_unique<llvm::raw_svector_ostream>(Buffer)); llvm::dbgs() << Buffer; }); // Use the LLVM backend to emit the pch container. clang::EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts, Ctx.getTargetInfo().getDataLayout(), M.get(), - BackendAction::Backend_EmitObj, OS); - - // Make sure the pch container hits disk. - OS->flush(); + BackendAction::Backend_EmitObj, std::move(OS)); // Free the memory for the temporary buffer. llvm::SmallVector<char, 0> Empty; @@ -307,10 +305,11 @@ public: std::unique_ptr<ASTConsumer> ObjectFilePCHContainerWriter::CreatePCHContainerGenerator( CompilerInstance &CI, const std::string &MainFileName, - const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, + const std::string &OutputFileName, + std::unique_ptr<llvm::raw_pwrite_stream> OS, std::shared_ptr<PCHBuffer> Buffer) const { - return llvm::make_unique<PCHContainerGenerator>(CI, MainFileName, - OutputFileName, OS, Buffer); + return llvm::make_unique<PCHContainerGenerator>( + CI, MainFileName, OutputFileName, std::move(OS), Buffer); } void ObjectFilePCHContainerReader::ExtractPCH( |