Merge branch 'master' into merge-2.068

druntime/phobos/dmd-testsuite not yet merged
This commit is contained in:
David Nadlinger 2015-09-13 18:17:23 +02:00
commit f9e8f0d09a
22 changed files with 358 additions and 47 deletions

View file

@ -6,6 +6,7 @@ addons:
- llvm-toolchain-precise - llvm-toolchain-precise
- llvm-toolchain-precise-3.5 - llvm-toolchain-precise-3.5
- llvm-toolchain-precise-3.6 - llvm-toolchain-precise-3.6
- llvm-toolchain-precise-3.7
- ubuntu-toolchain-r-test - ubuntu-toolchain-r-test
packages: packages:
- libconfig++8-dev - libconfig++8-dev
@ -13,7 +14,10 @@ addons:
- g++-4.9 - g++-4.9
- gcc-4.9-multilib - gcc-4.9-multilib
- g++-4.9-multilib - g++-4.9-multilib
- gcc-multilib
- g++-multilib
- linux-libc-dev:i386 - linux-libc-dev:i386
- libcurl3:i386
- libedit2 - libedit2
- libedit-dev - libedit-dev
- llvm-3.1 - llvm-3.1
@ -28,6 +32,8 @@ addons:
- llvm-3.5-dev - llvm-3.5-dev
- llvm-3.6 - llvm-3.6
- llvm-3.6-dev - llvm-3.6-dev
- llvm-3.7
- llvm-3.7-dev
install: install:
- if [[ "${LLVM_CONFIG}" == *3\.[567]* ]]; then export CC="gcc-4.9"; export CXX="g++-4.9"; fi - if [[ "${LLVM_CONFIG}" == *3\.[567]* ]]; then export CC="gcc-4.9"; export CXX="g++-4.9"; fi
env: env:
@ -40,7 +46,7 @@ env:
- LLVM_CONFIG="llvm-config-3.1" - LLVM_CONFIG="llvm-config-3.1"
matrix: matrix:
allow_failures: allow_failures:
- env: LLVM_CONFIG="llvm-config-3.7" - env: LLVM_CONFIG="llvm-config-3.8"
script: script:
- cmake -DLLVM_CONFIG=$(which ${LLVM_CONFIG}) $OPTS . - cmake -DLLVM_CONFIG=$(which ${LLVM_CONFIG}) $OPTS .
- make -j3 - make -j3
@ -49,8 +55,8 @@ script:
- bin/ldc2 -version || exit 1 - bin/ldc2 -version || exit 1
- MAKEOPTS=-j2 ctest -j1 --verbose -R "build-phobos2-" -E "-test-runner" - MAKEOPTS=-j2 ctest -j1 --verbose -R "build-phobos2-" -E "-test-runner"
- ctest -j3 --verbose -R "(build-)" -E "(build-phobos2-|-test-runner)" - ctest -j3 --verbose -R "(build-)" -E "(build-phobos2-|-test-runner)"
- MAKEOPTS=-j4 ctest -j1 --verbose -R "dmd-testsuite" -E "-debug" - CC="" MAKEOPTS=-j4 ctest -j1 --verbose -R "dmd-testsuite" -E "-debug"
- MAKEOPTS=-j4 ctest -j1 --verbose -R "dmd-testsuite-debug" - CC="" MAKEOPTS=-j4 ctest -j1 --verbose -R "dmd-testsuite-debug"
- ctest -j4 --output-on-failure -E "dmd-testsuite" - ctest -j4 --output-on-failure -E "dmd-testsuite"
after_success: after_success:

141
appveyor.yml Normal file
View file

