diff options
Diffstat (limited to 'lib/Frontend/Backend.cpp')
-rw-r--r-- | lib/Frontend/Backend.cpp | 91 |
1 files changed, 51 insertions, 40 deletions
diff --git a/lib/Frontend/Backend.cpp b/lib/Frontend/Backend.cpp index 13aecf1..bc56029 100644 --- a/lib/Frontend/Backend.cpp +++ b/lib/Frontend/Backend.cpp @@ -8,12 +8,13 @@ //===----------------------------------------------------------------------===// #include "clang/Frontend/ASTConsumers.h" -#include "clang/CodeGen/ModuleBuilder.h" -#include "clang/Frontend/CompileOptions.h" -#include "clang/AST/ASTContext.h" #include "clang/AST/ASTConsumer.h" +#include "clang/AST/ASTContext.h" #include "clang/AST/DeclGroup.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Basic/TargetOptions.h" +#include "clang/CodeGen/CodeGenOptions.h" +#include "clang/CodeGen/ModuleBuilder.h" #include "llvm/Module.h" #include "llvm/ModuleProvider.h" #include "llvm/PassManager.h" @@ -40,7 +41,8 @@ using namespace llvm; namespace { class VISIBILITY_HIDDEN BackendConsumer : public ASTConsumer { BackendAction Action; - CompileOptions CompileOpts; + CodeGenOptions CodeGenOpts; + TargetOptions TargetOpts; llvm::raw_ostream *AsmOutStream; llvm::formatted_raw_ostream FormattedOutStream; ASTContext *Context; @@ -75,11 +77,12 @@ namespace { public: BackendConsumer(BackendAction action, Diagnostic &Diags, - const LangOptions &langopts, const CompileOptions &compopts, - const std::string &infile, llvm::raw_ostream* OS, - LLVMContext& C) : + const LangOptions &langopts, const CodeGenOptions &compopts, + const TargetOptions &targetopts, const std::string &infile, + llvm::raw_ostream* OS, LLVMContext& C) : Action(action), - CompileOpts(compopts), + CodeGenOpts(compopts), + TargetOpts(targetopts), AsmOutStream(OS), LLVMIRGeneration("LLVM IR Generation Time"), CodeGenerationTime("Code Generation Time"), @@ -92,7 +95,7 @@ namespace { formatted_raw_ostream::PRESERVE_STREAM); // Enable -time-passes if -ftime-report is enabled. - llvm::TimePassesIsEnabled = CompileOpts.TimePasses; + llvm::TimePassesIsEnabled = CodeGenOpts.TimePasses; } ~BackendConsumer() { @@ -106,7 +109,7 @@ namespace { virtual void Initialize(ASTContext &Ctx) { Context = &Ctx; - if (CompileOpts.TimePasses) + if (CodeGenOpts.TimePasses) LLVMIRGeneration.startTimer(); Gen->Initialize(Ctx); @@ -115,7 +118,7 @@ namespace { ModuleProvider = new ExistingModuleProvider(TheModule); TheTargetData = new llvm::TargetData(Ctx.Target.getTargetDescription()); - if (CompileOpts.TimePasses) + if (CodeGenOpts.TimePasses) LLVMIRGeneration.stopTimer(); } @@ -124,24 +127,24 @@ namespace { Context->getSourceManager(), "LLVM IR generation of declaration"); - if (CompileOpts.TimePasses) + if (CodeGenOpts.TimePasses) LLVMIRGeneration.startTimer(); Gen->HandleTopLevelDecl(D); - if (CompileOpts.TimePasses) + if (CodeGenOpts.TimePasses) LLVMIRGeneration.stopTimer(); } virtual void HandleTranslationUnit(ASTContext &C) { { PrettyStackTraceString CrashInfo("Per-file LLVM IR generation"); - if (CompileOpts.TimePasses) + if (CodeGenOpts.TimePasses) LLVMIRGeneration.startTimer(); Gen->HandleTranslationUnit(C); - if (CompileOpts.TimePasses) + if (CodeGenOpts.TimePasses) LLVMIRGeneration.stopTimer(); } @@ -202,7 +205,7 @@ bool BackendConsumer::AddEmitPasses(std::string &Error) { } else if (Action == Backend_EmitLL) { getPerModulePasses()->add(createPrintModulePass(&FormattedOutStream)); } else { - bool Fast = CompileOpts.OptimizationLevel == 0; + bool Fast = CodeGenOpts.OptimizationLevel == 0; // Create the TargetMachine for generating code. std::string Triple = TheModule->getTargetTriple(); @@ -213,12 +216,12 @@ bool BackendConsumer::AddEmitPasses(std::string &Error) { } std::string FeaturesStr; - if (CompileOpts.CPU.size() || CompileOpts.Features.size()) { + if (TargetOpts.CPU.size() || TargetOpts.Features.size()) { SubtargetFeatures Features; - Features.setCPU(CompileOpts.CPU); + Features.setCPU(TargetOpts.CPU); for (std::vector<std::string>::iterator - it = CompileOpts.Features.begin(), - ie = CompileOpts.Features.end(); it != ie; ++it) + it = TargetOpts.Features.begin(), + ie = TargetOpts.Features.end(); it != ie; ++it) Features.AddFeature(*it); FeaturesStr = Features.getString(); } @@ -237,7 +240,7 @@ bool BackendConsumer::AddEmitPasses(std::string &Error) { FunctionPassManager *PM = getCodeGenPasses(); CodeGenOpt::Level OptLevel = CodeGenOpt::Default; - switch (CompileOpts.OptimizationLevel) { + switch (CodeGenOpts.OptimizationLevel) { default: break; case 0: OptLevel = CodeGenOpt::None; break; case 3: OptLevel = CodeGenOpt::Aggressive; break; @@ -266,37 +269,44 @@ bool BackendConsumer::AddEmitPasses(std::string &Error) { } void BackendConsumer::CreatePasses() { + unsigned OptLevel = CodeGenOpts.OptimizationLevel; + CodeGenOptions::InliningMethod Inlining = CodeGenOpts.Inlining; + + // Handle disabling of LLVM optimization, where we want to preserve the + // internal module before any optimization. + if (CodeGenOpts.DisableLLVMOpts) { + OptLevel = 0; + Inlining = CodeGenOpts.NoInlining; + } + // In -O0 if checking is disabled, we don't even have per-function passes. - if (CompileOpts.VerifyModule) + if (CodeGenOpts.VerifyModule) getPerFunctionPasses()->add(createVerifierPass()); // Assume that standard function passes aren't run for -O0. - if (CompileOpts.OptimizationLevel > 0) - llvm::createStandardFunctionPasses(getPerFunctionPasses(), - CompileOpts.OptimizationLevel); + if (OptLevel > 0) + llvm::createStandardFunctionPasses(getPerFunctionPasses(), OptLevel); llvm::Pass *InliningPass = 0; - switch (CompileOpts.Inlining) { - case CompileOptions::NoInlining: break; - case CompileOptions::NormalInlining: { + switch (Inlining) { + case CodeGenOptions::NoInlining: break; + case CodeGenOptions::NormalInlining: { // Inline small functions - unsigned Threshold = (CompileOpts.OptimizeSize || - CompileOpts.OptimizationLevel < 3) ? 50 : 200; + unsigned Threshold = (CodeGenOpts.OptimizeSize || OptLevel < 3) ? 50 : 200; InliningPass = createFunctionInliningPass(Threshold); break; } - case CompileOptions::OnlyAlwaysInlining: + case CodeGenOptions::OnlyAlwaysInlining: InliningPass = createAlwaysInlinerPass(); // Respect always_inline break; } // For now we always create per module passes. PassManager *PM = getPerModulePasses(); - llvm::createStandardModulePasses(PM, CompileOpts.OptimizationLevel, - CompileOpts.OptimizeSize, - CompileOpts.UnitAtATime, - CompileOpts.UnrollLoops, - CompileOpts.SimplifyLibCalls, + llvm::createStandardModulePasses(PM, OptLevel, CodeGenOpts.OptimizeSize, + CodeGenOpts.UnitAtATime, + CodeGenOpts.UnrollLoops, + CodeGenOpts.SimplifyLibCalls, /*HaveExceptions=*/true, InliningPass); } @@ -308,7 +318,7 @@ void BackendConsumer::EmitAssembly() { if (!TheModule || !TheTargetData) return; - TimeRegion Region(CompileOpts.TimePasses ? &CodeGenerationTime : 0); + TimeRegion Region(CodeGenOpts.TimePasses ? &CodeGenerationTime : 0); // Make sure IR generation is happy with the module. This is // released by the module provider. @@ -363,10 +373,11 @@ void BackendConsumer::EmitAssembly() { ASTConsumer *clang::CreateBackendConsumer(BackendAction Action, Diagnostic &Diags, const LangOptions &LangOpts, - const CompileOptions &CompileOpts, + const CodeGenOptions &CodeGenOpts, + const TargetOptions &TargetOpts, const std::string& InFile, llvm::raw_ostream* OS, LLVMContext& C) { - return new BackendConsumer(Action, Diags, LangOpts, CompileOpts, - InFile, OS, C); + return new BackendConsumer(Action, Diags, LangOpts, CodeGenOpts, + TargetOpts, InFile, OS, C); } |