From a0462fe1ee21cd233259057c5b43e208dc15dd01 Mon Sep 17 00:00:00 2001 From: Dmitry Babokin Date: Fri, 12 Apr 2013 14:06:12 +0400 Subject: [PATCH] #469: Fix for multi-target compilation --- ispc.cpp | 12 ++++++++---- ispc.h | 19 +++++++++++-------- module.cpp | 28 ++++++++++++++++++++-------- 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/ispc.cpp b/ispc.cpp index 88952b17..63b66c9c 100644 --- a/ispc.cpp +++ b/ispc.cpp @@ -551,10 +551,9 @@ Target::GetTripleString() const { return triple.str(); } - const char * -Target::GetISAString() const { - switch (m_isa) { +Target::ISAToString(ISA isa) { + switch (isa) { case Target::SSE2: return "sse2"; case Target::SSE4: @@ -568,11 +567,16 @@ Target::GetISAString() const { case Target::GENERIC: return "generic"; default: - FATAL("Unhandled target in GetISAString()"); + FATAL("Unhandled target in ISAToString()"); } return ""; } +const char * +Target::GetISAString() const { + return ISAToString(m_isa); +} + static bool lGenericTypeLayoutIndeterminate(llvm::Type *type) { diff --git a/ispc.h b/ispc.h index fae5190c..8b385bf6 100644 --- a/ispc.h +++ b/ispc.h @@ -169,6 +169,14 @@ extern void DoAssertPos(SourcePos pos, const char *file, int line, const char *e */ class Target { public: + /** Enumerator giving the instruction sets that the compiler can + target. These should be ordered from "worse" to "better" in that + if a processor supports multiple target ISAs, then the most + flexible/performant of them will apear last in the enumerant. Note + also that __best_available_isa() needs to be updated if ISAs are + added or the enumerant values are reordered. */ + enum ISA { SSE2, SSE4, AVX, AVX11, AVX2, GENERIC, NUM_ISAS }; + /** Initializes the given Target pointer for a target of the given name, if the name is a known target. Returns true if the target was initialized and false if the name is unknown. */ @@ -194,6 +202,9 @@ public: target. */ llvm::TargetMachine *GetTargetMachine() const {return m_targetMachine;} + /** Convert ISA enum to string */ + static const char *ISAToString(Target::ISA isa); + /** Returns a string like "avx" encoding the target. */ const char *GetISAString() const; @@ -210,14 +221,6 @@ public: /** Mark LLVM function with target specific attribute, if required. */ void markFuncWithTargetAttr(llvm::Function* func); - /** Enumerator giving the instruction sets that the compiler can - target. These should be ordered from "worse" to "better" in that - if a processor supports multiple target ISAs, then the most - flexible/performant of them will apear last in the enumerant. Note - also that __best_available_isa() needs to be updated if ISAs are - added or the enumerant values are reordered. */ - enum ISA { SSE2, SSE4, AVX, AVX11, AVX2, GENERIC, NUM_ISAS }; - const llvm::Target *getTarget() const {return m_target;} // Note the same name of method for 3.1 and 3.2+, this allows diff --git a/module.cpp b/module.cpp index 490a7415..d323a56b 100644 --- a/module.cpp +++ b/module.cpp @@ -2405,21 +2405,29 @@ Module::CompileAndOutput(const char *srcFile, // we generate the dispatch module's functions... } - llvm::Module *dispatchModule = - lCreateDispatchModule(exportedFunctions); - - lAddExtractedGlobals(dispatchModule, globals); - // Find the first non-NULL target machine from the targets we // compiled to above. We'll use this as the target machine for // compiling the dispatch module--this is safe in that it is the // least-common-denominator of all of the targets we compiled to. - llvm::TargetMachine *firstTargetMachine = targetMachines[0]; - int i = 1; - while (i < Target::NUM_ISAS && firstTargetMachine == NULL) + llvm::TargetMachine *firstTargetMachine = NULL; + int i = 0; + const char *firstISA; + while (i < Target::NUM_ISAS && firstTargetMachine == NULL) { + firstISA = Target::ISAToString((Target::ISA) i); firstTargetMachine = targetMachines[i++]; + } Assert(firstTargetMachine != NULL); + g->target = new Target(arch, cpu, firstISA, generatePIC); + if (!g->target->isValid()) { + return 1; + } + + llvm::Module *dispatchModule = + lCreateDispatchModule(exportedFunctions); + + lAddExtractedGlobals(dispatchModule, globals); + if (outFileName != NULL) { if (outputType == Bitcode) writeBitcode(dispatchModule, outFileName); @@ -2428,6 +2436,10 @@ Module::CompileAndOutput(const char *srcFile, outputType, outFileName); } + delete g->target; + g->target = NULL; + + return errorCount > 0; } }