@ -0,0 +1,141 @@
#---------------------------------#
# general configuration #
#---------------------------------#
#version: 1.0.{build}-{branch}
branches:
only:
- merge-2.067
# Do not build on tags (GitHub only)
skip_tags: true
#---------------------------------#
# environment configuration #
#---------------------------------#
# Operating system (build VM template)
os: Visual Studio 2015
environment:
matrix:
- APPVEYOR_JOB_CONFIG: Debug
- APPVEYOR_JOB_CONFIG: Release
matrix:
allow_failures:
- APPVEYOR_JOB_CONFIG: Release
# scripts that are called at very beginning, before repo cloning
init:
- git config --global core.autocrlf input
- '"c:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64'
- msbuild /version
- cl
- cmake --version
- python --version
# scripts that run after cloning repository
install:
- cd c:\projects
# Fetch submodules
- cd ldc
- git submodule update --init --recursive
- cd ..
# Clone libconfig
- git clone https://github.com/hyperrealm/libconfig.git libconfig
## Download & extract LLVM source
#- ps: Start-FileDownload 'http://llvm.org/pre-releases/3.7.0/rc3/llvm-3.7.0rc3.src.tar.xz' -FileName 'llvm.src.tar.xz'
#- 7z x llvm.src.tar.xz -so | 7z x -si -ttar > nul
#- ren llvm-3.7.0rc3.src llvm
# Download a pre-built LLVM & extract
# LLVM RelWithDebInfo: https://dl.dropboxusercontent.com/s/s1tk6134mku3ei8/llvm-x64-debuginfo.7z?dl=0
- ps: Start-FileDownload 'https://dl.dropboxusercontent.com/s/5cok3dvmohtduy6/llvm-x64-release.7z?dl=0' -FileName 'llvm-x64.7z'
- md llvm-x64
- cd llvm-x64
- 7z x ..\llvm-x64.7z > nul
- cd ..
# Download & install Ninja
- ps: Start-FileDownload 'https://github.com/martine/ninja/releases/download/v1.6.0/ninja-win.zip' -FileName 'ninja.zip'
- md ninja
- cd ninja
- 7z x ..\ninja.zip > nul
- cd ..
- set PATH=c:\projects\ninja;%PATH%
- ninja --version
# Download & extract libcurl
- ps: Start-FileDownload 'http://d.darktech.org/libcurl-7.43.0-WinSSL-zlib-x86-x64.zip' -FileName 'libcurl.zip'
- md libcurl
- cd libcurl
- 7z x ..\libcurl.zip > nul
- cd ..
# Copy libcurl.dll to final LDC installation directory and add to PATH
- md ldc-x64
- md ldc-x64\bin
- copy libcurl\dmd2\windows\bin64\libcurl.dll ldc-x64\bin
- set PATH=c:\projects\ldc-x64\bin;%PATH%
#---------------------------------#
# build configuration #
#---------------------------------#
before_build:
- cd c:\projects
# Build libconfig
- msbuild libconfig\lib\libconfig.vcxproj /p:Configuration=ReleaseStatic /p:Platform=x64
## Generate build files for LLVM, build & install
#- md ninja-llvm
#- cd ninja-llvm
#- cmake -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=c:\projects\llvm-x64 -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_APPEND_VC_REV=ON ..\llvm
#- ninja install
build_script:
- cd c:\projects
# Work around LDC issue #988 and add a lib required in combination with VS 2015
- ps: (gc ldc\ldc2.conf.in).replace('@ADDITIONAL_DEFAULT_LDC_SWITCHES@', ', "-L/FORCE:MULTIPLE", "-Llegacy_stdio_definitions.lib"@ADDITIONAL_DEFAULT_LDC_SWITCHES@') | sc ldc\ldc2.conf.in
- ps: (gc ldc\ldc2_install.conf.in).replace('@ADDITIONAL_DEFAULT_LDC_SWITCHES@', ', "-L/FORCE:MULTIPLE", "-Llegacy_stdio_definitions.lib"@ADDITIONAL_DEFAULT_LDC_SWITCHES@') | sc ldc\ldc2_install.conf.in
- ps: (gc ldc\ldc2_phobos.conf.in).replace('@ADDITIONAL_DEFAULT_LDC_SWITCHES@', ', "-L/FORCE:MULTIPLE", "-Llegacy_stdio_definitions.lib"@ADDITIONAL_DEFAULT_LDC_SWITCHES@') | sc ldc\ldc2_phobos.conf.in
# Generate build files for LDC
- md ninja-ldc
- cd ninja-ldc
- cmake -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=c:\projects\ldc-x64 -DLLVM_ROOT_DIR=c:/projects/llvm-x64 -DLIBCONFIG_INCLUDE_DIR=c:/projects/libconfig/lib -DLIBCONFIG_LIBRARY=c:/projects/libconfig/lib/x64/ReleaseStatic/libconfig.lib ..\ldc
# Work around LDC issue #930
- ps: (gc build.ninja).replace('runtime/std/string-unittest-debug.obj -w -d -g -unittest', 'runtime/std/string-unittest-debug.obj -w -d -unittest') | sc build.ninja
# Build LDC, druntime and phobos
- ninja -j2
after_build:
# Debug job: install LDC, compress & publish as artifact
- ps: |
If ($Env:APPVEYOR_JOB_CONFIG -eq 'Debug') {
echo 'Preparing artifact...'
cd c:\projects\ninja-ldc
ninja install
cd ..\ldc-x64
7z a ..\ldc-x64.7z * > $null
cd ..
Push-AppveyorArtifact ldc-x64.7z
}
#---------------------------------#
# test configuration #
#---------------------------------#
test_script:
- cd c:\projects\ninja-ldc
- bin\ldc2 -version
# Compile, link & execute a hello-world program
- ps: 'echo "import std.stdio; void main() { writeln(""Hello world!""); }" > hello.d'
- if "%APPVEYOR_JOB_CONFIG%"=="Debug" ( bin\ldc2 -g hello.d ) else ( bin\ldc2 hello.d )
- hello.exe
# Compile the druntime & phobos unit tests
- set TEST_SUFFIX=unittest
- if "%APPVEYOR_JOB_CONFIG%"=="Debug" ( set TEST_SUFFIX=unittest-debug)
# pre-build some modules serially - those known to require lots of memory
- ninja -j1 runtime\std\algorithm\searching-%TEST_SUFFIX%.obj runtime\std\algorithm\setops-%TEST_SUFFIX%.obj runtime\std\array-%TEST_SUFFIX%.obj runtime\std\conv-%TEST_SUFFIX%.obj runtime\std\datetime-%TEST_SUFFIX%.obj runtime\std\range\package-%TEST_SUFFIX%.obj runtime\std\range\primitives-%TEST_SUFFIX%.obj runtime\std\regex\internal\tests-%TEST_SUFFIX%.obj runtime\std\string-%TEST_SUFFIX%.obj runtime\std\traits-%TEST_SUFFIX%.obj
- ninja -j2 druntime-ldc-%TEST_SUFFIX% phobos2-ldc-%TEST_SUFFIX%
# Execute the unit tests; exclude dmd-testsuite for now
- set CTEST_SUFFIX=-E "-debug|testsuite"
- if "%APPVEYOR_JOB_CONFIG%"=="Debug" ( set CTEST_SUFFIX=-R -debug -E testsuite)
- ctest --output-on-failure %CTEST_SUFFIX%

