Merge remote-tracking branch 'origin/master' into runtime_compile_v5

This commit is contained in:
Ivan 2017-10-23 21:53:27 +03:00
commit 31861621eb
19 changed files with 124 additions and 144 deletions

View file

@ -95,6 +95,9 @@ install:
- eval "${DC} --version"
script:
# Invoke CMake with MULTILIB=ON just to make sure the Makefiles can be generated.
- mkdir multilibCMakeTest && cd multilibCMakeTest && cmake -DMULTILIB=ON -DLLVM_CONFIG=$(which ../${LLVM_CONFIG}) $OPTS .. && cd ..
# Invoke CMake again for the actual build.
- cmake -G Ninja -DLLVM_CONFIG=$(which ${LLVM_CONFIG}) -DLDC_INSTALL_LLVM_RUNTIME_LIBS=ON $OPTS .
# Build LDC and stdlib unittest runners.
- ninja -j3 all all-test-runners

View file

@ -66,7 +66,6 @@ version(IN_LLVM)
import gen.semantic : extraLDCSpecificSemanticAnalysis;
extern (C++):
void genCmain(Scope* sc);
// in driver/main.cpp
void addDefaultVersionIdentifiers();
void codegenModules(ref Modules modules);
@ -204,6 +203,8 @@ Where:
", FileName.canonicalName(global.inifilename), fpic, m32mscoff, mscrtlib);
}
} // !IN_LLVM
/// DMD-generated module `__entrypoint` where the C main resides
extern (C++) __gshared Module entrypoint = null;
/// Module in which the D main is
@ -231,6 +232,26 @@ extern (C++) void genCmain(Scope* sc)
/* The D code to be generated is provided as D source code in the form of a string.
* Note that Solaris, for unknown reasons, requires both a main() and an _main()
*/
version(IN_LLVM)
{
immutable cmaincode =
q{
pragma(LDC_profile_instr, false):
extern(C)
{
int _d_run_main(int argc, char **argv, void* mainFunc);
int _Dmain(char[][] args);
int main(int argc, char **argv)
{
return _d_run_main(argc, argv, &_Dmain);
}
version (Solaris) int _main(int argc, char** argv) { return main(argc, argv); }
}
pragma(LDC_no_moduleinfo);
};
}
else
{
immutable cmaincode =
q{
extern(C)
@ -244,6 +265,7 @@ extern (C++) void genCmain(Scope* sc)
version (Solaris) int _main(int argc, char** argv) { return main(argc, argv); }
}
};
}
Identifier id = Id.entrypoint;
auto m = new Module("__entrypoint.d", id, 0, 0);
scope p = new Parser!ASTCodegen(m, cmaincode, false);
@ -264,6 +286,8 @@ extern (C++) void genCmain(Scope* sc)
rootHasMain = sc._module;
}
version(IN_LLVM) {} else
{
/**
* DMD's real entry point

View file

@ -83,4 +83,22 @@ struct Target
static LINK systemLinkage();
};
#if IN_LLVM
// Provide explicit template instantiation definitions for FPTypeProperties<T>
// static members. See:
// https://stackoverflow.com/questions/43439862/c-template-instantiation-of-variable-required-here-but-no-definition-is-ava
template <typename T> real_t Target::FPTypeProperties<T>::max;
template <typename T> real_t Target::FPTypeProperties<T>::min_normal;
template <typename T> real_t Target::FPTypeProperties<T>::nan;
template <typename T> real_t Target::FPTypeProperties<T>::snan;
template <typename T> real_t Target::FPTypeProperties<T>::infinity;
template <typename T> real_t Target::FPTypeProperties<T>::epsilon;
template <typename T> d_int64 Target::FPTypeProperties<T>::dig;
template <typename T> d_int64 Target::FPTypeProperties<T>::mant_dig;
template <typename T> d_int64 Target::FPTypeProperties<T>::max_exp;
template <typename T> d_int64 Target::FPTypeProperties<T>::min_exp;
template <typename T> d_int64 Target::FPTypeProperties<T>::max_10_exp;
template <typename T> d_int64 Target::FPTypeProperties<T>::min_10_exp;
#endif
#endif

View file

@ -299,7 +299,11 @@ int createStaticLibrary() {
global.params.targetTriple->isWindowsMSVCEnvironment();
#if LDC_LLVM_VER >= 309
const bool useInternalArchiver = ar.empty();
const bool useInternalArchiver =
ar.empty() &&
// require an explicit empty `-ar=` for OSX targets due to Xcode 9 ranlib
// bug (https://github.com/ldc-developers/ldc/issues/2350)
(!global.params.targetTriple->isOSDarwin() || ar.getNumOccurrences() > 0);
#else
const bool useInternalArchiver = false;
#endif

View file

@ -26,10 +26,10 @@
#include "llvm/Support/YAMLTraits.h"
/// The module with the frontend-generated C main() definition.
extern Module *g_entrypointModule;
extern Module *entrypoint; // defined in ddmd/mars.d
/// The module that contains the actual D main() (_Dmain) definition.
extern Module *g_dMainModule;
extern Module *rootHasMain; // defined in ddmd/mars.d
#if LDC_LLVM_VER < 600
namespace llvm {
@ -316,8 +316,8 @@ void CodeGenerator::emit(Module *m) {
prepareLLModule(m);
codegenModule(ir_, m);
if (m == g_dMainModule) {
codegenModule(ir_, g_entrypointModule);
if (m == rootHasMain) {
codegenModule(ir_, entrypoint);
if (global.params.targetTriple->getEnvironment() == llvm::Triple::Android) {
// On Android, bracket TLS data with the symbols _tlsstart and _tlsend, as

View file

@ -1,72 +0,0 @@
//===-- codegenerator.d ---------------------------------------------------===//
//
// LDC the LLVM D compiler
//
// This file is distributed under the BSD-style LDC license. See the LICENSE
// file for details.
//
//===----------------------------------------------------------------------===//
module driver.codegenerator;
import ddmd.astcodegen;
import ddmd.dmodule;
import ddmd.dscope;
import ddmd.globals;
import ddmd.id;
import ddmd.identifier;
import ddmd.parse;
import ddmd.tokens;
extern (C++) __gshared Module g_entrypointModule = null;
extern (C++) __gshared Module g_dMainModule = null;
/// Callback to generate a C main() function, invoked by the frontend.
extern (C++) void genCmain(Scope *sc) {
if (g_entrypointModule) {
return;
}
/* The D code to be generated is provided as D source code in the form of a
* string.
* Note that Solaris, for unknown reasons, requires both a main() and an
* _main()
*/
static __gshared const(char)[] code =
q{
pragma(LDC_profile_instr, false):
extern(C)
{
int _d_run_main(int argc, char **argv, void* mainFunc);
int _Dmain(char[][] args);
int main(int argc, char **argv)
{
return _d_run_main(argc, argv, &_Dmain);
}
version (Solaris) int _main(int argc, char** argv) { return main(argc, argv); }
}
pragma(LDC_no_moduleinfo);
};
Identifier id = Id.entrypoint;
auto m = new Module("__entrypoint.d", id, 0, 0);
scope p = new Parser!ASTCodegen(m, code, false);
p.scanloc = Loc();
p.nextToken();
m.members = p.parseModule();
assert(p.token.value == TOKeof);
bool v = global.params.verbose;
global.params.verbose = false;
m.importedFrom = m;
m.importAll(null);
m.semantic(null);
m.semantic2(null);
m.semantic3(null);
global.params.verbose = v;
g_entrypointModule = m;
g_dMainModule = sc._module;
}

