From c936f8474558748d673f7492a5f525f7369a0635 Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Wed, 9 Mar 2016 19:59:13 +0100 Subject: [PATCH 1/9] ARM: More fixes to the test suite. --- tests/d2/dmd-testsuite | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/d2/dmd-testsuite b/tests/d2/dmd-testsuite index 4238acad39..4cc5f97930 160000 --- a/tests/d2/dmd-testsuite +++ b/tests/d2/dmd-testsuite @@ -1 +1 @@ -Subproject commit 4238acad391cc9642ecb6e45280389865b9feb7e +Subproject commit 4cc5f97930ce5ed9a23f9a2cc76df85bfac02749 From 5a56016d494e42b3b80c20eb1ad48755f6796e06 Mon Sep 17 00:00:00 2001 From: Johan Engelen Date: Mon, 7 Mar 2016 17:48:09 +0100 Subject: [PATCH 2/9] Fix #1344. Add `--version` to `ldmd2`. --- driver/ldmd.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/driver/ldmd.cpp b/driver/ldmd.cpp index a100d6614c..cb6b384049 100644 --- a/driver/ldmd.cpp +++ b/driver/ldmd.cpp @@ -214,6 +214,7 @@ Usage:\n\ -v verbose\n\ -vcolumns print character (column) numbers in diagnostics\n\ -vdmd print the command used to invoke the underlying compiler\n\ + --version print compiler version and exit\n\ -version=level compile in version code >= level\n\ -version=ident compile in version code identified by ident\n" #if 0 @@ -713,6 +714,11 @@ Params parseArgs(size_t originalArgc, char **originalArgv, } else if (strcmp(p + 1, "-help") == 0) { printUsage(originalArgv[0], ldcPath); exit(EXIT_SUCCESS); + } else if (strcmp(p + 1, "-version") == 0) { + // Print version information by actually invoking ldc -version. + const char *versionargs[] = {ldcPath.c_str(), "-version", nullptr}; + execute(ldcPath, versionargs); + exit(EXIT_SUCCESS); } else if (strcmp(p + 1, "-r") == 0) { result.hiddenDebugR = 1; } else if (strcmp(p + 1, "-x") == 0) { From 1af1d07cde58176e4c551fb41b69054c72e498e1 Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Sat, 12 Mar 2016 15:23:53 +0100 Subject: [PATCH 3/9] LLVM 3.9: Add new library globalisel --- CMakeLists.txt | 2 +- cmake/Modules/FindLLVM.cmake | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ecd0a4a26b..caad1dc1eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ include(CheckCXXCompilerFlag) # find_package(LLVM 3.5 REQUIRED - all-targets analysis asmparser asmprinter bitreader bitwriter codegen core debuginfocodeview debuginfodwarf debuginfopdb instcombine ipa ipo instrumentation irreader linker lto mc mcdisassembler mcparser objcarcopts object option profiledata scalaropts selectiondag support tablegen target transformutils vectorize ${EXTRA_LLVM_MODULES}) + all-targets analysis asmparser asmprinter bitreader bitwriter codegen core debuginfocodeview debuginfodwarf debuginfopdb globalisel instcombine ipa ipo instrumentation irreader linker lto mc mcdisassembler mcparser objcarcopts object option profiledata scalaropts selectiondag support tablegen target transformutils vectorize ${EXTRA_LLVM_MODULES}) math(EXPR LDC_LLVM_VER ${LLVM_VERSION_MAJOR}*100+${LLVM_VERSION_MINOR}) # Remove LLVMTableGen library from list of libraries string(REGEX MATCH "^-.*LLVMTableGen[^;]*;|;-.*LLVMTableGen[^;]*" LLVM_TABLEGEN_LIBRARY "${LLVM_LIBRARIES}") diff --git a/cmake/Modules/FindLLVM.cmake b/cmake/Modules/FindLLVM.cmake index cab447a349..1b9c372c1e 100644 --- a/cmake/Modules/FindLLVM.cmake +++ b/cmake/Modules/FindLLVM.cmake @@ -76,8 +76,9 @@ if ((WIN32 AND NOT(MINGW OR CYGWIN)) OR NOT LLVM_CONFIG) list(APPEND LLVM_FIND_COMPONENTS "debuginfo") endif() if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-8][\\.0-9A-Za-z]*") - # Versions below 3.9 do not support components debuginfocodeview + # Versions below 3.9 do not support components debuginfocodeview, globalisel list(REMOVE_ITEM LLVM_FIND_COMPONENTS "debuginfocodeview" index) + list(REMOVE_ITEM LLVM_FIND_COMPONENTS "globalisel" index) endif() if(${LLVM_VERSION_STRING} MATCHES "^3\\.[8-9][\\.0-9A-Za-z]*") # Versions beginning with 3.8 do not support component ipa @@ -155,8 +156,9 @@ else() list(APPEND LLVM_FIND_COMPONENTS "debuginfo") endif() if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-8][\\.0-9A-Za-z]*") - # Versions below 3.9 do not support components debuginfocodeview + # Versions below 3.9 do not support components debuginfocodeview, globalisel list(REMOVE_ITEM LLVM_FIND_COMPONENTS "debuginfocodeview" index) + list(REMOVE_ITEM LLVM_FIND_COMPONENTS "globalisel" index) endif() if(${LLVM_VERSION_STRING} MATCHES "^3\\.[8-9][\\.0-9A-Za-z]*") # Versions beginning with 3.8 do not support component ipa From 8391626dddb1650a4a3df68eef0f4cc99efe306a Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Sat, 12 Mar 2016 16:58:21 +0100 Subject: [PATCH 4/9] Remove PassNameParser (may be breaking some command lines!) This PR removes the command line option which adds the pass names as additional command line options. This code prevents compiling for AArch64 (since LLVM 3.7) and ARM (since LLVM 3.8). Recommendation on LLVM list was to use the PassNameParser only in test tools but not in a production compiler. --- gen/optimizer.cpp | 38 +------------------------------------- 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/gen/optimizer.cpp b/gen/optimizer.cpp index 48bf468afa..531bf54b74 100644 --- a/gen/optimizer.cpp +++ b/gen/optimizer.cpp @@ -40,12 +40,6 @@ extern llvm::TargetMachine *gTargetMachine; using namespace llvm; -// Allow the user to specify specific optimizations to run. -static cl::list - passList(cl::desc("Running specific optimizations:"), - cl::Hidden // to clean up --help output - ); - static cl::opt optimizeLevel( cl::desc("Setting the optimization level:"), cl::ZeroOrMore, cl::values( @@ -384,37 +378,7 @@ bool ldc_optimize_module(llvm::Module *M) { mpm.add(createStripSymbolsPass(true)); } - bool defaultsAdded = false; - // Create a new optimization pass for each one specified on the command line - for (unsigned i = 0; i < passList.size(); ++i) { - if (optimizeLevel && - optimizeLevel.getPosition() < passList.getPosition(i)) { - addOptimizationPasses(mpm, fpm, optLevel(), sizeLevel()); - defaultsAdded = true; - } - - const PassInfo *passInf = passList[i]; - Pass *pass = nullptr; - if (passInf->getNormalCtor()) { - pass = passInf->getNormalCtor()(); - } else { - const char *arg = passInf->getPassArgument(); // may return null - if (arg) { - error(Loc(), "Can't create pass '-%s' (%s)", arg, pass->getPassName()); - } else { - error(Loc(), "Can't create pass (%s)", pass->getPassName()); - } - llvm_unreachable("pass creation failed"); - } - if (pass) { - addPass(mpm, pass); - } - } - - // Add the default passes for the specified optimization level. - if (!defaultsAdded) { - addOptimizationPasses(mpm, fpm, optLevel(), sizeLevel()); - } + addOptimizationPasses(mpm, fpm, optLevel(), sizeLevel()); // Run per-function passes. fpm.doInitialization(); From 2ee4df2c9ba2fd544922fa071578a9a1994c20f9 Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Sat, 12 Mar 2016 20:43:51 +0000 Subject: [PATCH 5/9] Linux/PPC: Add errno constants. --- runtime/druntime | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/druntime b/runtime/druntime index 604394bb88..cc4e4de1ca 160000 --- a/runtime/druntime +++ b/runtime/druntime @@ -1 +1 @@ -Subproject commit 604394bb887a59cb70bb20e6919ef4f43d47ef50 +Subproject commit cc4e4de1cac0c35bcb2f802481068acbbf59c16e From 412aa04ef6e2217795bca6d9bab467a82a9d7366 Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Sat, 12 Mar 2016 20:44:19 +0000 Subject: [PATCH 6/9] Linux/AArch64: More ABI implementation. This is still not perfect but already fixes some test failures. --- gen/abi-aarch64.cpp | 85 +++++++++++++++++++++++++++++++++++++++------ gen/abi.cpp | 3 ++ 2 files changed, 78 insertions(+), 10 deletions(-) diff --git a/gen/abi-aarch64.cpp b/gen/abi-aarch64.cpp index 4c23198b91..c935075ae2 100644 --- a/gen/abi-aarch64.cpp +++ b/gen/abi-aarch64.cpp @@ -16,32 +16,97 @@ #include "gen/abi-generic.h" #include "gen/abi-aarch64.h" +namespace { + struct CompositeToArray64 : ABIRewrite { + LLValue *get(Type *dty, LLValue *v) override { + Logger::println("rewriting i64 array -> as %s", dty->toChars()); + LLValue *lval = DtoRawAlloca(v->getType(), 0); + DtoStore(v, lval); + + LLType *pTy = getPtrToType(DtoType(dty)); + return DtoLoad(DtoBitCast(lval, pTy), "get-result"); + } + + LLValue *put(DValue *dv) override { + Type *dty = dv->getType(); + Logger::println("rewriting %s -> as i64 array", dty->toChars()); + LLType *t = type(dty, nullptr); + return DtoLoad(DtoBitCast(dv->getRVal(), getPtrToType(t))); + } + + LLType *type(Type *t, LLType *) override { + // An i64 array that will hold Type 't' + size_t sz = (t->size() + 7) / 8; + return LLArrayType::get(LLIntegerType::get(gIR->context(), 64), sz); + } + }; +} + struct AArch64TargetABI : TargetABI { + HFAToArray hfaToArray; + CompositeToArray64 compositeToArray64; + IntegerRewrite integerRewrite; + bool returnInArg(TypeFunction *tf) override { if (tf->isref) { return false; } - // Return structs and static arrays on the stack. The latter is needed - // because otherwise LLVM tries to actually return the array in a number - // of physical registers, which leads, depending on the target, to - // either horrendous codegen or backend crashes. Type *rt = tf->next->toBasetype(); - return (rt->ty == Tstruct || rt->ty == Tsarray); + + // FIXME + if (tf->linkage == LINKd) + return rt->ty == Tsarray || rt->ty == Tstruct; + + return rt->ty == Tsarray || + (rt->ty == Tstruct && rt->size() > 4 && !isHFA((TypeStruct *)rt)); } - bool passByVal(Type *t) override { return t->toBasetype()->ty == Tstruct; } + bool passByVal(Type *t) override { + t = t->toBasetype(); + return ((t->ty == Tsarray || t->ty == Tstruct) && t->size() > 64); + } - void rewriteFunctionType(TypeFunction *t, IrFuncTy &fty) override { - for (auto arg : fty.args) { - if (!arg->byref) { - rewriteArgument(fty, *arg); + void rewriteFunctionType(TypeFunction *tf, IrFuncTy &fty) override { + Type *retTy = fty.ret->type->toBasetype(); + if (!fty.ret->byref && retTy->ty == Tstruct) { + // Rewrite HFAs only because union HFAs are turned into IR types that are + // non-HFA and messes up register selection + if (isHFA((TypeStruct *)retTy, &fty.ret->ltype)) { + fty.ret->rewrite = &hfaToArray; } + else { + fty.ret->rewrite = &integerRewrite; + fty.ret->ltype = integerRewrite.type(fty.ret->type, fty.ret->ltype); + } + } + + for (auto arg : fty.args) { + if (!arg->byref) + rewriteArgument(fty, *arg); + } + + // extern(D): reverse parameter order for non variadics, for DMD-compliance + if (tf->linkage == LINKd && tf->varargs != 1 && fty.args.size() > 1) { + fty.reverseParams = true; } } void rewriteArgument(IrFuncTy &fty, IrFuncTyArg &arg) override { // FIXME + Type *ty = arg.type->toBasetype(); + + if (ty->ty == Tstruct) { + // Rewrite HFAs only because union HFAs are turned into IR types that are + // non-HFA and messes up register selection + if (isHFA((TypeStruct *)ty, &arg.ltype)) { + arg.rewrite = &hfaToArray; + } + else { + arg.rewrite = &compositeToArray64; + arg.ltype = compositeToArray64.type(arg.type, arg.ltype); + } + } } /** diff --git a/gen/abi.cpp b/gen/abi.cpp index f815210df2..14589d609c 100644 --- a/gen/abi.cpp +++ b/gen/abi.cpp @@ -195,6 +195,9 @@ bool TargetABI::isHFA(TypeStruct *t, llvm::Type **rewriteType) { case 8: floatType = llvm::Type::getDoubleTy(gIR->context()); break; + case 16: + floatType = llvm::Type::getFP128Ty(gIR->context()); + break; default: llvm_unreachable("Unexpected size for float type"); } From 657df158ba111a88b547d00eb0d0bfc8ddc03cf7 Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Sun, 13 Mar 2016 01:54:16 +0000 Subject: [PATCH 7/9] Linux/AArch64: Better ABI implementation. --- gen/abi-aarch64.cpp | 7 +++++-- gen/abi-generic.h | 11 ++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/gen/abi-aarch64.cpp b/gen/abi-aarch64.cpp index c935075ae2..ed3ab3e5c6 100644 --- a/gen/abi-aarch64.cpp +++ b/gen/abi-aarch64.cpp @@ -59,12 +59,13 @@ struct AArch64TargetABI : TargetABI { return rt->ty == Tsarray || rt->ty == Tstruct; return rt->ty == Tsarray || - (rt->ty == Tstruct && rt->size() > 4 && !isHFA((TypeStruct *)rt)); + (rt->ty == Tstruct && rt->size() > 16 && !isHFA((TypeStruct *)rt)); } bool passByVal(Type *t) override { t = t->toBasetype(); - return ((t->ty == Tsarray || t->ty == Tstruct) && t->size() > 64); + return t->ty == Tsarray || + (t->ty == Tstruct && t->size() > 16 && !isHFA((TypeStruct *)t)); } void rewriteFunctionType(TypeFunction *tf, IrFuncTy &fty) override { @@ -74,6 +75,7 @@ struct AArch64TargetABI : TargetABI { // non-HFA and messes up register selection if (isHFA((TypeStruct *)retTy, &fty.ret->ltype)) { fty.ret->rewrite = &hfaToArray; + fty.ret->ltype = hfaToArray.type(fty.ret->type, fty.ret->ltype); } else { fty.ret->rewrite = &integerRewrite; @@ -101,6 +103,7 @@ struct AArch64TargetABI : TargetABI { // non-HFA and messes up register selection if (isHFA((TypeStruct *)ty, &arg.ltype)) { arg.rewrite = &hfaToArray; + arg.ltype = hfaToArray.type(arg.type, arg.ltype); } else { arg.rewrite = &compositeToArray64; diff --git a/gen/abi-generic.h b/gen/abi-generic.h index b3ff6983f7..17bacdbd37 100644 --- a/gen/abi-generic.h +++ b/gen/abi-generic.h @@ -119,7 +119,7 @@ struct RemoveStructPadding : ABIRewrite { */ struct IntegerRewrite : ABIRewrite { static LLType *getIntegerType(unsigned minSizeInBytes) { - if (minSizeInBytes > 8) { + if (minSizeInBytes > 16) { return nullptr; } @@ -136,6 +136,15 @@ struct IntegerRewrite : ABIRewrite { case 7: size = 8; break; + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + size = 16; + break; default: break; } From f7af985f7523dccfe30ef1b4cd0647941bf5aa0c Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Sun, 13 Mar 2016 13:24:28 +0000 Subject: [PATCH 8/9] Linux/PPC: Really fix the import for md.d/ripemd.d. --- runtime/phobos | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/phobos b/runtime/phobos index c35065c315..cf6c4a7497 160000 --- a/runtime/phobos +++ b/runtime/phobos @@ -1 +1 @@ -Subproject commit c35065c315f1c684b9ce76d464b2ee1b0040fd84 +Subproject commit cf6c4a74973b3001c2761d510e63408b84f3d3c5 From 7e03ee4587fbe5daba15ce9f3599bc94c91c0989 Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Sun, 13 Mar 2016 14:38:32 +0000 Subject: [PATCH 9/9] Linux/AArch64: More changes to ABI implementation. - Remove byval attribute - Do not reverse parameter list The latter point is required by the spec at http://dlang.org/spec/abi.html: "The extern (C) and extern (D) calling convention matches the C calling convention used by the supported C compiler on the host system." --- gen/abi-aarch64.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/gen/abi-aarch64.cpp b/gen/abi-aarch64.cpp index ed3ab3e5c6..4f81c8cdcb 100644 --- a/gen/abi-aarch64.cpp +++ b/gen/abi-aarch64.cpp @@ -86,11 +86,8 @@ struct AArch64TargetABI : TargetABI { for (auto arg : fty.args) { if (!arg->byref) rewriteArgument(fty, *arg); - } - - // extern(D): reverse parameter order for non variadics, for DMD-compliance - if (tf->linkage == LINKd && tf->varargs != 1 && fty.args.size() > 1) { - fty.reverseParams = true; + else if (passByVal(arg->type)) + arg->attrs.remove(LLAttribute::ByVal); } } @@ -98,10 +95,10 @@ struct AArch64TargetABI : TargetABI { // FIXME Type *ty = arg.type->toBasetype(); - if (ty->ty == Tstruct) { + if (ty->ty == Tstruct || ty->ty == Tsarray) { // Rewrite HFAs only because union HFAs are turned into IR types that are // non-HFA and messes up register selection - if (isHFA((TypeStruct *)ty, &arg.ltype)) { + if (ty->ty == Tstruct && isHFA((TypeStruct *)ty, &arg.ltype)) { arg.rewrite = &hfaToArray; arg.ltype = hfaToArray.type(arg.type, arg.ltype); }