View file

@ -453,8 +453,11 @@ void createStaticLibrary()
else else
libName = "a.out"; libName = "a.out";
} }
if (!FileName::absolute(libName.c_str())) // KN: The following lines were added to fix a test case failure (runnable/test13774.sh).
libName = FileName::combine(global.params.objdir, libName.c_str()); // Root cause is that dmd handles it in this why.
// As a side effect this change broke compiling with dub.
// if (!FileName::absolute(libName.c_str()))
// libName = FileName::combine(global.params.objdir, libName.c_str());
std::string libExt = std::string(".") + global.lib_ext; std::string libExt = std::string(".") + global.lib_ext;
if (!endsWith(libName, libExt)) if (!endsWith(libName, libExt))
libName.append(libExt); libName.append(libExt);

View file

@ -464,6 +464,24 @@ llvm::TargetMachine* createTargetMachine(
// to default to "generic"). // to default to "generic").
cpu = getTargetCPU(cpu, triple); cpu = getTargetCPU(cpu, triple);
// cmpxchg16b is not available on old 64bit CPUs. Enable code generation
// if the user did not make an explicit choice.
if (cpu == "x86-64")
{
#if LDC_LLVM_VER >= 304
const char* cx16_plus = "+cx16";
const char* cx16_minus = "-cx16";
#else
const char* cx16_plus = "+cmpxchg16b";
const char* cx16_minus = "-cmpxchg16b";
#endif
bool cx16 = false;
for (unsigned i = 0; i < attrs.size(); ++i)
if (attrs[i] == cx16_plus || attrs[i] == cx16_minus) cx16 = true;
if (!cx16)
features.AddFeature(cx16_plus);
}
if (Logger::enabled()) if (Logger::enabled())
{ {
Logger::println("Targeting '%s' (CPU '%s' with features '%s')", Logger::println("Targeting '%s' (CPU '%s' with features '%s')",

View file

@ -22,8 +22,14 @@
struct X86TargetABI : TargetABI struct X86TargetABI : TargetABI
{ {
const bool isOSX;
IntegerRewrite integerRewrite; IntegerRewrite integerRewrite;
X86TargetABI()
: isOSX(global.params.isOSX)
{
}
llvm::CallingConv::ID callingConv(llvm::FunctionType* ft, LINK l) llvm::CallingConv::ID callingConv(llvm::FunctionType* ft, LINK l)
{ {
switch (l) switch (l)
@ -64,6 +70,22 @@ struct X86TargetABI : TargetABI
} }
} }
bool returnOSXStructInArg(TypeStruct* t)
{
// https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/LowLevelABI/Mac_OS_X_ABI_Function_Calls.pdf
//
// OS X variation on IA-32 for returning structs, page 57 section on
// Returning Results:
// "Structures 1 or 2 bytes in size are placed in EAX. Structures 4
// or 8 bytes in size are placed in: EAX and EDX. Structures of
// other sizes are placed at the address supplied by the caller."
// Non-POD structs (non-C compatible) should always be returned in an
// arg though (yes, sometimes extern(C) functions return these, but C
// code does not handle struct lifecycle).
size_t sz = t->Type::size();
return !t->sym->isPOD() || (sz != 1 && sz != 2 && sz != 4 && sz != 8);
}
bool returnInArg(TypeFunction* tf) bool returnInArg(TypeFunction* tf)
{ {
if (tf->isref) if (tf->isref)
@ -78,9 +100,15 @@ struct X86TargetABI : TargetABI
; ;
} }
// other ABI's follow C, which is cdouble and creal returned on the stack // other ABI's follow C, which is cdouble and creal returned on the stack
// as well as structs // as well as structs (except for some OSX cases).
else else
return (rt->ty == Tstruct || rt->ty == Tcomplex64 || rt->ty == Tcomplex80); {
if (rt->ty == Tstruct)
{
return !isOSX || returnOSXStructInArg((TypeStruct*)rt);
}
return (rt->ty == Tsarray || rt->ty == Tcomplex64 || rt->ty == Tcomplex80);
}
} }
bool passByVal(Type* t) bool passByVal(Type* t)
@ -171,7 +199,19 @@ struct X86TargetABI : TargetABI
fty.ret->rewrite = &integerRewrite; fty.ret->rewrite = &integerRewrite;
fty.ret->ltype = integerRewrite.type(fty.ret->type, fty.ret->ltype); fty.ret->ltype = integerRewrite.type(fty.ret->type, fty.ret->ltype);
} }
else if (isOSX)
{
// value struct returns should be rewritten as an int type to
// generate correct register usage (matches clang).
// note: sret functions change ret type to void so this won't
// trigger for those
Type* retTy = fty.ret->type->toBasetype();
if (!fty.ret->byref && retTy->ty == Tstruct)
{
fty.ret->rewrite = &integerRewrite;
fty.ret->ltype = integerRewrite.type(fty.ret->type, fty.ret->ltype);
}
}
// IMPLICIT PARAMETERS // IMPLICIT PARAMETERS
// EXPLICIT PARAMETERS // EXPLICIT PARAMETERS

View file

@ -612,7 +612,8 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
if (cinfo->fields.dim != 12) if (cinfo->fields.dim != 12)
{ {
error(Loc(), "object.d ClassInfo class is incorrect"); error(Loc(), "Unexpected number of fields in object.ClassInfo; "
"druntime version does not match compiler (see -v)");
fatal(); fatal();
} }

View file

@ -89,6 +89,7 @@ public:
llvm::GlobalVariable *interfaceZ = ir->getClassInfoSymbol(); llvm::GlobalVariable *interfaceZ = ir->getClassInfoSymbol();
interfaceZ->setInitializer(ir->getClassInfoInit()); interfaceZ->setInitializer(ir->getClassInfoInit());
interfaceZ->setLinkage(DtoLinkage(decl)); interfaceZ->setLinkage(DtoLinkage(decl));
if (DtoIsTemplateInstance(decl)) SET_COMDAT(interfaceZ, gIR->module);
} }
} }
@ -124,6 +125,7 @@ public:
llvm::GlobalVariable *initZ = ir->getInitSymbol(); llvm::GlobalVariable *initZ = ir->getInitSymbol();
initZ->setInitializer(ir->getDefaultInit()); initZ->setInitializer(ir->getDefaultInit());
initZ->setLinkage(DtoLinkage(decl)); initZ->setLinkage(DtoLinkage(decl));
if (DtoIsTemplateInstance(decl)) SET_COMDAT(initZ, gIR->module);
// emit typeinfo // emit typeinfo
DtoTypeInfoOf(decl->type); DtoTypeInfoOf(decl->type);
@ -167,18 +169,22 @@ public:
IrAggr *ir = getIrAggr(decl); IrAggr *ir = getIrAggr(decl);
llvm::GlobalValue::LinkageTypes const linkage = DtoLinkage(decl); llvm::GlobalValue::LinkageTypes const linkage = DtoLinkage(decl);
const bool isTemplateInstance = DtoIsTemplateInstance(decl);
llvm::GlobalVariable *initZ = ir->getInitSymbol(); llvm::GlobalVariable *initZ = ir->getInitSymbol();
initZ->setInitializer(ir->getDefaultInit()); initZ->setInitializer(ir->getDefaultInit());
initZ->setLinkage(linkage); initZ->setLinkage(linkage);
if (isTemplateInstance) SET_COMDAT(initZ, gIR->module);
llvm::GlobalVariable *vtbl = ir->getVtblSymbol(); llvm::GlobalVariable *vtbl = ir->getVtblSymbol();
vtbl->setInitializer(ir->getVtblInit()); vtbl->setInitializer(ir->getVtblInit());
vtbl->setLinkage(linkage); vtbl->setLinkage(linkage);
if (isTemplateInstance) SET_COMDAT(vtbl, gIR->module);
llvm::GlobalVariable *classZ = ir->getClassInfoSymbol(); llvm::GlobalVariable *classZ = ir->getClassInfoSymbol();
classZ->setInitializer(ir->getClassInfoInit()); classZ->setInitializer(ir->getClassInfoInit());
classZ->setLinkage(linkage); classZ->setLinkage(linkage);
if (isTemplateInstance) SET_COMDAT(classZ, gIR->module);
// No need to do TypeInfo here, it is <name>__classZ for classes in D2. // No need to do TypeInfo here, it is <name>__classZ for classes in D2.
} }

