Merge pull request #471 from dbabokin/multi_targets

#469: Fix for multi-target compilation
This commit is contained in:
jbrodman
2013-04-12 07:58:05 -07:00
3 changed files with 39 additions and 20 deletions

View File

@@ -551,10 +551,9 @@ Target::GetTripleString() const {
return triple.str(); return triple.str();
} }
const char * const char *
Target::GetISAString() const { Target::ISAToString(ISA isa) {
switch (m_isa) { switch (isa) {
case Target::SSE2: case Target::SSE2:
return "sse2"; return "sse2";
case Target::SSE4: case Target::SSE4:
@@ -568,11 +567,16 @@ Target::GetISAString() const {
case Target::GENERIC: case Target::GENERIC:
return "generic"; return "generic";
default: default:
FATAL("Unhandled target in GetISAString()"); FATAL("Unhandled target in ISAToString()");
} }
return ""; return "";
} }
const char *
Target::GetISAString() const {
return ISAToString(m_isa);
}
static bool static bool
lGenericTypeLayoutIndeterminate(llvm::Type *type) { lGenericTypeLayoutIndeterminate(llvm::Type *type) {

19
ispc.h
View File

@@ -169,6 +169,14 @@ extern void DoAssertPos(SourcePos pos, const char *file, int line, const char *e
*/ */
class Target { class Target {
public: 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 /** Initializes the given Target pointer for a target of the given
name, if the name is a known target. Returns true if the name, if the name is a known target. Returns true if the
target was initialized and false if the name is unknown. */ target was initialized and false if the name is unknown. */
@@ -194,6 +202,9 @@ public:
target. */ target. */
llvm::TargetMachine *GetTargetMachine() const {return m_targetMachine;} 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. */ /** Returns a string like "avx" encoding the target. */
const char *GetISAString() const; const char *GetISAString() const;
@@ -210,14 +221,6 @@ public:
/** Mark LLVM function with target specific attribute, if required. */ /** Mark LLVM function with target specific attribute, if required. */
void markFuncWithTargetAttr(llvm::Function* func); 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;} const llvm::Target *getTarget() const {return m_target;}
// Note the same name of method for 3.1 and 3.2+, this allows // Note the same name of method for 3.1 and 3.2+, this allows

View File

@@ -2405,21 +2405,29 @@ Module::CompileAndOutput(const char *srcFile,
// we generate the dispatch module's functions... // 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 // Find the first non-NULL target machine from the targets we
// compiled to above. We'll use this as the target machine for // compiled to above. We'll use this as the target machine for
// compiling the dispatch module--this is safe in that it is the // compiling the dispatch module--this is safe in that it is the
// least-common-denominator of all of the targets we compiled to. // least-common-denominator of all of the targets we compiled to.
llvm::TargetMachine *firstTargetMachine = targetMachines[0]; llvm::TargetMachine *firstTargetMachine = NULL;
int i = 1; int i = 0;
while (i < Target::NUM_ISAS && firstTargetMachine == NULL) const char *firstISA;
while (i < Target::NUM_ISAS && firstTargetMachine == NULL) {
firstISA = Target::ISAToString((Target::ISA) i);
firstTargetMachine = targetMachines[i++]; firstTargetMachine = targetMachines[i++];
}
Assert(firstTargetMachine != NULL); 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 (outFileName != NULL) {
if (outputType == Bitcode) if (outputType == Bitcode)
writeBitcode(dispatchModule, outFileName); writeBitcode(dispatchModule, outFileName);
@@ -2428,6 +2436,10 @@ Module::CompileAndOutput(const char *srcFile,
outputType, outFileName); outputType, outFileName);
} }
delete g->target;
g->target = NULL;
return errorCount > 0; return errorCount > 0;
} }
} }