diff --git a/ispc.cpp b/ispc.cpp index cd217a97..f0810c85 100644 --- a/ispc.cpp +++ b/ispc.cpp @@ -72,7 +72,7 @@ Module *m; bool Target::GetTarget(const char *arch, const char *cpu, const char *isa, - Target *t) { + bool pic, Target *t) { if (cpu == NULL) { std::string hostCPU = llvm::sys::getHostCPUName(); if (hostCPU.size() > 0) @@ -100,6 +100,8 @@ Target::GetTarget(const char *arch, const char *cpu, const char *isa, bool error = false; + t->generatePIC = pic; + // Make sure the target architecture is a known one; print an error // with the valid ones otherwise. t->target = NULL; @@ -228,14 +230,17 @@ llvm::TargetMachine * Target::GetTargetMachine() const { std::string triple = GetTripleString(); + llvm::Reloc::Model relocModel = generatePIC ? llvm::Reloc::PIC_ : + llvm::Reloc::Default; #if defined(LLVM_3_0svn) || defined(LLVM_3_0) std::string featuresString = attributes; llvm::TargetMachine *targetMachine = - target->createTargetMachine(triple, cpu, featuresString); + target->createTargetMachine(triple, cpu, featuresString, relocModel); #else std::string featuresString = cpu + std::string(",") + attributes; llvm::TargetMachine *targetMachine = target->createTargetMachine(triple, featuresString); + targetMachine->setRelocationModel(relocModel); #endif assert(targetMachine != NULL); diff --git a/ispc.h b/ispc.h index 0cbc9b3a..ae249e70 100644 --- a/ispc.h +++ b/ispc.h @@ -162,7 +162,7 @@ struct Target { name, if the name is a known target. Returns true if the target was initialized and false if the name is unknown. */ static bool GetTarget(const char *arch, const char *cpu, const char *isa, - Target *); + bool pic, Target *); /** Returns a comma-delimited string giving the names of the currently supported target ISAs. */ @@ -215,8 +215,12 @@ struct Target { integer multiple of the native vector width, for example if we're "doubling up" and compiling 8-wide on a 4-wide SSE system. */ int vectorWidth; + + /** Indicates whether position independent code should be generated. */ + bool generatePIC; }; + /** @brief Structure that collects optimization options This structure collects all of the options related to optimization of diff --git a/main.cpp b/main.cpp index aa8cce82..70fdc0db 100644 --- a/main.cpp +++ b/main.cpp @@ -98,6 +98,7 @@ static void usage(int ret) { printf(" disable-uniform-memory-optimizations\tDisable uniform-based coherent memory access\n"); printf(" disable-masked-store-optimizations\tDisable lowering to regular stores when possible\n"); #endif + printf(" [--pic]\t\t\t\tGenerate position-independent code\n"); printf(" [--target=]\t\t\tSelect target ISA. ={%s}\n", Target::SupportedTargetISAs()); printf(" [--version]\t\t\t\tPrint ispc version\n"); printf(" [--woff]\t\t\t\tDisable warnings\n"); @@ -184,8 +185,9 @@ int main(int Argc, char *Argv[]) { bool debugSet = false, optSet = false; Module::OutputType ot = Module::Object; - + bool generatePIC = false; const char *arch = NULL, *cpu = NULL, *target = NULL; + for (int i = 1; i < argc; ++i) { if (!strcmp(argv[i], "--help")) usage(0); @@ -286,6 +288,8 @@ int main(int Argc, char *Argv[]) { g->includeStdlib = false; else if (!strcmp(argv[i], "--nocpp")) g->runCPP = false; + else if (!strcmp(argv[i], "--pic")) + generatePIC = true; else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { printf("Intel(r) SPMD Program Compiler (ispc) build %s (%s)\n", BUILD_DATE, BUILD_VERSION); @@ -307,7 +311,7 @@ int main(int Argc, char *Argv[]) { if (debugSet && !optSet) g->opt.level = 0; - if (!Target::GetTarget(arch, cpu, target, &g->target)) + if (!Target::GetTarget(arch, cpu, target, generatePIC, &g->target)) usage(1); m = new Module(file);