View file

@ -768,6 +768,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
gIR->functions.push_back(irFunc); gIR->functions.push_back(irFunc);
func->setLinkage(lowerFuncLinkage(fd)); func->setLinkage(lowerFuncLinkage(fd));
if (func->hasLinkOnceLinkage() || func->hasWeakLinkage()) SET_COMDAT(func, gIR->module);
// On x86_64, always set 'uwtable' for System V ABI compatibility. // On x86_64, always set 'uwtable' for System V ABI compatibility.
// TODO: Find a better place for this. // TODO: Find a better place for this.

View file

@ -1,4 +1,5 @@
#include "gen/inlineir.h" #include "gen/inlineir.h"
#include "gen/llvmhelpers.h"
#include "declaration.h" #include "declaration.h"
#include "template.h" #include "template.h"
@ -102,6 +103,7 @@ llvm::Function* DtoInlineIRFunction(FuncDeclaration* fdecl)
LLFunction* fun = gIR->module.getFunction(mangled_name); LLFunction* fun = gIR->module.getFunction(mangled_name);
fun->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage); fun->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
SET_COMDAT(fun, gIR->module);
fun->addFnAttr(LDC_ATTRIBUTE(AlwaysInline)); fun->addFnAttr(LDC_ATTRIBUTE(AlwaysInline));
return fun; return fun;
} }

View file

