From c6750b34b7b219162171c48003d82926ec8b1496 Mon Sep 17 00:00:00 2001 From: Frits van Bommel Date: Wed, 24 Jun 2009 17:14:50 +0200 Subject: [PATCH 1/9] Don't initialize arrays of (arrays of...) void-initialized typedefs. --- gen/arrays.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/gen/arrays.cpp b/gen/arrays.cpp index 040b36ae..fc364228 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -397,6 +397,25 @@ LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr) return llvm::ConstantStruct::get(values, 2); } +////////////////////////////////////////////////////////////////////////////////////////// +static bool isInitialized(Type* et) { + // Strip array types from element type + Type* bt = et->toBasetype(); + while (bt->ty == Tsarray || bt->ty == Tarray) { + et = bt->nextOf(); + bt = et->toBasetype(); + } + // If it's a typedef with "= void" initializer then don't initialize. + if (et->ty == Ttypedef) { + Logger::println("Typedef: %s", et->toChars()); + TypedefDeclaration* tdd = ((TypeTypedef*)et)->sym; + if (tdd && tdd->init && tdd->init->isVoidInitializer()) + return false; + } + // Otherwise, it's always initialized. + return true; +} + ////////////////////////////////////////////////////////////////////////////////////////// DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool defaultInit) { @@ -411,7 +430,10 @@ DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool default LLValue* arrayLen = dim->getRVal(); // get runtime function - bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit(); + Type* eltType = arrayType->toBasetype()->nextOf(); + if (defaultInit && !isInitialized(eltType)) + defaultInit = false; + bool zeroInit = eltType->isZeroInit(); const char* fnname = defaultInit ? (zeroInit ? "_d_newarrayT" : "_d_newarrayiT") : "_d_newarrayvT"; LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, fnname); @@ -445,6 +467,8 @@ DSliceValue* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size // get runtime function bool zeroInit = vtype->isZeroInit(); + if (defaultInit && !isInitialized(vtype)) + defaultInit = false; const char* fnname = defaultInit ? (zeroInit ? "_d_newarraymT" : "_d_newarraymiT") : "_d_newarraymvT"; LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, fnname); From 8e8837737a8c1e88634a501092969c86faa0b2f9 Mon Sep 17 00:00:00 2001 From: Frits van Bommel Date: Wed, 24 Jun 2009 18:01:02 +0200 Subject: [PATCH 2/9] Be a little less overzealous with arrays of void-initialized typedefs; initialize `new VoidTD[][](2)` and `new VoidTD[][][](2, 3)` (but not `new VoidTD[2][3]`, which is a dynamic array of static arrays of void-initialized typedefs). --- gen/arrays.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gen/arrays.cpp b/gen/arrays.cpp index fc364228..eab6cc05 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -399,9 +399,9 @@ LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr) ////////////////////////////////////////////////////////////////////////////////////////// static bool isInitialized(Type* et) { - // Strip array types from element type + // Strip static array types from element type Type* bt = et->toBasetype(); - while (bt->ty == Tsarray || bt->ty == Tarray) { + while (bt->ty == Tsarray) { et = bt->nextOf(); bt = et->toBasetype(); } From 8bbf6ab984efd7b8b01264f504fb497c37a30ada Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Fri, 26 Jun 2009 17:18:36 +0200 Subject: [PATCH 3/9] Treat ConditionalDeclarations correctly in DtoDeclarationExp. Fixes #332. --- gen/llvmhelpers.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 502884b5..fa4da945 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -979,10 +979,12 @@ DValue* DtoDeclarationExp(Dsymbol* declaration) else if (AttribDeclaration* a = declaration->isAttribDeclaration()) { Logger::println("AttribDeclaration"); - if (a->decl) - for (int i=0; i < a->decl->dim; ++i) + // choose the right set in case this is a conditional declaration + Array *d = a->include(NULL, NULL); + if (d) + for (int i=0; i < d->dim; ++i) { - DtoDeclarationExp((Dsymbol*)a->decl->data[i]); + DtoDeclarationExp((Dsymbol*)d->data[i]); } } // mixin declaration From e0331c7b53e55012c901a932f6b837d5ef99ce4f Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Fri, 26 Jun 2009 21:00:12 +0200 Subject: [PATCH 4/9] Make debug info work with newer LLVM. --- gen/todebug.cpp | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/gen/todebug.cpp b/gen/todebug.cpp index da4c5ef8..7eff09d8 100644 --- a/gen/todebug.cpp +++ b/gen/todebug.cpp @@ -45,23 +45,6 @@ static LLGlobalVariable* emitDwarfGlobalDecl(const LLStructType* type, const cha ////////////////////////////////////////////////////////////////////////////////////////////////// -static llvm::DIAnchor getDwarfAnchor(dwarf_constants c) -{ - switch (c) - { - case DW_TAG_compile_unit: - return gIR->difactory.GetOrCreateCompileUnitAnchor(); - case DW_TAG_variable: - return gIR->difactory.GetOrCreateGlobalVariableAnchor(); - case DW_TAG_subprogram: - return gIR->difactory.GetOrCreateSubprogramAnchor(); - default: - assert(0); - } -} - -////////////////////////////////////////////////////////////////////////////////////////////////// - static const llvm::StructType* getDwarfCompileUnitType() { return isaStruct(gIR->module->getTypeByName("llvm.dbg.compile_unit.type")); } @@ -311,7 +294,11 @@ static llvm::DICompositeType dwarfCompositeType(Type* type, llvm::DICompileUnit // set to handle recursive types properly gv = emitDwarfGlobalDecl(getDwarfCompositeTypeType(), "llvm.dbg.compositetype"); // set bogus initializer to satisfy asserts in DICompositeType constructor - gv->setInitializer(LLConstant::getNullValue(getDwarfCompositeTypeType())); + std::vector initvals(11); + initvals[0] = DBG_TAG(DW_TAG_structure_type); + for (int i = 1; i < initvals.size(); ++i) + initvals[i] = LLConstant::getNullValue(getDwarfCompositeTypeType()->getContainedType(i)); + gv->setInitializer(LLConstantStruct::get(getDwarfCompositeTypeType(), initvals)); ir->diCompositeType = llvm::DICompositeType(gv); tag = DW_TAG_structure_type; From 88f6e9e83a380bc99db519cba31285d6b90664e2 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Fri, 26 Jun 2009 21:02:23 +0200 Subject: [PATCH 5/9] Initialize LLVM target and asmprinter for the native and extra targets. Uses some CMake hackery to get the native LLVM target name, since it only provides a conveniance function for initializing the native target and not the native asmprinter. --- CMakeLists.txt | 30 +++++++++++++++++++++++------- gen/main.cpp | 17 +++++++++++++++-- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f2757939..bc5a56b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,13 +54,6 @@ execute_process( OUTPUT_STRIP_TRAILING_WHITESPACE ) -set(EXTRA_LLVM_MODULES "" CACHE STRING "extra llvm components to link in (see llvm-config --components)") -execute_process( - COMMAND ${PERL_EXECUTABLE} ${LLVM_CONFIG} --libfiles bitwriter linker ipo instrumentation backend ${EXTRA_LLVM_MODULES} - OUTPUT_VARIABLE LLVM_LIBS - OUTPUT_STRIP_TRAILING_WHITESPACE -) - set(D_VERSION 1 CACHE STRING "D language version") set(PROGRAM_PREFIX CACHE STRING "prepended to ldc binary name") set(PROGRAM_SUFFIX CACHE STRING "appended to ldc binary name") @@ -135,6 +128,29 @@ set(DEFAULT_ALT_TARGET ${HOST_ALT_TARGET} CACHE STRING "default alt target") include_directories(. ${DMDFE_PATH} ${DMDFE_PATH}/root ${PROJECT_BINARY_DIR}/${DMDFE_PATH} ${PROJECT_BINARY_DIR} ${LLVM_INSTDIR}/include) +set(EXTRA_LLVM_MODULES "" CACHE STRING "extra llvm components to link in (see llvm-config --components)") +separate_arguments(EXTRA_LLVM_MODULES) +execute_process( + COMMAND ${PERL_EXECUTABLE} ${LLVM_CONFIG} --libfiles bitwriter linker ipo instrumentation backend ${EXTRA_LLVM_MODULES} + OUTPUT_VARIABLE LLVM_LIBS + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +# build a define that contains all LLVM targets required and is usable for +# preprocessor code generation. start with the native target. +file(STRINGS ${LLVM_INSTDIR}/include/llvm/Config/config.h LLVM_NATIVE_ARCH REGEX "^#define LLVM_NATIVE_ARCH") +string(REGEX REPLACE "^#define LLVM_NATIVE_ARCH (.*)Target$" "\\1" LLVM_NATIVE_ARCH ${LLVM_NATIVE_ARCH}) +set(LLVM_MODULES_DEFINE "LLVM_TARGET(${LLVM_NATIVE_ARCH})") +# chain the extra target list to the define +foreach(EXTRA_TARGET ${EXTRA_LLVM_MODULES}) + set(LLVM_MODULES_DEFINE "${LLVM_MODULES_DEFINE} LLVM_TARGET(${EXTRA_TARGET})") +endforeach(EXTRA_TARGET) +set_source_files_properties( + ${PROJECT_SOURCE_DIR}/gen/main.cpp PROPERTIES + COMPILE_DEFINITIONS LDC_TARGETS=${LLVM_MODULES_DEFINE} +) + + file(GLOB FE_SRC ${DMDFE_PATH}/*.c) file(GLOB FE_SRC_ROOT ${DMDFE_PATH}/root/*.c) file(GLOB_RECURSE GEN_SRC gen/*.cpp) diff --git a/gen/main.cpp b/gen/main.cpp index aa600f2c..5920d8a2 100644 --- a/gen/main.cpp +++ b/gen/main.cpp @@ -4,6 +4,7 @@ // which uses the llvm license #include "gen/llvm.h" +#include "gen/llvm-version.h" #include "llvm/LinkAllVMCore.h" #include "llvm/Linker.h" #include "llvm/System/Signals.h" @@ -11,6 +12,9 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetMachineRegistry.h" +#if LLVM_REV >= 73610 +#include "llvm/Target/TargetSelect.h" +#endif #include #include @@ -421,8 +425,17 @@ int main(int argc, char** argv) mod.setTargetTriple(global.params.targetTriple); - // Allocate target machine. First, check whether the user has - // explicitly specified an architecture to compile for. + // Allocate target machine. + + // first initialize llvm +#if LLVM_REV >= 73610 +#define LLVM_TARGET(A) LLVMInitialize##A##Target(); LLVMInitialize##A##AsmPrinter(); +// this is defined to be LLVM_TARGET(target name 1) LLVM_TARGET(target name 2) ... +LDC_TARGETS +#undef LLVM_TARGET +#endif + + // Check whether the user has explicitly specified an architecture to compile for. if (mArch == 0) { std::string Err; From 81e0b81e10a2dd8583b921c95e1a50154a619d9a Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Mon, 29 Jun 2009 21:44:11 +0200 Subject: [PATCH 6/9] LLVM_INSTDIR -> LLVM_INCLUDEDIR fix by d0k. --- CMakeLists.txt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bc5a56b0..1882502c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,11 @@ execute_process( OUTPUT_VARIABLE LLVM_LDFLAGS OUTPUT_STRIP_TRAILING_WHITESPACE ) +execute_process( + COMMAND ${PERL_EXECUTABLE} ${LLVM_CONFIG} --includedir + OUTPUT_VARIABLE LLVM_INCLUDEDIR + OUTPUT_STRIP_TRAILING_WHITESPACE +) set(D_VERSION 1 CACHE STRING "D language version") set(PROGRAM_PREFIX CACHE STRING "prepended to ldc binary name") @@ -126,7 +131,7 @@ set(LDC_GENERATED set(DEFAULT_TARGET ${HOST_TARGET} CACHE STRING "default target") set(DEFAULT_ALT_TARGET ${HOST_ALT_TARGET} CACHE STRING "default alt target") -include_directories(. ${DMDFE_PATH} ${DMDFE_PATH}/root ${PROJECT_BINARY_DIR}/${DMDFE_PATH} ${PROJECT_BINARY_DIR} ${LLVM_INSTDIR}/include) +include_directories(. ${DMDFE_PATH} ${DMDFE_PATH}/root ${PROJECT_BINARY_DIR}/${DMDFE_PATH} ${PROJECT_BINARY_DIR} ${LLVM_INCLUDEDIR}) set(EXTRA_LLVM_MODULES "" CACHE STRING "extra llvm components to link in (see llvm-config --components)") separate_arguments(EXTRA_LLVM_MODULES) @@ -138,7 +143,7 @@ execute_process( # build a define that contains all LLVM targets required and is usable for # preprocessor code generation. start with the native target. -file(STRINGS ${LLVM_INSTDIR}/include/llvm/Config/config.h LLVM_NATIVE_ARCH REGEX "^#define LLVM_NATIVE_ARCH") +file(STRINGS ${LLVM_INCLUDEDIR}/llvm/Config/config.h LLVM_NATIVE_ARCH REGEX "^#define LLVM_NATIVE_ARCH") string(REGEX REPLACE "^#define LLVM_NATIVE_ARCH (.*)Target$" "\\1" LLVM_NATIVE_ARCH ${LLVM_NATIVE_ARCH}) set(LLVM_MODULES_DEFINE "LLVM_TARGET(${LLVM_NATIVE_ARCH})") # chain the extra target list to the define From 151e266deb1eba48c81ec0d12f7ded9ebaa62ae1 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Tue, 30 Jun 2009 22:07:50 +0200 Subject: [PATCH 7/9] Yet another fix for finding llvm's config file. Since llvm-config --includedir sometimes includes the trailing llvm/ and sometimes it doesn't, we just check both directories. --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1882502c..3ea3142e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -143,7 +143,9 @@ execute_process( # build a define that contains all LLVM targets required and is usable for # preprocessor code generation. start with the native target. -file(STRINGS ${LLVM_INCLUDEDIR}/llvm/Config/config.h LLVM_NATIVE_ARCH REGEX "^#define LLVM_NATIVE_ARCH") +find_path(LLVM_CONFIG_FILE_PATH config.h PATHS ${LLVM_INCLUDEDIR}/llvm/Config ${LLVM_INCLUDEDIR}/Config NO_DEFAULT_PATH) +message(${LLVM_CONFIG_FILE_PATH}/config.h) +file(STRINGS ${LLVM_CONFIG_FILE_PATH}/config.h LLVM_NATIVE_ARCH REGEX "^#define LLVM_NATIVE_ARCH") string(REGEX REPLACE "^#define LLVM_NATIVE_ARCH (.*)Target$" "\\1" LLVM_NATIVE_ARCH ${LLVM_NATIVE_ARCH}) set(LLVM_MODULES_DEFINE "LLVM_TARGET(${LLVM_NATIVE_ARCH})") # chain the extra target list to the define From 22b36384b01e7e0fe26b86a08b379a739453b1e7 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Fri, 3 Jul 2009 17:24:35 +0200 Subject: [PATCH 8/9] Fix build for LLVM >= r74640 Some LLVM objects now take a 'Context' to make multi-threaded apps easier. Since we're not multi-threaded it's safe to use llvm::getGlobalContext() which gives us the same behavior as we had before. --- gen/main.cpp | 11 +++++++++++ gen/runtime.cpp | 8 ++++++++ gen/toobj.cpp | 9 ++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/gen/main.cpp b/gen/main.cpp index 5920d8a2..603c5eb9 100644 --- a/gen/main.cpp +++ b/gen/main.cpp @@ -7,6 +7,9 @@ #include "gen/llvm-version.h" #include "llvm/LinkAllVMCore.h" #include "llvm/Linker.h" +#if LLVM_REV >= 74640 +#include "llvm/LLVMContext.h" +#endif #include "llvm/System/Signals.h" #include "llvm/Target/SubtargetFeature.h" #include "llvm/Target/TargetMachine.h" @@ -399,7 +402,11 @@ int main(int argc, char** argv) if (global.errors) fatal(); +#if LLVM_REV >= 74640 + llvm::Module mod("dummy", llvm::getGlobalContext()); +#else llvm::Module mod("dummy"); +#endif // override triple if needed const char* defaultTriple = DEFAULT_TARGET_TRIPLE; @@ -919,7 +926,11 @@ LDC_TARGETS char* name = m->toChars(); char* filename = m->objfile->name->str; +#if LLVM_REV >= 74640 + llvm::Linker linker(name, name, llvm::getGlobalContext()); +#else llvm::Linker linker(name, name); +#endif std::string errormsg; for (int i = 0; i < llvmModules.size(); i++) { diff --git a/gen/runtime.cpp b/gen/runtime.cpp index bc9a8eb6..e5fe2079 100644 --- a/gen/runtime.cpp +++ b/gen/runtime.cpp @@ -1,4 +1,8 @@ #include "gen/llvm.h" +#include "gen/llvm-version.h" +#if LLVM_REV >= 74640 +#include "llvm/LLVMContext.h" +#endif #include "llvm/Module.h" #include "llvm/Attributes.h" #include "llvm/Bitcode/ReaderWriter.h" @@ -149,7 +153,11 @@ static const LLType* rt_dg2() static void LLVM_D_BuildRuntimeModule() { Logger::println("building module"); +#if LLVM_REV >= 74640 + M = new llvm::Module("ldc internal runtime", llvm::getGlobalContext()); +#else M = new llvm::Module("ldc internal runtime"); +#endif Logger::println("building basic types"); const LLType* voidTy = LLType::VoidTy; diff --git a/gen/toobj.cpp b/gen/toobj.cpp index 928093a5..a7f2286c 100644 --- a/gen/toobj.cpp +++ b/gen/toobj.cpp @@ -11,8 +11,12 @@ #include #include "gen/llvm.h" +#include "gen/llvm-version.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Bitcode/ReaderWriter.h" +#if LLVM_REV >= 74640 +#include "llvm/LLVMContext.h" +#endif #include "llvm/Module.h" #include "llvm/ModuleProvider.h" #include "llvm/PassManager.h" @@ -43,7 +47,6 @@ #include "gen/functions.h" #include "gen/irstate.h" #include "gen/llvmhelpers.h" -#include "gen/llvm-version.h" #include "gen/logger.h" #include "gen/optimizer.h" #include "gen/programs.h" @@ -94,7 +97,11 @@ llvm::Module* Module::genLLVMModule(Ir* sir) // create a new ir state // TODO look at making the instance static and moving most functionality into IrModule where it belongs +#if LLVM_REV >= 74640 + IRState ir(new llvm::Module(mname, llvm::getGlobalContext())); +#else IRState ir(new llvm::Module(mname)); +#endif gIR = &ir; ir.dmodule = this; From feaefc3314dcc57f4fe17ea7ed13400e26444c19 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Fri, 3 Jul 2009 18:49:42 +0200 Subject: [PATCH 9/9] Better error handling for CMake LLVM config file detection. --- CMakeLists.txt | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ea3142e..d99d5f1b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -144,10 +144,18 @@ execute_process( # build a define that contains all LLVM targets required and is usable for # preprocessor code generation. start with the native target. find_path(LLVM_CONFIG_FILE_PATH config.h PATHS ${LLVM_INCLUDEDIR}/llvm/Config ${LLVM_INCLUDEDIR}/Config NO_DEFAULT_PATH) -message(${LLVM_CONFIG_FILE_PATH}/config.h) -file(STRINGS ${LLVM_CONFIG_FILE_PATH}/config.h LLVM_NATIVE_ARCH REGEX "^#define LLVM_NATIVE_ARCH") -string(REGEX REPLACE "^#define LLVM_NATIVE_ARCH (.*)Target$" "\\1" LLVM_NATIVE_ARCH ${LLVM_NATIVE_ARCH}) -set(LLVM_MODULES_DEFINE "LLVM_TARGET(${LLVM_NATIVE_ARCH})") +if(LLVM_CONFIG_FILE_PATH STREQUAL "LLVM_CONFIG_FILE_PATH-NOTFOUND") + message("Couldn't find your llvm Config.h file in ${LLVM_INCLUDEDIR}, no native target will be initialized.") +else(LLVM_CONFIG_FILE_PATH STREQUAL "LLVM_CONFIG_FILE_PATH-NOTFOUND") + file(STRINGS ${LLVM_CONFIG_FILE_PATH}/config.h LLVM_NATIVE_ARCH REGEX "^#define LLVM_NATIVE_ARCH") + if(LLVM_NATIVE_ARCH) + string(REGEX REPLACE "^#define LLVM_NATIVE_ARCH (.*)Target$" "\\1" LLVM_NATIVE_ARCH ${LLVM_NATIVE_ARCH}) + message("Found native target ${LLVM_NATIVE_ARCH}") + set(LLVM_MODULES_DEFINE "LLVM_TARGET(${LLVM_NATIVE_ARCH})") + else(LLVM_NATIVE_ARCH) + message("Couldn't find the LLVM_NATIVE_ARCH define in ${LLVM_CONFIG_FILE_PATH}/config.h. Probably you have an older LLVM and can ignore this warning.") + endif(LLVM_NATIVE_ARCH) +endif(LLVM_CONFIG_FILE_PATH STREQUAL "LLVM_CONFIG_FILE_PATH-NOTFOUND") # chain the extra target list to the define foreach(EXTRA_TARGET ${EXTRA_LLVM_MODULES}) set(LLVM_MODULES_DEFINE "${LLVM_MODULES_DEFINE} LLVM_TARGET(${EXTRA_TARGET})")