View file

@ -23,11 +23,12 @@
#include "ir/irmodule.h"
// returns the keytype typeinfo
static LLValue *to_keyti(DValue *aa) {
static LLConstant *to_keyti(DValue *aa, LLType *targetType) {
// keyti param
assert(aa->type->toBasetype()->ty == Taarray);
TypeAArray *aatype = static_cast<TypeAArray *>(aa->type->toBasetype());
return DtoTypeInfoOf(aatype->index, false);
LLConstant *ti = DtoTypeInfoOf(aatype->index, /*base=*/false);
return DtoBitCast(ti, targetType);
}
////////////////////////////////////////////////////////////////////////////////
@ -58,14 +59,14 @@ DLValue *DtoAAIndex(Loc &loc, Type *type, DValue *aa, DValue *key,
LLValue *ret;
if (lvalue) {
LLValue *rawAATI =
DtoTypeInfoOf(aa->type->unSharedOf()->mutableOf(), false);
DtoTypeInfoOf(aa->type->unSharedOf()->mutableOf(), /*base=*/false);
LLValue *castedAATI = DtoBitCast(rawAATI, funcTy->getParamType(1));
LLValue *valsize = DtoConstSize_t(getTypeAllocSize(DtoType(type)));
ret = gIR->CreateCallOrInvoke(func, aaval, castedAATI, valsize, pkey,
"aa.index")
.getInstruction();
} else {
LLValue *keyti = DtoBitCast(to_keyti(aa), funcTy->getParamType(1));
LLValue *keyti = to_keyti(aa, funcTy->getParamType(1));
ret = gIR->CreateCallOrInvoke(func, aaval, keyti, pkey, "aa.index")
.getInstruction();
}
@ -131,8 +132,7 @@ DValue *DtoAAIn(Loc &loc, Type *type, DValue *aa, DValue *key) {
aaval = DtoBitCast(aaval, funcTy->getParamType(0));
// keyti param
LLValue *keyti = to_keyti(aa);
keyti = DtoBitCast(keyti, funcTy->getParamType(1));
LLValue *keyti = to_keyti(aa, funcTy->getParamType(1));
// pkey param
LLValue *pkey = makeLValue(loc, key);
@ -177,8 +177,7 @@ DValue *DtoAARemove(Loc &loc, DValue *aa, DValue *key) {
aaval = DtoBitCast(aaval, funcTy->getParamType(0));
// keyti param
LLValue *keyti = to_keyti(aa);
keyti = DtoBitCast(keyti, funcTy->getParamType(1));
LLValue *keyti = to_keyti(aa, funcTy->getParamType(1));
// pkey param
LLValue *pkey = makeLValue(loc, key);

View file

@ -2537,7 +2537,7 @@ struct AsmProcessor {
case FPInt_Types:
switch (ptrtype) {
case Short_Ptr:
type_suffix = "";
type_suffix = 's';
break;
case Int_Ptr:
type_suffix = 'l';

View file

@ -438,7 +438,7 @@ static LLConstant *build_offti_entry(ClassDeclaration *cd, VarDeclaration *vd) {
inits[0] = DtoConstSize_t(offset);
// TypeInfo ti;
inits[1] = DtoTypeInfoOf(vd->type, true);
inits[1] = DtoTypeInfoOf(vd->type);
// done
return llvm::ConstantStruct::get(inits);

View file

@ -89,15 +89,18 @@ public:
}
// Emit TypeInfo.
DtoTypeInfoOf(decl->type);
DtoTypeInfoOf(decl->type, /*base=*/false);
// Define __InterfaceZ.
// Declare __InterfaceZ.
IrAggr *ir = getIrAggr(decl);
llvm::GlobalVariable *interfaceZ = ir->getClassInfoSymbol();
// Only define if not speculative.
if (!isSpeculativeType(decl->type)) {
interfaceZ->setInitializer(ir->getClassInfoInit());
setLinkage(decl, interfaceZ);
}
}
}
//////////////////////////////////////////////////////////////////////////
@ -134,12 +137,11 @@ public:
IrAggr *ir = getIrAggr(decl);
auto &initZ = ir->getInitSymbol();
auto initGlobal = llvm::cast<LLGlobalVariable>(initZ);
assert(initGlobal);
setLinkage(decl, initGlobal);
initZ = irs->setGlobalVarInitializer(initGlobal, ir->getDefaultInit());
setLinkage(decl, initGlobal);
// emit typeinfo
DtoTypeInfoOf(decl->type);
DtoTypeInfoOf(decl->type, /*base=*/false);
}
// Emit __xopEquals/__xopCmp/__xtoHash.
@ -186,19 +188,18 @@ public:
auto &initZ = ir->getInitSymbol();
auto initGlobal = llvm::cast<LLGlobalVariable>(initZ);
assert(initGlobal);
setLinkage(lwc, initGlobal);
initZ = irs->setGlobalVarInitializer(initGlobal, ir->getDefaultInit());
setLinkage(lwc, initGlobal);
llvm::GlobalVariable *vtbl = ir->getVtblSymbol();
vtbl->setInitializer(ir->getVtblInit());
setLinkage(lwc, vtbl);
llvm::GlobalVariable *classZ = ir->getClassInfoSymbol();
if (!isSpeculativeType(decl->type)) {
classZ->setInitializer(ir->getClassInfoInit());
setLinkage(lwc, classZ);
// No need to do TypeInfo here, it is <name>__classZ for classes in D2.
}
}
}
@ -288,8 +289,8 @@ public:
// Set the initializer, swapping out the variable if the types do not
// match.
setLinkage(lwc, gvar);
irGlobal->value = irs->setGlobalVarInitializer(gvar, initVal);
setLinkage(lwc, gvar);
// Also set up the debug info.
irs->DBuilder.EmitGlobalVariable(gvar, decl);
@ -468,18 +469,14 @@ public:
//////////////////////////////////////////////////////////////////////////
void visit(TypeInfoDeclaration *decl) LLVM_OVERRIDE {
if (irs->dcomputetarget || isSpeculativeType(decl->tinfo)) {
return;
}
if (!irs->dcomputetarget)
TypeInfoDeclaration_codegen(decl, irs);
}
//////////////////////////////////////////////////////////////////////////
void visit(TypeInfoClassDeclaration *decl) LLVM_OVERRIDE {
if (irs->dcomputetarget || isSpeculativeType(decl->tinfo)) {
return;
}
if (!irs->dcomputetarget)
TypeInfoClassDeclaration_codegen(decl, irs);
}
};