@ -1824,3 +1824,10 @@ unsigned getFieldGEPIndex(AggregateDeclaration* ad, VarDeclaration* vd)
assert(byteOffset == 0 && "Cannot address field by a simple GEP."); assert(byteOffset == 0 && "Cannot address field by a simple GEP.");
return fieldIndex; return fieldIndex;
} }
#if LDC_LLVM_VER >= 307
bool supportsCOMDAT()
{
return !global.params.targetTriple.isOSBinFormatMachO();
}
#endif

View file

@ -230,4 +230,15 @@ DValue *toElem(Expression *e, bool tryGetLvalue);
DValue *toElemDtor(Expression *e); DValue *toElemDtor(Expression *e);
LLConstant *toConstElem(Expression *e, IRState *p); LLConstant *toConstElem(Expression *e, IRState *p);
#if LDC_LLVM_VER >= 307
bool supportsCOMDAT();
#define SET_COMDAT(x,m) if (supportsCOMDAT()) x->setComdat(m.getOrInsertComdat(x->getName()))
#else
#define SET_COMDAT(x,m)
#endif
#endif #endif

View file

@ -779,7 +779,8 @@ static void genModuleInfo(Module *m, bool emitFullModuleInfo)
// The base struct should consist only of _flags/_index. // The base struct should consist only of _flags/_index.
if (Module::moduleinfo->structsize != 4 + 4) if (Module::moduleinfo->structsize != 4 + 4)
{ {
m->error("object.d ModuleInfo class is incorrect"); m->error("Unexpected size of struct object.ModuleInfo; "
"druntime version does not match compiler (see -v)");
fatal(); fatal();
} }
} }

View file

@ -102,6 +102,7 @@ void RTTIBuilder::push_void_array(llvm::Constant* CI, Type* valtype, Dsymbol* ma
LLGlobalVariable* G = new LLGlobalVariable( LLGlobalVariable* G = new LLGlobalVariable(
gIR->module, CI->getType(), true, TYPEINFO_LINKAGE_TYPE, CI, initname); gIR->module, CI->getType(), true, TYPEINFO_LINKAGE_TYPE, CI, initname);
SET_COMDAT(G, gIR->module);
G->setAlignment(valtype->alignsize()); G->setAlignment(valtype->alignsize());
push_void_array(getTypePaddedSize(CI->getType()), G); push_void_array(getTypePaddedSize(CI->getType()), G);
@ -121,6 +122,7 @@ void RTTIBuilder::push_array(llvm::Constant * CI, uint64_t dim, Type* valtype, D
LLGlobalVariable* G = new LLGlobalVariable( LLGlobalVariable* G = new LLGlobalVariable(
gIR->module, CI->getType(), true, TYPEINFO_LINKAGE_TYPE, CI, initname); gIR->module, CI->getType(), true, TYPEINFO_LINKAGE_TYPE, CI, initname);
SET_COMDAT(G, gIR->module);
G->setAlignment(valtype->alignsize()); G->setAlignment(valtype->alignsize());
push_array(dim, DtoBitCast(G, DtoType(valtype->pointerTo()))); push_array(dim, DtoBitCast(G, DtoType(valtype->pointerTo())));
@ -194,6 +196,7 @@ void RTTIBuilder::finalize(LLType* type, LLValue* value)
llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(value); llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(value);
gvar->setInitializer(tiInit); gvar->setInitializer(tiInit);
gvar->setLinkage(TYPEINFO_LINKAGE_TYPE); gvar->setLinkage(TYPEINFO_LINKAGE_TYPE);
SET_COMDAT(gvar, gIR->module);
} }
LLConstant* RTTIBuilder::get_constant(LLStructType *initType) LLConstant* RTTIBuilder::get_constant(LLStructType *initType)

View file

