diff --git a/ispc.cpp b/ispc.cpp index 81fe9d53..88952b17 100644 --- a/ispc.cpp +++ b/ispc.cpp @@ -146,6 +146,11 @@ static const char *supportedCPUs[] = { Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) : m_target(NULL), m_targetMachine(NULL), +#if defined(LLVM_3_1) + m_targetData(NULL), +#else + m_dataLayout(NULL), +#endif m_valid(false), m_isa(SSE2), m_arch(""), @@ -443,16 +448,37 @@ Target::Target(const char *arch, const char *cpu, const char *isa, bool pic) : m_targetMachine->setAsmVerbosityDefault(true); - // Set is32Bit + // Initialize TargetData/DataLayout in 3 steps. + // 1. Get default data layout first + std::string dl_string; #if defined(LLVM_3_1) - const llvm::TargetData *targetData = m_targetMachine->getTargetData(); - this->m_is32Bit = (targetData->getPointerSize() == 4); + dl_string = m_targetMachine->getTargetData()->getStringRepresentation(); #else - int addressSpace = 0; - const llvm::DataLayout *dataLayout = m_targetMachine->getDataLayout(); - this->m_is32Bit = (dataLayout->getPointerSize(addressSpace) == 4); + dl_string = m_targetMachine->getDataLayout()->getStringRepresentation(); #endif + // 2. Adjust for generic + if (m_isa == Target::GENERIC) { + // <16 x i1> vectors only need 16 bit / 2 byte alignment, so add + // that to the regular datalayout string for IA.. + // For generic-4 target we need to treat <4 x i1> as 128 bit value + // in terms of required memory storage and alignment, as this is + // translated to __m128 type. + dl_string = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" + "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-" + "f80:128:128-n8:16:32:64-S128-v16:16:16-v32:32:32-v4:128:128"; + } + + // 3. Finally set member data +#if defined(LLVM_3_1) + m_targetData = new llvm::TargetData(dl_string); +#else + m_dataLayout = new llvm::DataLayout(dl_string); +#endif + + // Set is32Bit + this->m_is32Bit = (getDataLayout()->getPointerSize() == 4); + #if !defined(LLVM_3_1) && !defined(LLVM_3_2) // This is LLVM 3.3+ feature. // Initialize target-specific "target-feature" attribute. @@ -603,15 +629,7 @@ Target::SizeOf(llvm::Type *type, "sizeof_int", insertAtEnd); } -#if defined(LLVM_3_1) - const llvm::TargetData *td = GetTargetMachine()->getTargetData(); - Assert(td != NULL); - uint64_t bitSize = td->getTypeSizeInBits(type); -#else - const llvm::DataLayout *dl = GetTargetMachine()->getDataLayout(); - Assert(dl != NULL); - uint64_t bitSize = dl->getTypeSizeInBits(type); -#endif + uint64_t bitSize = getDataLayout()->getTypeSizeInBits(type); Assert((bitSize % 8) == 0); uint64_t byteSize = bitSize / 8; @@ -650,15 +668,7 @@ Target::StructOffset(llvm::Type *type, int element, return NULL; } -#if defined(LLVM_3_1) - const llvm::TargetData *td = GetTargetMachine()->getTargetData(); - Assert(td != NULL); - const llvm::StructLayout *sl = td->getStructLayout(structType); -#else - const llvm::DataLayout *dl = GetTargetMachine()->getDataLayout(); - Assert(dl != NULL); - const llvm::StructLayout *sl = dl->getStructLayout(structType); -#endif + const llvm::StructLayout *sl = getDataLayout()->getStructLayout(structType); Assert(sl != NULL); uint64_t offset = sl->getElementOffset(element); diff --git a/ispc.h b/ispc.h index 29a57c03..fae5190c 100644 --- a/ispc.h +++ b/ispc.h @@ -72,6 +72,11 @@ namespace llvm { class BasicBlock; class Constant; class ConstantValue; +#if defined(LLVM_3_1) + class TargetData; +#else + class DataLayout; +#endif class DIBuilder; class DIDescriptor; class DIFile; @@ -215,6 +220,14 @@ public: const llvm::Target *getTarget() const {return m_target;} + // Note the same name of method for 3.1 and 3.2+, this allows + // to reduce number ifdefs on client side. +#if defined(LLVM_3_1) + llvm::TargetData *getDataLayout() const {return m_targetData;} +#else + llvm::DataLayout *getDataLayout() const {return m_dataLayout;} +#endif + /** Reports if Target object has valid state. */ bool isValid() const {return m_valid;} @@ -261,6 +274,12 @@ private: */ llvm::TargetMachine *m_targetMachine; +#if defined(LLVM_3_1) + llvm::TargetData *m_targetData; +#else + llvm::DataLayout *m_dataLayout; +#endif + /** flag to report invalid state after construction (due to bad parameters passed to constructor). */ bool m_valid; diff --git a/module.cpp b/module.cpp index 67034a61..490a7415 100644 --- a/module.cpp +++ b/module.cpp @@ -257,14 +257,8 @@ Module::Module(const char *fn) { module = new llvm::Module(filename ? filename : "", *g->ctx); module->setTargetTriple(g->target->GetTripleString()); - if (g->target->getISA() == Target::GENERIC) { - // <16 x i1> vectors only need 16 bit / 2 byte alignment, so add - // that to the regular datalayout string for IA.. - std::string datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" - "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-" - "f80:128:128-n8:16:32:64-S128-v16:16:16-v32:32:32"; - module->setDataLayout(datalayout); - } + // DataLayout information supposed to be managed in single place in Target class. + module->setDataLayout(g->target->getDataLayout()->getStringRepresentation()); if (g->generateDebuggingSymbols) { diBuilder = new llvm::DIBuilder(*module); @@ -1060,15 +1054,9 @@ Module::writeObjectFileOrAssembly(llvm::TargetMachine *targetMachine, llvm::PassManager pm; #if defined(LLVM_3_1) - if (const llvm::TargetData *td = targetMachine->getTargetData()) - pm.add(new llvm::TargetData(*td)); - else - pm.add(new llvm::TargetData(module)); + pm.add(new llvm::TargetData(*g->target->getDataLayout())); #else - if (const llvm::DataLayout *dl = targetMachine->getDataLayout()) - pm.add(new llvm::DataLayout(*dl)); - else - pm.add(new llvm::DataLayout(module)); + pm.add(new llvm::DataLayout(*g->target->getDataLayout())); #endif llvm::formatted_raw_ostream fos(of->os()); diff --git a/opt.cpp b/opt.cpp index b01c412b..d230ff11 100644 --- a/opt.cpp +++ b/opt.cpp @@ -414,14 +414,13 @@ Optimize(llvm::Module *module, int optLevel) { new llvm::TargetLibraryInfo(llvm::Triple(module->getTargetTriple())); optPM.add(targetLibraryInfo); + #if defined(LLVM_3_1) - optPM.add(new llvm::TargetData(module)); + optPM.add(new llvm::TargetData(*g->target->getDataLayout())); #else + optPM.add(new llvm::DataLayout(*g->target->getDataLayout())); + llvm::TargetMachine *targetMachine = g->target->GetTargetMachine(); - if (const llvm::DataLayout *dl = targetMachine->getDataLayout()) - optPM.add(new llvm::DataLayout(*dl)); - else - optPM.add(new llvm::DataLayout(module)); #ifdef LLVM_3_2 optPM.add(new llvm::TargetTransformInfo(targetMachine->getScalarTargetTransformInfo(), targetMachine->getVectorTargetTransformInfo()));