View file

@ -939,6 +939,10 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
return;
}
if (!fd->fbody) {
return;
}
llvm::Function *const func = irFunc->getLLVMFunc();
if (!func->empty()) {
@ -949,10 +953,6 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
return;
}
if (!fd->fbody) {
return;
}
// debug info
irFunc->diSubprogram = gIR->DBuilder.EmitSubProgram(fd);

View file

@ -64,7 +64,7 @@ void RTTIBuilder::push_null(Type *T) { push(getNullValue(DtoType(T))); }
void RTTIBuilder::push_null_vp() { push(getNullValue(getVoidPtrType())); }
void RTTIBuilder::push_typeinfo(Type *t) { push(DtoTypeInfoOf(t, true)); }
void RTTIBuilder::push_typeinfo(Type *t) { push(DtoTypeInfoOf(t)); }
void RTTIBuilder::push_classinfo(ClassDeclaration *cd) {
push(getIrAggr(cd)->getClassInfoSymbol());

View file

@ -68,11 +68,8 @@ public:
}
if (TypeInfoDeclaration *ti = e->var->isTypeInfoDeclaration()) {
LLType *vartype = DtoType(e->type);
result = DtoTypeInfoOf(ti->tinfo, false);
if (result->getType() != getPtrToType(vartype)) {
result = llvm::ConstantExpr::getBitCast(result, vartype);
}
result = DtoBitCast(result, DtoType(e->type));
return;
}
@ -707,6 +704,7 @@ public:
TypeInfoDeclaration_codegen(tid, p);
}
result = llvm::cast<llvm::GlobalVariable>(getIrGlobal(tid)->value);
result = DtoBitCast(result, DtoType(e->type));
}
//////////////////////////////////////////////////////////////////////////////