@ -345,9 +345,27 @@ bool DtoLowerMagicIntrinsic(IRState* p, FuncDeclaration* fndecl, CallExp *e, DVa
LLValue* ptr = toElem(exp2)->getRVal(); LLValue* ptr = toElem(exp2)->getRVal();
if (!val->getType()->isIntegerTy()) { if (!val->getType()->isIntegerTy()) {
llvm::PointerType *v = isaPointer(val->getType());
if (v && v->getContainedType(0)->isStructTy()) {
switch (const size_t N = getTypeBitSize(v->getContainedType(0))) {
case 8:
case 16:
case 32:
case 64:
case 128:
val = DtoLoad(DtoBitCast(val, llvm::Type::getIntNPtrTy(gIR->context(), static_cast<unsigned>(N))));
ptr = DtoBitCast(ptr, llvm::Type::getIntNPtrTy(gIR->context(), static_cast<unsigned>(N)));
break;
default:
goto errorStore;
}
}
else {
errorStore:
e->error("atomic store only supports integer types, not '%s'", exp1->type->toChars()); e->error("atomic store only supports integer types, not '%s'", exp1->type->toChars());
fatal(); fatal();
} }
}
llvm::StoreInst* ret = p->ir->CreateStore(val, ptr); llvm::StoreInst* ret = p->ir->CreateStore(val, ptr);
ret->setAtomic(llvm::AtomicOrdering(atomicOrdering)); ret->setAtomic(llvm::AtomicOrdering(atomicOrdering));
@ -366,16 +384,40 @@ bool DtoLowerMagicIntrinsic(IRState* p, FuncDeclaration* fndecl, CallExp *e, DVa
int atomicOrdering = (*e->arguments)[1]->toInteger(); int atomicOrdering = (*e->arguments)[1]->toInteger();
LLValue* ptr = toElem(exp)->getRVal(); LLValue* ptr = toElem(exp)->getRVal();
LLType* ptrTy = ptr->getType()->getContainedType(0);
Type* retType = exp->type->nextOf(); Type* retType = exp->type->nextOf();
if (!ptr->getType()->getContainedType(0)->isIntegerTy()) { if (!ptrTy->isIntegerTy()) {
if (ptrTy->isStructTy()) {
switch (const size_t N = getTypeBitSize(ptrTy)) {
case 8:
case 16:
case 32:
case 64:
case 128:
ptr = DtoBitCast(ptr, llvm::Type::getIntNPtrTy(gIR->context(), static_cast<unsigned>(N)));
break;
default:
goto errorLoad;
}
}
else {
errorLoad:
e->error("atomic load only supports integer types, not '%s'", retType->toChars()); e->error("atomic load only supports integer types, not '%s'", retType->toChars());
fatal(); fatal();
} }
}
llvm::LoadInst* val = p->ir->CreateLoad(ptr); llvm::LoadInst* load = p->ir->CreateLoad(ptr);
val->setAlignment(getTypeAllocSize(val->getType())); load->setAlignment(getTypeAllocSize(load->getType()));
val->setAtomic(llvm::AtomicOrdering(atomicOrdering)); load->setAtomic(llvm::AtomicOrdering(atomicOrdering));
llvm::Value* val = load;
if (val->getType() != ptrTy) {
llvm::Value* tmp = DtoRawAlloca(val->getType(), 0);
DtoStore(val, tmp);
tmp = DtoBitCast(tmp, ptrTy->getPointerTo());
val = tmp;
}
result = new DImValue(retType, val); result = new DImValue(retType, val);
return true; return true;
} }
@ -393,6 +435,31 @@ bool DtoLowerMagicIntrinsic(IRState* p, FuncDeclaration* fndecl, CallExp *e, DVa
LLValue* ptr = toElem(exp1)->getRVal(); LLValue* ptr = toElem(exp1)->getRVal();
LLValue* cmp = toElem(exp2)->getRVal(); LLValue* cmp = toElem(exp2)->getRVal();
LLValue* val = toElem(exp3)->getRVal(); LLValue* val = toElem(exp3)->getRVal();
LLType* retTy = val->getType();
if (!cmp->getType()->isIntegerTy()) {
llvm::PointerType *v = isaPointer(cmp->getType());
if (v && v->getContainedType(0)->isStructTy()) {
switch (const size_t N = getTypeBitSize(v->getContainedType(0))) {
case 8:
case 16:
case 32:
case 64:
case 128:
ptr = DtoBitCast(ptr, llvm::Type::getIntNPtrTy(gIR->context(), static_cast<unsigned>(N)));
cmp = DtoLoad(DtoBitCast(cmp, llvm::Type::getIntNPtrTy(gIR->context(), static_cast<unsigned>(N))));
val = DtoLoad(DtoBitCast(val, llvm::Type::getIntNPtrTy(gIR->context(), static_cast<unsigned>(N))));
break;
default:
goto errorCmpxchg;
}
}
else {
errorCmpxchg:
e->error("cmpxchg only supports integer types, not '%s'", exp2->type->toChars());
fatal();
}
}
#if LDC_LLVM_VER >= 305 #if LDC_LLVM_VER >= 305
LLValue* ret = p->ir->CreateAtomicCmpXchg(ptr, cmp, val, llvm::AtomicOrdering(atomicOrdering), llvm::AtomicOrdering(atomicOrdering)); LLValue* ret = p->ir->CreateAtomicCmpXchg(ptr, cmp, val, llvm::AtomicOrdering(atomicOrdering), llvm::AtomicOrdering(atomicOrdering));
// Use the same quickfix as for dragonegg - see r210956 // Use the same quickfix as for dragonegg - see r210956
@ -400,7 +467,13 @@ bool DtoLowerMagicIntrinsic(IRState* p, FuncDeclaration* fndecl, CallExp *e, DVa
#else #else
LLValue* ret = p->ir->CreateAtomicCmpXchg(ptr, cmp, val, llvm::AtomicOrdering(atomicOrdering)); LLValue* ret = p->ir->CreateAtomicCmpXchg(ptr, cmp, val, llvm::AtomicOrdering(atomicOrdering));
#endif #endif
result = new DImValue(exp3->type, ret); llvm::Value* retVal = ret;
if (retVal->getType() != retTy) {
llvm::Value* tmp = DtoRawAlloca(retVal->getType(), 0);
DtoStore(retVal, tmp);
retVal = DtoBitCast(tmp, retTy->getPointerTo());
}
result = new DImValue(exp3->type, retVal);
return true; return true;
} }

View file

