зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
5fccd36204
Коммит
c9fe644675
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче