summaryrefslogtreecommitdiffstats
path: root/lib/Frontend/Backend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Frontend/Backend.cpp')
-rw-r--r--lib/Frontend/Backend.cpp91
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);
}
OpenPOWER on IntegriCloud