@ -337,6 +337,14 @@ void IrAggr::addFieldInitializers(
// has interface vtbls? // has interface vtbls?
if (cd->vtblInterfaces && cd->vtblInterfaces->dim > 0) if (cd->vtblInterfaces && cd->vtblInterfaces->dim > 0)
{ {
// Align interface infos to pointer size.
unsigned aligned = (offset + Target::ptrsize - 1) & ~(Target::ptrsize - 1);
if (offset < aligned)
{
add_zeros(constants, offset, aligned);
offset = aligned;
}
// false when it's not okay to use functions from super classes // false when it's not okay to use functions from super classes
bool newinsts = (cd == aggrdecl->isClassDeclaration()); bool newinsts = (cd == aggrdecl->isClassDeclaration());

View file

@ -138,7 +138,7 @@ void ScopeStack::runCleanups(
} }
// Insert the unconditional branch to the first cleanup block. // Insert the unconditional branch to the first cleanup block.
irs->ir->CreateBr(cleanupScopes.back().beginBlock); irs->ir->CreateBr(cleanupScopes[sourceScope - 1].beginBlock);
// Update all the control flow in the cleanups to make sure we end up where // Update all the control flow in the cleanups to make sure we end up where
// we want. // we want.
@ -353,6 +353,7 @@ llvm::BasicBlock* ScopeStack::emitLandingPad() {
it != end; ++it it != end; ++it
) { ) {
// Insert any cleanups in between the last catch we ran and this one. // Insert any cleanups in between the last catch we ran and this one.
assert(lastCleanup >= it->cleanupScope);
if (lastCleanup > it->cleanupScope) { if (lastCleanup > it->cleanupScope) {
landingPad->setCleanup(true); landingPad->setCleanup(true);
llvm::BasicBlock* afterCleanupBB = llvm::BasicBlock::Create( llvm::BasicBlock* afterCleanupBB = llvm::BasicBlock::Create(
@ -416,9 +417,6 @@ IrFunction::IrFunction(FuncDeclaration* fd) {
func = NULL; func = NULL;
allocapoint = NULL; allocapoint = NULL;
queued = false;
defined = false;
retArg = NULL; retArg = NULL;
thisArg = NULL; thisArg = NULL;
nestArg = NULL; nestArg = NULL;

View file

@ -322,7 +322,8 @@ private:
/// ///
std::vector<JumpTarget> continueTargets; std::vector<JumpTarget> continueTargets;
/// /// cleanupScopes[i] contains the information to go from
/// currentCleanupScope() == i + 1 to currentCleanupScope() == i.
std::vector<CleanupScope> cleanupScopes; std::vector<CleanupScope> cleanupScopes;
/// ///
@ -361,7 +362,9 @@ llvm::CallSite ScopeStack::callOrInvoke(llvm::Value* callee, const T &args,
} }
if (currentLandingPads().empty()) { if (currentLandingPads().empty()) {
// Have not encountered. // Have not encountered any catches (for which we would push a scope) or
// calls to throwing functions (where we would have already executed
// this if) in this cleanup scope yet.
currentLandingPads().push_back(0); currentLandingPads().push_back(0);
} }
@ -402,9 +405,6 @@ struct IrFunction {
/// Points to the associated scope stack while emitting code for the function. /// Points to the associated scope stack while emitting code for the function.
ScopeStack* scopes; ScopeStack* scopes;
bool queued;
bool defined;
llvm::Value* retArg; // return in ptr arg llvm::Value* retArg; // return in ptr arg
llvm::Value* thisArg; // class/struct 'this' arg llvm::Value* thisArg; // class/struct 'this' arg
llvm::Value* nestArg; // nested function 'this' arg llvm::Value* nestArg; // nested function 'this' arg

View file

@ -192,7 +192,11 @@ void AggrTypeBuilder::addAggregate(AggregateDeclaration *ad)
void AggrTypeBuilder::alignCurrentOffset(unsigned alignment) void AggrTypeBuilder::alignCurrentOffset(unsigned alignment)
{ {
m_offset = (m_offset + alignment - 1) & ~(alignment - 1); unsigned aligned = (m_offset + alignment - 1) & ~(alignment - 1);
if (m_offset < aligned) {
m_fieldIndex += add_zeros(m_defaultTypes, m_offset, aligned);
m_offset = aligned;
}
} }
void AggrTypeBuilder::addTailPadding(unsigned aggregateSize) void AggrTypeBuilder::addTailPadding(unsigned aggregateSize)

View file

@ -10,7 +10,7 @@ default:
"-I@INCLUDE_INSTALL_DIR@/ldc", "-I@INCLUDE_INSTALL_DIR@/ldc",
"-I@INCLUDE_INSTALL_DIR@", "-I@INCLUDE_INSTALL_DIR@",
"-L-L@CMAKE_INSTALL_LIBDIR@", @MULTILIB_ADDITIONAL_INSTALL_PATH@ "-L-L@CMAKE_INSTALL_LIBDIR@", @MULTILIB_ADDITIONAL_INSTALL_PATH@
"-defaultlib=phobos2-ldc,curl,druntime-ldc", "-defaultlib=phobos2-ldc,druntime-ldc",
"-debuglib=phobos2-ldc-debug,curl,druntime-ldc-debug"@ADDITIONAL_DEFAULT_LDC_SWITCHES@ "-debuglib=phobos2-ldc-debug,druntime-ldc-debug"@ADDITIONAL_DEFAULT_LDC_SWITCHES@
]; ];
}; };

View file

@ -11,7 +11,7 @@ default:
"-I@RUNTIME_DIR@/src", // Needed for gc.*/rt.* unit tests. "-I@RUNTIME_DIR@/src", // Needed for gc.*/rt.* unit tests.
"-I@PHOBOS2_DIR@/", "-I@PHOBOS2_DIR@/",
"-L-L@CMAKE_BINARY_DIR@/lib@LIB_SUFFIX@", @MULTILIB_ADDITIONAL_PATH@@SHARED_LIBS_RPATH@ "-L-L@CMAKE_BINARY_DIR@/lib@LIB_SUFFIX@", @MULTILIB_ADDITIONAL_PATH@@SHARED_LIBS_RPATH@
"-defaultlib=phobos2-ldc,curl,druntime-ldc", "-defaultlib=phobos2-ldc,druntime-ldc",
"-debuglib=phobos2-ldc-debug,curl,druntime-ldc-debug"@ADDITIONAL_DEFAULT_LDC_SWITCHES@ "-debuglib=phobos2-ldc-debug,druntime-ldc-debug"@ADDITIONAL_DEFAULT_LDC_SWITCHES@
]; ];
}; };

