diff options
author | John McCall <rjmccall@apple.com> | 2010-03-04 00:23:29 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-03-04 00:23:29 +0000 |
commit | c9fe644675503894e9e76e8ecd8e6519426548de (patch) | |
tree | ff130be72fa30cac9af308e4eedb57d8c647d818 | |
parent | 5fccd36204f11c8491325038e6ffcc784399098e (diff) |
Create a TargetMachine whenever we create a CodeGenAction. The codegen of
some builtins will rely on target knowledge.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97693 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/CodeGen/ModuleBuilder.h | 2 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 7 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 8 | ||||
-rw-r--r-- | lib/CodeGen/ModuleBuilder.cpp | 13 | ||||
-rw-r--r-- | lib/Frontend/CodeGenAction.cpp | 126 |
5 files changed, 94 insertions, 62 deletions
diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h index 2a3aa6a904..40669926e2 100644 --- a/include/clang/CodeGen/ModuleBuilder.h +++ b/include/clang/CodeGen/ModuleBuilder.h @@ -20,6 +20,7 @@ namespace llvm { class LLVMContext; class Module; + class TargetMachine; } namespace clang { @@ -36,6 +37,7 @@ namespace clang { CodeGenerator *CreateLLVMCodeGen(Diagnostic &Diags, const std::string &ModuleName, const CodeGenOptions &CGO, + const llvm::TargetMachine &Machine, llvm::LLVMContext& C); } diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 91c7322c67..a3a9e61977 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -40,11 +40,12 @@ using namespace CodeGen; CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, - llvm::Module &M, const llvm::TargetData &TD, - Diagnostic &diags) + llvm::Module &M, const llvm::TargetMachine &TM, + const llvm::TargetData &TD, Diagnostic &diags) : BlockModule(C, M, TD, Types, *this), Context(C), Features(C.getLangOptions()), CodeGenOpts(CGO), TheModule(M), - TheTargetData(TD), TheTargetCodeGenInfo(0), Diags(diags), + TheTargetMachine(TM), TheTargetData(TD), TheTargetCodeGenInfo(0), + Diags(diags), Types(C, M, TD, getTargetCodeGenInfo().getABIInfo()), MangleCtx(C), VtableInfo(*this), Runtime(0), MemCpyFn(0), MemMoveFn(0), MemSetFn(0), CFConstantStringClassRef(0), diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index ac8332647b..8b9a0f29c7 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -38,6 +38,7 @@ namespace llvm { class Function; class GlobalValue; class TargetData; + class TargetMachine; class FunctionType; class LLVMContext; } @@ -86,6 +87,7 @@ class CodeGenModule : public BlockModule { const LangOptions &Features; const CodeGenOptions &CodeGenOpts; llvm::Module &TheModule; + const llvm::TargetMachine &TheTargetMachine; const llvm::TargetData &TheTargetData; mutable const TargetCodeGenInfo *TheTargetCodeGenInfo; Diagnostic &Diags; @@ -168,7 +170,8 @@ class CodeGenModule : public BlockModule { llvm::LLVMContext &VMContext; public: CodeGenModule(ASTContext &C, const CodeGenOptions &CodeGenOpts, - llvm::Module &M, const llvm::TargetData &TD, Diagnostic &Diags); + llvm::Module &M, const llvm::TargetMachine &TM, + const llvm::TargetData &TD, Diagnostic &Diags); ~CodeGenModule(); @@ -198,6 +201,9 @@ public: const llvm::TargetData &getTargetData() const { return TheTargetData; } llvm::LLVMContext &getLLVMContext() { return VMContext; } const TargetCodeGenInfo &getTargetCodeGenInfo() const; + const llvm::TargetMachine &getTargetMachine() const { + return TheTargetMachine; + } /// getDeclVisibilityMode - Compute the visibility of the decl \arg D. LangOptions::VisibilityMode getDeclVisibilityMode(const Decl *D) const; diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp index 1e1edc1c48..4ae18bbb14 100644 --- a/lib/CodeGen/ModuleBuilder.cpp +++ b/lib/CodeGen/ModuleBuilder.cpp @@ -29,6 +29,7 @@ namespace { class CodeGeneratorImpl : public CodeGenerator { Diagnostic &Diags; llvm::OwningPtr<const llvm::TargetData> TD; + const llvm::TargetMachine &TM; ASTContext *Ctx; const CodeGenOptions CodeGenOpts; // Intentionally copied in. protected: @@ -36,8 +37,11 @@ namespace { llvm::OwningPtr<CodeGen::CodeGenModule> Builder; public: CodeGeneratorImpl(Diagnostic &diags, const std::string& ModuleName, - const CodeGenOptions &CGO, llvm::LLVMContext& C) - : Diags(diags), CodeGenOpts(CGO), M(new llvm::Module(ModuleName, C)) {} + const CodeGenOptions &CGO, + const llvm::TargetMachine &TM, + llvm::LLVMContext& C) + : Diags(diags), TM(TM), CodeGenOpts(CGO), + M(new llvm::Module(ModuleName, C)) {} virtual ~CodeGeneratorImpl() {} @@ -56,7 +60,7 @@ namespace { M->setDataLayout(Ctx->Target.getTargetDescription()); TD.reset(new llvm::TargetData(Ctx->Target.getTargetDescription())); Builder.reset(new CodeGen::CodeGenModule(Context, CodeGenOpts, - *M, *TD, Diags)); + *M, TM, *TD, Diags)); } virtual void HandleTopLevelDecl(DeclGroupRef DG) { @@ -95,6 +99,7 @@ namespace { CodeGenerator *clang::CreateLLVMCodeGen(Diagnostic &Diags, const std::string& ModuleName, const CodeGenOptions &CGO, + const llvm::TargetMachine &Machine, llvm::LLVMContext& C) { - return new CodeGeneratorImpl(Diags, ModuleName, CGO, C); + return new CodeGeneratorImpl(Diags, ModuleName, CGO, Machine, C); } diff --git a/lib/Frontend/CodeGenAction.cpp b/lib/Frontend/CodeGenAction.cpp index b1795a3aa3..ca78974bbc 100644 --- a/lib/Frontend/CodeGenAction.cpp +++ b/lib/Frontend/CodeGenAction.cpp @@ -64,6 +64,7 @@ namespace { llvm::OwningPtr<llvm::Module> TheModule; llvm::TargetData *TheTargetData; + llvm::OwningPtr<llvm::TargetMachine> TheTargetMachine; mutable FunctionPassManager *CodeGenPasses; mutable PassManager *PerModulePasses; @@ -84,6 +85,7 @@ namespace { public: BackendConsumer(BackendAction action, Diagnostic &_Diags, + llvm::TargetMachine &machine, const LangOptions &langopts, const CodeGenOptions &compopts, const TargetOptions &targetopts, bool TimePasses, const std::string &infile, llvm::raw_ostream *OS, @@ -96,8 +98,8 @@ namespace { AsmOutStream(OS), LLVMIRGeneration("LLVM IR Generation Time"), CodeGenerationTime("Code Generation Time"), - Gen(CreateLLVMCodeGen(Diags, infile, compopts, C)), - TheTargetData(0), + Gen(CreateLLVMCodeGen(Diags, infile, compopts, machine, C)), + TheTargetData(0), TheTargetMachine(&machine), CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) { if (AsmOutStream) @@ -216,15 +218,6 @@ bool BackendConsumer::AddEmitPasses() { } else { bool Fast = CodeGenOpts.OptimizationLevel == 0; - // Create the TargetMachine for generating code. - std::string Error; - std::string Triple = TheModule->getTargetTriple(); - const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error); - if (!TheTarget) { - Diags.Report(diag::err_fe_unable_to_create_target) << Error; - return false; - } - // FIXME: Expose these capabilities via actual APIs!!!! Aside from just // being gross, this is also totally broken if we ever care about // concurrency. @@ -241,32 +234,6 @@ bool BackendConsumer::AddEmitPasses() { llvm::UseSoftFloat = CodeGenOpts.SoftFloat; UnwindTablesMandatory = CodeGenOpts.UnwindTables; - TargetMachine::setAsmVerbosityDefault(CodeGenOpts.AsmVerbose); - - // FIXME: Parse this earlier. - if (CodeGenOpts.RelocationModel == "static") { - TargetMachine::setRelocationModel(llvm::Reloc::Static); - } else if (CodeGenOpts.RelocationModel == "pic") { - TargetMachine::setRelocationModel(llvm::Reloc::PIC_); - } else { - assert(CodeGenOpts.RelocationModel == "dynamic-no-pic" && - "Invalid PIC model!"); - TargetMachine::setRelocationModel(llvm::Reloc::DynamicNoPIC); - } - // FIXME: Parse this earlier. - if (CodeGenOpts.CodeModel == "small") { - TargetMachine::setCodeModel(llvm::CodeModel::Small); - } else if (CodeGenOpts.CodeModel == "kernel") { - TargetMachine::setCodeModel(llvm::CodeModel::Kernel); - } else if (CodeGenOpts.CodeModel == "medium") { - TargetMachine::setCodeModel(llvm::CodeModel::Medium); - } else if (CodeGenOpts.CodeModel == "large") { - TargetMachine::setCodeModel(llvm::CodeModel::Large); - } else { - assert(CodeGenOpts.CodeModel.empty() && "Invalid code model!"); - TargetMachine::setCodeModel(llvm::CodeModel::Default); - } - std::vector<const char *> BackendArgs; BackendArgs.push_back("clang"); // Fake program name. if (!CodeGenOpts.DebugPass.empty()) { @@ -283,18 +250,6 @@ bool BackendConsumer::AddEmitPasses() { llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1, (char**) &BackendArgs[0]); - std::string FeaturesStr; - if (TargetOpts.CPU.size() || TargetOpts.Features.size()) { - SubtargetFeatures Features; - Features.setCPU(TargetOpts.CPU); - for (std::vector<std::string>::const_iterator - it = TargetOpts.Features.begin(), - ie = TargetOpts.Features.end(); it != ie; ++it) - Features.AddFeature(*it); - FeaturesStr = Features.getString(); - } - TargetMachine *TM = TheTarget->createTargetMachine(Triple, FeaturesStr); - // Set register scheduler & allocation policy. RegisterScheduler::setDefault(createDefaultScheduler); RegisterRegAlloc::setDefault(Fast ? createLocalRegisterAllocator : @@ -327,8 +282,8 @@ bool BackendConsumer::AddEmitPasses() { TargetMachine::CodeGenFileType CGFT = TargetMachine::CGFT_AssemblyFile; if (Action == Backend_EmitObj) CGFT = TargetMachine::CGFT_ObjectFile; - if (TM->addPassesToEmitFile(*PM, FormattedOutStream, CGFT, OptLevel, - DisableVerify)) { + if (TheTargetMachine->addPassesToEmitFile(*PM, FormattedOutStream, + CGFT, OptLevel, DisableVerify)) { Diags.Report(diag::err_fe_unable_to_interface_with_target); return false; } @@ -462,8 +417,65 @@ llvm::Module *CodeGenAction::takeModule() { return TheModule.take(); } +static llvm::TargetMachine *CreateTargetMachine(CompilerInstance &CI) { + const CodeGenOptions &CodeGenOpts = CI.getCodeGenOpts(); + const TargetOptions &TargetOpts = CI.getTargetOpts(); + + std::string Error; + std::string Triple = CI.getTarget().getTriple().getTriple(); + const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error); + if (!TheTarget) { + CI.getDiagnostics().Report(diag::err_fe_unable_to_create_target) << Error; + return 0; + } + + TargetMachine::setAsmVerbosityDefault(CodeGenOpts.AsmVerbose); + + // FIXME: Parse this earlier. + if (CodeGenOpts.RelocationModel == "static") { + TargetMachine::setRelocationModel(llvm::Reloc::Static); + } else if (CodeGenOpts.RelocationModel == "pic") { + TargetMachine::setRelocationModel(llvm::Reloc::PIC_); + } else { + assert(CodeGenOpts.RelocationModel == "dynamic-no-pic" && + "Invalid PIC model!"); + TargetMachine::setRelocationModel(llvm::Reloc::DynamicNoPIC); + } + + // FIXME: Parse this earlier. + if (CodeGenOpts.CodeModel == "small") { + TargetMachine::setCodeModel(llvm::CodeModel::Small); + } else if (CodeGenOpts.CodeModel == "kernel") { + TargetMachine::setCodeModel(llvm::CodeModel::Kernel); + } else if (CodeGenOpts.CodeModel == "medium") { + TargetMachine::setCodeModel(llvm::CodeModel::Medium); + } else if (CodeGenOpts.CodeModel == "large") { + TargetMachine::setCodeModel(llvm::CodeModel::Large); + } else { + assert(CodeGenOpts.CodeModel.empty() && "Invalid code model!"); + TargetMachine::setCodeModel(llvm::CodeModel::Default); + } + + std::string FeaturesStr; + if (TargetOpts.CPU.size() || TargetOpts.Features.size()) { + SubtargetFeatures Features; + Features.setCPU(TargetOpts.CPU); + for (std::vector<std::string>::const_iterator + it = TargetOpts.Features.begin(), + ie = TargetOpts.Features.end(); it != ie; ++it) + Features.AddFeature(*it); + FeaturesStr = Features.getString(); + } + + return TheTarget->createTargetMachine(Triple, FeaturesStr); +} + ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) { + llvm::OwningPtr<llvm::TargetMachine> TM(CreateTargetMachine(CI)); + if (!TM) + return 0; + BackendAction BA = static_cast<BackendAction>(Act); llvm::OwningPtr<llvm::raw_ostream> OS; switch (BA) { @@ -485,9 +497,15 @@ ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI, if (BA != Backend_EmitNothing && !OS) return 0; - return new BackendConsumer(BA, CI.getDiagnostics(), CI.getLangOpts(), - CI.getCodeGenOpts(), CI.getTargetOpts(), - CI.getFrontendOpts().ShowTimers, InFile, OS.take(), + return new BackendConsumer(BA, + CI.getDiagnostics(), + *TM.take(), + CI.getLangOpts(), + CI.getCodeGenOpts(), + CI.getTargetOpts(), + CI.getFrontendOpts().ShowTimers, + InFile, + OS.take(), CI.getLLVMContext()); } |