aboutsummaryrefslogtreecommitdiff
path: root/lib/Frontend/Backend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Frontend/Backend.cpp')
-rw-r--r--lib/Frontend/Backend.cpp85
1 files changed, 45 insertions, 40 deletions
diff --git a/lib/Frontend/Backend.cpp b/lib/Frontend/Backend.cpp
index 1c536b07cee2..13aecf171718 100644
--- a/lib/Frontend/Backend.cpp
+++ b/lib/Frontend/Backend.cpp
@@ -24,8 +24,8 @@
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/StandardPasses.h"
#include "llvm/Support/Timer.h"
#include "llvm/System/Path.h"
@@ -33,7 +33,7 @@
#include "llvm/Target/SubtargetFeature.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetMachineRegistry.h"
+#include "llvm/Target/TargetRegistry.h"
using namespace clang;
using namespace llvm;
@@ -42,13 +42,14 @@ namespace {
BackendAction Action;
CompileOptions CompileOpts;
llvm::raw_ostream *AsmOutStream;
+ llvm::formatted_raw_ostream FormattedOutStream;
ASTContext *Context;
Timer LLVMIRGeneration;
Timer CodeGenerationTime;
-
+
llvm::OwningPtr<CodeGenerator> Gen;
-
+
llvm::Module *TheModule;
llvm::TargetData *TheTargetData;
@@ -71,21 +72,25 @@ namespace {
bool AddEmitPasses(std::string &Error);
void EmitAssembly();
-
- public:
- BackendConsumer(BackendAction action, Diagnostic &Diags,
+
+ public:
+ BackendConsumer(BackendAction action, Diagnostic &Diags,
const LangOptions &langopts, const CompileOptions &compopts,
const std::string &infile, llvm::raw_ostream* OS,
LLVMContext& C) :
- Action(action),
+ Action(action),
CompileOpts(compopts),
- AsmOutStream(OS),
+ AsmOutStream(OS),
LLVMIRGeneration("LLVM IR Generation Time"),
CodeGenerationTime("Code Generation Time"),
Gen(CreateLLVMCodeGen(Diags, infile, compopts, C)),
TheModule(0), TheTargetData(0), ModuleProvider(0),
CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) {
-
+
+ if (AsmOutStream)
+ FormattedOutStream.setStream(*AsmOutStream,
+ formatted_raw_ostream::PRESERVE_STREAM);
+
// Enable -time-passes if -ftime-report is enabled.
llvm::TimePassesIsEnabled = CompileOpts.TimePasses;
}
@@ -100,25 +105,25 @@ namespace {
virtual void Initialize(ASTContext &Ctx) {
Context = &Ctx;
-
+
if (CompileOpts.TimePasses)
LLVMIRGeneration.startTimer();
-
+
Gen->Initialize(Ctx);
TheModule = Gen->GetModule();
ModuleProvider = new ExistingModuleProvider(TheModule);
TheTargetData = new llvm::TargetData(Ctx.Target.getTargetDescription());
-
+
if (CompileOpts.TimePasses)
LLVMIRGeneration.stopTimer();
}
-
+
virtual void HandleTopLevelDecl(DeclGroupRef D) {
PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
Context->getSourceManager(),
"LLVM IR generation of declaration");
-
+
if (CompileOpts.TimePasses)
LLVMIRGeneration.startTimer();
@@ -127,7 +132,7 @@ namespace {
if (CompileOpts.TimePasses)
LLVMIRGeneration.stopTimer();
}
-
+
virtual void HandleTranslationUnit(ASTContext &C) {
{
PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
@@ -142,12 +147,12 @@ namespace {
// EmitAssembly times and registers crash info itself.
EmitAssembly();
-
+
// Force a flush here in case we never get released.
if (AsmOutStream)
- AsmOutStream->flush();
+ FormattedOutStream.flush();
}
-
+
virtual void HandleTagDeclDefinition(TagDecl *D) {
PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
Context->getSourceManager(),
@@ -158,7 +163,7 @@ namespace {
virtual void CompleteTentativeDefinition(VarDecl *D) {
Gen->CompleteTentativeDefinition(D);
}
- };
+ };
}
FunctionPassManager *BackendConsumer::getCodeGenPasses() const {
@@ -193,16 +198,16 @@ bool BackendConsumer::AddEmitPasses(std::string &Error) {
return true;
if (Action == Backend_EmitBC) {
- getPerModulePasses()->add(createBitcodeWriterPass(*AsmOutStream));
+ getPerModulePasses()->add(createBitcodeWriterPass(FormattedOutStream));
} else if (Action == Backend_EmitLL) {
- getPerModulePasses()->add(createPrintModulePass(AsmOutStream));
+ getPerModulePasses()->add(createPrintModulePass(&FormattedOutStream));
} else {
bool Fast = CompileOpts.OptimizationLevel == 0;
// Create the TargetMachine for generating code.
- const TargetMachineRegistry::entry *TME =
- TargetMachineRegistry::getClosestStaticTargetForModule(*TheModule, Error);
- if (!TME) {
+ std::string Triple = TheModule->getTargetTriple();
+ const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
+ if (!TheTarget) {
Error = std::string("Unable to get target machine: ") + Error;
return false;
}
@@ -211,18 +216,18 @@ bool BackendConsumer::AddEmitPasses(std::string &Error) {
if (CompileOpts.CPU.size() || CompileOpts.Features.size()) {
SubtargetFeatures Features;
Features.setCPU(CompileOpts.CPU);
- for (std::vector<std::string>::iterator
+ for (std::vector<std::string>::iterator
it = CompileOpts.Features.begin(),
ie = CompileOpts.Features.end(); it != ie; ++it)
Features.AddFeature(*it);
FeaturesStr = Features.getString();
}
- TargetMachine *TM = TME->CtorFn(*TheModule, FeaturesStr);
-
+ TargetMachine *TM = TheTarget->createTargetMachine(Triple, FeaturesStr);
+
// Set register scheduler & allocation policy.
RegisterScheduler::setDefault(createDefaultScheduler);
- RegisterRegAlloc::setDefault(Fast ? createLocalRegisterAllocator :
- createLinearScanRegisterAllocator);
+ RegisterRegAlloc::setDefault(Fast ? createLocalRegisterAllocator :
+ createLinearScanRegisterAllocator);
// From llvm-gcc:
// If there are passes we have to run on the entire module, we do codegen
@@ -240,7 +245,7 @@ bool BackendConsumer::AddEmitPasses(std::string &Error) {
// Normal mode, emit a .s file by running the code generator.
// Note, this also adds codegenerator level optimization passes.
- switch (TM->addPassesToEmitFile(*PM, *AsmOutStream,
+ switch (TM->addPassesToEmitFile(*PM, FormattedOutStream,
TargetMachine::AssemblyFile, OptLevel)) {
default:
case FileModel::Error:
@@ -249,7 +254,7 @@ bool BackendConsumer::AddEmitPasses(std::string &Error) {
case FileModel::AsmFile:
break;
}
-
+
if (TM->addPassesToEmitFileFinish(*CodeGenPasses, (MachineCodeEmitter *)0,
OptLevel)) {
Error = "Unable to interface with target machine!\n";
@@ -287,8 +292,8 @@ void BackendConsumer::CreatePasses() {
// For now we always create per module passes.
PassManager *PM = getPerModulePasses();
- llvm::createStandardModulePasses(PM, CompileOpts.OptimizationLevel,
- CompileOpts.OptimizeSize,
+ llvm::createStandardModulePasses(PM, CompileOpts.OptimizationLevel,
+ CompileOpts.OptimizeSize,
CompileOpts.UnitAtATime,
CompileOpts.UnrollLoops,
CompileOpts.SimplifyLibCalls,
@@ -297,12 +302,12 @@ void BackendConsumer::CreatePasses() {
}
/// EmitAssembly - Handle interaction with LLVM backend to generate
-/// actual machine code.
+/// actual machine code.
void BackendConsumer::EmitAssembly() {
// Silently ignore if we weren't initialized for some reason.
if (!TheModule || !TheTargetData)
return;
-
+
TimeRegion Region(CompileOpts.TimePasses ? &CodeGenerationTime : 0);
// Make sure IR generation is happy with the module. This is
@@ -323,7 +328,7 @@ void BackendConsumer::EmitAssembly() {
std::string Error;
if (!AddEmitPasses(Error)) {
// FIXME: Don't fail this way.
- llvm::cerr << "ERROR: " << Error << "\n";
+ llvm::errs() << "ERROR: " << Error << "\n";
::exit(1);
}
@@ -332,19 +337,19 @@ void BackendConsumer::EmitAssembly() {
if (PerFunctionPasses) {
PrettyStackTraceString CrashInfo("Per-function optimization");
-
+
PerFunctionPasses->doInitialization();
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
if (!I->isDeclaration())
PerFunctionPasses->run(*I);
PerFunctionPasses->doFinalization();
}
-
+
if (PerModulePasses) {
PrettyStackTraceString CrashInfo("Per-module optimization passes");
PerModulePasses->run(*M);
}
-
+
if (CodeGenPasses) {
PrettyStackTraceString CrashInfo("Code generation");
CodeGenPasses->doInitialization();