View file

@ -129,12 +129,6 @@ list(APPEND CORE_D ${LDC_D} ${RUNTIME_DIR}/src/object.d)
file(GLOB CORE_C ${RUNTIME_DIR}/src/core/stdc/*.c) file(GLOB CORE_C ${RUNTIME_DIR}/src/core/stdc/*.c)
if(PHOBOS2_DIR) if(PHOBOS2_DIR)
if(BUILD_SHARED_LIBS)
# std.net.curl depends on libcurl when building a shared library, we
# need to take care of that.
find_package(CURL REQUIRED)
endif()
file(GLOB PHOBOS2_D ${PHOBOS2_DIR}/std/*.d) file(GLOB PHOBOS2_D ${PHOBOS2_DIR}/std/*.d)
file(GLOB PHOBOS2_D_ALGORITHM ${PHOBOS2_DIR}/std/algorithm/*.d) file(GLOB PHOBOS2_D_ALGORITHM ${PHOBOS2_DIR}/std/algorithm/*.d)
file(GLOB PHOBOS2_D_CONTAINER ${PHOBOS2_DIR}/std/container/*.d) file(GLOB PHOBOS2_D_CONTAINER ${PHOBOS2_DIR}/std/container/*.d)
@ -446,7 +440,7 @@ macro(build_runtime d_flags c_flags ld_flags lib_suffix path_suffix outlist_targ
# TODO: As for druntime, adapt once shared libraries are supported # TODO: As for druntime, adapt once shared libraries are supported
# on more operating systems. # on more operating systems.
target_link_libraries(phobos2-ldc${target_suffix} target_link_libraries(phobos2-ldc${target_suffix}
druntime-ldc${target_suffix} "curl" "m" "pthread" "dl") druntime-ldc${target_suffix} "m" "pthread" "dl")
endif() endif()
list(APPEND ${outlist_targets} "phobos2-ldc${target_suffix}") list(APPEND ${outlist_targets} "phobos2-ldc${target_suffix}")
@ -719,7 +713,7 @@ macro(build_test_runner name_suffix d_flags c_flags)
COMMAND ${LDC_EXE} COMMAND ${LDC_EXE}
-of${PROJECT_BINARY_DIR}/phobos2-test-runner${name_suffix}${CMAKE_EXECUTABLE_SUFFIX} -of${PROJECT_BINARY_DIR}/phobos2-test-runner${name_suffix}${CMAKE_EXECUTABLE_SUFFIX}
-defaultlib=druntime-ldc,${phobos2-casm} -debuglib=druntime-ldc,${phobos2-casm} -defaultlib=druntime-ldc,${phobos2-casm} -debuglib=druntime-ldc,${phobos2-casm}
-singleobj -L-lcurl ${flags} ${phobos2_o} ${RUNTIME_DIR}/src/test_runner.d -singleobj ${flags} ${phobos2_o} ${RUNTIME_DIR}/src/test_runner.d
) )
set_tests_properties(build-phobos2-test-runner${name_suffix} PROPERTIES set_tests_properties(build-phobos2-test-runner${name_suffix} PROPERTIES
DEPENDS build-phobos2-ldc-unittest${name_suffix} DEPENDS build-phobos2-ldc-unittest${name_suffix}

View file

@ -13,12 +13,6 @@ function(add_testsuite config_name dflags model)
add_test(NAME clean-${name} add_test(NAME clean-${name}
COMMAND ${CMAKE_COMMAND} -E remove_directory ${outdir}) COMMAND ${CMAKE_COMMAND} -E remove_directory ${outdir})
# FIXME: Link in libcurl even though dmd-testsuite does not depend on it
# to avoid linking issues as described in GitHub #683.
if(NOT BUILD_SHARED_LIBS)
set(dflags "${dflags} -defaultlib=phobos2-ldc,druntime-ldc,curl -debuglib=phobos2-ldc-debug,druntime-ldc-debug,curl")
endif()
# The DFLAGS environment variable read by LDMD is used because the DMD # The DFLAGS environment variable read by LDMD is used because the DMD
# testsuite build system provides no way to run the test cases with a # testsuite build system provides no way to run the test cases with a
# given set of flags without trying all combinations of them. # given set of flags without trying all combinations of them.