View file

@ -2447,7 +2447,7 @@ public:
getRuntimeFunction(e->loc, gIR->module, "_d_assocarrayliteralTX");
LLFunctionType *funcTy = func->getFunctionType();
LLValue *aaTypeInfo =
DtoBitCast(DtoTypeInfoOf(stripModifiers(aatype)),
DtoBitCast(DtoTypeInfoOf(stripModifiers(aatype), /*base=*/false),
DtoType(Type::typeinfoassociativearray->type));
LLConstant *idxs[2] = {DtoConstUint(0), DtoConstUint(0)};

View file

@ -482,7 +482,7 @@ public:
LLType *tiTy = DtoType(Type::dtypeinfo->type);
for (auto arg : *tu->arguments) {
arrInits.push_back(DtoTypeInfoOf(arg->type, true));
arrInits.push_back(DtoTypeInfoOf(arg->type));
}
// build array
@ -619,12 +619,12 @@ void TypeInfoDeclaration_codegen(TypeInfoDeclaration *decl, IRState *p) {
emitTypeMetadata(decl);
// this is a declaration of a builtin __initZ var
if (builtinTypeInfo(decl->tinfo)) {
// check if the definition can be elided
if (isSpeculativeType(decl->tinfo) || builtinTypeInfo(decl->tinfo)) {
return;
}
// define custom typedef
// define the TypeInfo global
LLVMDefineVisitor v;
decl->accept(&v);
}

View file

@ -523,8 +523,11 @@ macro(build_runtime_libs druntime_o druntime_bc phobos2_o phobos2_bc c_flags ld_
set_common_library_properties(phobos2-ldc${target_suffix} "${is_shared}")
if("${is_shared}" STREQUAL "ON")
# Make sure to link shared unittest-Phobos against shared NON-unittest-druntime
# in order to exclude the druntime tests for the Phobos test runner.
string(REPLACE "-unittest" "" target_suffix_without_unittest "${target_suffix}")
target_link_libraries(phobos2-ldc${target_suffix}
druntime-ldc${target_suffix} ${C_SYSTEM_LIBS})
druntime-ldc${target_suffix_without_unittest} ${C_SYSTEM_LIBS})
endif()
list(APPEND ${outlist_targets} "phobos2-ldc${target_suffix}")
@ -825,7 +828,7 @@ function(build_test_runners name_suffix path_suffix d_flags c_flags linkflags is
if(PHOBOS2_DIR)
set(phobos_name phobos2-test-runner${target_suffix})
add_executable(${phobos_name} EXCLUDE_FROM_ALL ${PROJECT_BINARY_DIR}/dummy.c)
target_link_libraries(${phobos_name} druntime-ldc-unittest${target_suffix})
target_link_libraries(${phobos_name} druntime-ldc${target_suffix})
set(full_linkflags "${test_runner_o} ${linkflags}")
append_testrunner_linkflags("phobos2-ldc-unittest${name_suffix}" "${path_suffix}" "${is_shared}" full_linkflags)
add_dependencies(${phobos_name} test_runner${target_suffix} phobos2-ldc-unittest${target_suffix})
@ -880,8 +883,14 @@ function(build_test_runner_variants path_suffix d_flags c_flags)
build_test_runner_variant("-debug" "${path_suffix}" "${D_FLAGS_DEBUG};${d_flags}" "${c_flags}")
endfunction()
set(TESTLIB_SUFFIX "${LIB_SUFFIX}")
if(MULTILIB AND "${TARGET_SYSTEM}" MATCHES "APPLE")
# match `hostsuffix` used for building the normal libs
set(TESTLIB_SUFFIX "${LIB_SUFFIX}${HOST_BITNESS}")
endif()
# Now generate all test runner targets.
build_test_runner_variants("${LIB_SUFFIX}" "" "")
build_test_runner_variants("${TESTLIB_SUFFIX}" "" "")
if(MULTILIB AND ${HOST_BITNESS} EQUAL 64)
build_test_runner_variants("${MULTILIB_SUFFIX}" "-m32" "-m32")
endif()
@ -938,7 +947,7 @@ function(add_runtime_tests_variants path_suffix)
endif()
endfunction()
add_runtime_tests_variants("${LIB_SUFFIX}")
add_runtime_tests_variants("${TESTLIB_SUFFIX}")
if(MULTILIB AND ${HOST_BITNESS} EQUAL 64)
add_runtime_tests_variants("${MULTILIB_SUFFIX}")
endif()

@ -1 +1 @@
Subproject commit ba8eed538d87fbb7a65f009279cf16a5a3d34b76
Subproject commit 62ef007e03edf798fcb62528c518305accf17d70

View file

@ -15,11 +15,11 @@ struct S
{
}
// CHECK: @{{.*}}classvarC14TypeInfo_Class{{\"?}} = thread_local global %object.TypeInfo_Class* @{{.*}}1C7__ClassZ
// CHECK: _D{{.*}}classvarC14TypeInfo_Class{{\"?}} = thread_local global %object.TypeInfo_Class* {{.*}}1C7__ClassZ
auto classvar = typeid(C);
// CHECK: @{{.*}}interfacevarC18TypeInfo_Interface{{\"?}} = thread_local global %"typeid({{.*}}.I)"* @{{.*}}_D{{[0-9]+}}TypeInfo_C{{.*}}1I6__initZ
// CHECK: _D{{.*}}interfacevarC18TypeInfo_Interface{{\"?}} = thread_local global %object.TypeInfo_Interface* {{.*}}TypeInfo_C{{.*}}1I6__initZ
auto interfacevar = typeid(I);
// CHECK: @{{.*}}structvarC15TypeInfo_Struct{{\"?}} = thread_local global %"typeid({{.*}}S)"* @{{.*}}_D{{[0-9]+}}TypeInfo_S{{.*}}1S6__initZ
// CHECK: _D{{.*}}structvarC15TypeInfo_Struct{{\"?}} = thread_local global %object.TypeInfo_Struct* {{.*}}TypeInfo_S{{.*}}1S6__initZ
auto structvar = typeid(S);

View file

@ -30,7 +30,7 @@ struct SWithUnion
union
{
struct { ubyte ub = 6; ushort us = 33; ulong ul_dummy = void; ulong last = 123; }
struct { ubyte ub = 6; ushort us = 33; align(8) ulong ul_dummy = void; ulong last = 123; }
struct { uint ui1; uint ui2 = 84; ulong ul = 666; }
}
}