Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2.079] Support minimal runtime #2641

Merged
merged 10 commits into from
Apr 10, 2018
6 changes: 0 additions & 6 deletions driver/codegenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,6 @@ void emitLLVMUsedArray(IRState &irs) {
namespace ldc {
CodeGenerator::CodeGenerator(llvm::LLVMContext &context, bool singleObj)
: context_(context), moduleCount_(0), singleObj_(singleObj), ir_(nullptr) {
if (!ClassDeclaration::object) {
error(Loc(), "declaration for class `Object` not found; druntime not "
"configured properly");
fatal();
}

#if LDC_LLVM_VER >= 309
// Set the context to discard value names when not generating textual IR.
if (!global.params.output_ll) {
Expand Down
5 changes: 3 additions & 2 deletions driver/linker-msvc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ void addMscrtLibs(std::vector<std::string> &args,
}

void addLibIfFound(std::vector<std::string> &args, const llvm::Twine &name) {
if (llvm::sys::fs::exists(exe_path::prependLibDir(name)))
args.push_back(name.str());
std::string candidate = exe_path::prependLibDir(name);
if (llvm::sys::fs::exists(candidate))
args.push_back(std::move(candidate));
}

void addSanitizerLibs(std::vector<std::string> &args) {
Expand Down
20 changes: 10 additions & 10 deletions gen/arrays.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,13 +674,6 @@ DSliceValue *DtoNewDynArray(Loc &loc, Type *arrayType, DValue *dim,
IF_LOG Logger::println("DtoNewDynArray : %s", arrayType->toChars());
LOG_SCOPE;

// typeinfo arg
LLValue *arrayTypeInfo = DtoTypeInfoOf(arrayType);

// dim arg
assert(DtoType(dim->type) == DtoSize_t());
LLValue *arrayLen = DtoRVal(dim);

// get runtime function
Type *eltType = arrayType->toBasetype()->nextOf();
bool zeroInit = eltType->isZeroInit();
Expand All @@ -690,6 +683,13 @@ DSliceValue *DtoNewDynArray(Loc &loc, Type *arrayType, DValue *dim,
: "_d_newarrayU";
LLFunction *fn = getRuntimeFunction(loc, gIR->module, fnname);

// typeinfo arg
LLValue *arrayTypeInfo = DtoTypeInfoOf(arrayType);

// dim arg
assert(DtoType(dim->type) == DtoSize_t());
LLValue *arrayLen = DtoRVal(dim);

// call allocator
LLValue *newArray =
gIR->CreateCallOrInvoke(fn, arrayTypeInfo, arrayLen, ".gc_mem")
Expand All @@ -704,9 +704,6 @@ DSliceValue *DtoNewMulDimDynArray(Loc &loc, Type *arrayType, DValue **dims,
IF_LOG Logger::println("DtoNewMulDimDynArray : %s", arrayType->toChars());
LOG_SCOPE;

// typeinfo arg
LLValue *arrayTypeInfo = DtoTypeInfoOf(arrayType);

// get value type
Type *vtype = arrayType->toBasetype();
for (size_t i = 0; i < ndims; ++i) {
Expand All @@ -718,6 +715,9 @@ DSliceValue *DtoNewMulDimDynArray(Loc &loc, Type *arrayType, DValue **dims,
vtype->isZeroInit() ? "_d_newarraymTX" : "_d_newarraymiTX";
LLFunction *fn = getRuntimeFunction(loc, gIR->module, fnname);

// typeinfo arg
LLValue *arrayTypeInfo = DtoTypeInfoOf(arrayType);

// Check if constant
bool allDimsConst = true;
for (size_t i = 0; i < ndims; ++i) {
Expand Down
28 changes: 18 additions & 10 deletions gen/classes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ DValue *DtoNewClass(Loc &loc, TypeClass *tc, NewExp *newexp) {
llvm::Function *fn =
getRuntimeFunction(loc, gIR->module, "_d_allocclass");
LLConstant *ci = DtoBitCast(getIrAggr(tc->sym)->getClassInfoSymbol(),
DtoType(Type::typeinfoclass->type));
DtoType(getClassInfoType()));
mem =
gIR->CreateCallOrInvoke(fn, ci, ".newclass_gc_alloc").getInstruction();
mem = DtoBitCast(mem, DtoType(tc), ".newclass_gc");
Expand Down Expand Up @@ -347,17 +347,25 @@ DValue *DtoCastClass(Loc &loc, DValue *val, Type *_to) {

////////////////////////////////////////////////////////////////////////////////

DValue *DtoDynamicCastObject(Loc &loc, DValue *val, Type *_to) {
// call:
// Object _d_dynamic_cast(Object o, ClassInfo c)
static void resolveObjectAndClassInfoClasses() {
// check declarations in object.d
getObjectType();
getClassInfoType();

DtoResolveClass(ClassDeclaration::object);
DtoResolveClass(Type::typeinfoclass);
}

DValue *DtoDynamicCastObject(Loc &loc, DValue *val, Type *_to) {
// call:
// Object _d_dynamic_cast(Object o, ClassInfo c)

llvm::Function *func =
getRuntimeFunction(loc, gIR->module, "_d_dynamic_cast");
LLFunctionType *funcTy = func->getFunctionType();

resolveObjectAndClassInfoClasses();

// Object o
LLValue *obj = DtoRVal(val);
obj = DtoBitCast(obj, funcTy->getParamType(0));
Expand Down Expand Up @@ -389,13 +397,12 @@ DValue *DtoDynamicCastInterface(Loc &loc, DValue *val, Type *_to) {
// call:
// Object _d_interface_cast(void* p, ClassInfo c)

DtoResolveClass(ClassDeclaration::object);
DtoResolveClass(Type::typeinfoclass);

llvm::Function *func =
getRuntimeFunction(loc, gIR->module, "_d_interface_cast");
LLFunctionType *funcTy = func->getFunctionType();

resolveObjectAndClassInfoClasses();

// void* p
LLValue *ptr = DtoRVal(val);
ptr = DtoBitCast(ptr, funcTy->getParamType(0));
Expand Down Expand Up @@ -606,7 +613,8 @@ LLConstant *DtoDefineClassInfo(ClassDeclaration *cd) {
assert(cd->type->ty == Tclass);

IrAggr *ir = getIrAggr(cd);
ClassDeclaration *cinfo = Type::typeinfoclass;
Type *const cinfoType = getClassInfoType(); // check declaration in object.d
ClassDeclaration *const cinfo = Type::typeinfoclass;

if (cinfo->fields.dim != 12) {
error(Loc(), "Unexpected number of fields in `object.ClassInfo`; "
Expand All @@ -615,7 +623,7 @@ LLConstant *DtoDefineClassInfo(ClassDeclaration *cd) {
}

// use the rtti builder
RTTIBuilder b(cinfo);
RTTIBuilder b(cinfoType);

LLConstant *c;

Expand Down Expand Up @@ -656,7 +664,7 @@ LLConstant *DtoDefineClassInfo(ClassDeclaration *cd) {
if (cd->baseClass && !cd->isInterfaceDeclaration()) {
b.push_classinfo(cd->baseClass);
} else {
b.push_null(cinfo->type);
b.push_null(cinfoType);
}

// destructor
Expand Down
2 changes: 1 addition & 1 deletion gen/declarations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ class CodegenVisitor : public Visitor {
setLinkage(decl, initGlobal);

// emit typeinfo
if (global.params.useTypeInfo) {
if (global.params.useTypeInfo && Type::dtypeinfo) {
DtoTypeInfoOf(decl->type, /*base=*/false);
}
}
Expand Down
2 changes: 1 addition & 1 deletion gen/functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ llvm::FunctionType *DtoFunctionType(Type *type, IrFuncTy &irFty, Type *thistype,
if (isLLVMVariadic && f->linkage == LINKd) {
// Add extra `_arguments` parameter for D-style variadic functions.
newIrFty.arg_arguments =
new IrFuncTyArg(Type::dtypeinfo->type->arrayOf(), false);
new IrFuncTyArg(getTypeInfoType()->arrayOf(), false);
++nextLLArgIdx;
}

Expand Down
2 changes: 1 addition & 1 deletion gen/llvmhelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1286,7 +1286,7 @@ LLConstant *DtoTypeInfoOf(Type *type, bool base) {
LLConstant *c = isaConstant(getIrGlobal(tidecl)->value);
assert(c != NULL);
if (base) {
return llvm::ConstantExpr::getBitCast(c, DtoType(Type::dtypeinfo->type));
return llvm::ConstantExpr::getBitCast(c, DtoType(getTypeInfoType()));
}
return c;
}
Expand Down
16 changes: 8 additions & 8 deletions gen/moduleinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "gen/logger.h"
#include "gen/mangling.h"
#include "gen/rttibuilder.h"
#include "gen/runtime.h"
#include "ir/irfunction.h"
#include "ir/irmodule.h"
#include "ir/irtype.h"
Expand Down Expand Up @@ -132,7 +133,7 @@ llvm::Function *buildModuleSharedDtor(Module *m) {

/// Builds the (constant) data content for the importedModules[] array.
llvm::Constant *buildImportedModules(Module *m, size_t &count) {
const auto moduleInfoPtrTy = DtoPtrToType(Module::moduleinfo->type);
const auto moduleInfoPtrTy = DtoPtrToType(getModuleInfoType());

std::vector<LLConstant *> importInits;
for (auto mod : m->aimports) {
Expand All @@ -154,7 +155,7 @@ llvm::Constant *buildImportedModules(Module *m, size_t &count) {

/// Builds the (constant) data content for the localClasses[] array.
llvm::Constant *buildLocalClasses(Module *m, size_t &count) {
const auto classinfoTy = Type::typeinfoclass->type->ctype->getLLType();
const auto classinfoTy = DtoType(getClassInfoType());

ClassDeclarations aclasses;
for (auto s : *m->members) {
Expand Down Expand Up @@ -193,16 +194,15 @@ llvm::Constant *buildLocalClasses(Module *m, size_t &count) {
}

llvm::GlobalVariable *genModuleInfo(Module *m) {
if (!Module::moduleinfo) {
m->error("object.d is missing the `ModuleInfo` struct");
fatal();
}
// check declaration in object.d
const auto moduleInfoType = getModuleInfoType();
const auto moduleInfoDecl = Module::moduleinfo;

// The "new-style" ModuleInfo records are variable-length, with the presence
// of the various fields indicated by a certain flag bit. The base struct
// should consist only of the _flags/_index fields (the latter of which is
// unused).
if (Module::moduleinfo->structsize != 4 + 4) {
if (moduleInfoDecl->structsize != 4 + 4) {
m->error("Unexpected size of struct `object.ModuleInfo`; "
"druntime version does not match compiler (see -v)");
fatal();
Expand Down Expand Up @@ -262,7 +262,7 @@ llvm::GlobalVariable *genModuleInfo(Module *m) {
}

// Now, start building the initialiser for the ModuleInfo instance.
RTTIBuilder b(Module::moduleinfo);
RTTIBuilder b(moduleInfoType);

b.push_uint(flags);
b.push_uint(0); // index
Expand Down
10 changes: 6 additions & 4 deletions gen/modules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ void emitModuleRefToSection(RegistryStyle style, std::string moduleMangle,
// functions).
const bool isFirst = !gIR->module.getGlobalVariable("ldc.dso_slot");

llvm::Type *const moduleInfoPtrTy = DtoPtrToType(Module::moduleinfo->type);
llvm::Type *const moduleInfoPtrTy = DtoPtrToType(getModuleInfoType());
const auto sectionName =
style == RegistryStyle::sectionMSVC
? ".minfo"
Expand Down Expand Up @@ -708,9 +708,11 @@ void codegenModule(IRState *irs, Module *m) {
fatal();
}

// Skip emission of all the additional module metadata if requested by the
// user or the betterC switch is on.
if (global.params.useModuleInfo && !m->noModuleInfo) {
// Skip emission of all the additional module metadata if:
// a) the -betterC switch is on,
// b) requested explicitly by the user via pragma(LDC_no_moduleinfo), or if
// c) there's no ModuleInfo declaration.
if (global.params.useModuleInfo && !m->noModuleInfo && Module::moduleinfo) {
// generate ModuleInfo
registerModuleInfo(m);
}
Expand Down
8 changes: 4 additions & 4 deletions gen/passes/GarbageCollect2Stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ struct Analysis {
CallGraph *CG;
CallGraphNode *CGNode;

Type *getTypeFor(Value *typeinfo) const;
llvm::Type *getTypeFor(Value *typeinfo) const;
};
}

Expand Down Expand Up @@ -105,7 +105,7 @@ enum Type {

class FunctionInfo {
protected:
Type *Ty;
llvm::Type *Ty;

public:
ReturnType::Type ReturnType;
Expand Down Expand Up @@ -559,7 +559,7 @@ bool GarbageCollect2Stack::runOnFunction(Function &F) {
return Changed;
}

Type *Analysis::getTypeFor(Value *typeinfo) const {
llvm::Type *Analysis::getTypeFor(Value *typeinfo) const {
GlobalVariable *ti_global =
dyn_cast<GlobalVariable>(typeinfo->stripPointerCasts());
if (!ti_global) {
Expand Down Expand Up @@ -826,7 +826,7 @@ bool isSafeToStackAllocate(BasicBlock::iterator Alloc, Value *V,
// its return value and doesn't unwind (a readonly function can leak bits
// by throwing an exception or not depending on the input value).
if (CS.onlyReadsMemory() && CS.doesNotThrow() &&
I->getType() == Type::getVoidTy(I->getContext())) {
I->getType() == llvm::Type::getVoidTy(I->getContext())) {
break;
}

Expand Down
4 changes: 2 additions & 2 deletions gen/passes/SimplifyDRuntimeCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ struct LLVM_LIBRARY_VISIBILITY ArrayCastLenOpt : public LibCallOptimization {
IRBuilder<> &B) override {
// Verify we have a reasonable prototype for _d_array_cast_len
const FunctionType *FT = Callee->getFunctionType();
const Type *RetTy = FT->getReturnType();
const llvm::Type *RetTy = FT->getReturnType();
if (Callee->arg_size() != 3 || !isa<IntegerType>(RetTy) ||
FT->getParamType(0) != RetTy || FT->getParamType(1) != RetTy ||
FT->getParamType(2) != RetTy) {
Expand Down Expand Up @@ -263,7 +263,7 @@ struct LLVM_LIBRARY_VISIBILITY ArraySliceCopyOpt : public LibCallOptimization {
IRBuilder<> &B) override {
// Verify we have a reasonable prototype for _d_array_slice_copy
const FunctionType *FT = Callee->getFunctionType();
const Type *VoidPtrTy = PointerType::getUnqual(B.getInt8Ty());
const llvm::Type *VoidPtrTy = PointerType::getUnqual(B.getInt8Ty());
if (Callee->arg_size() != 4 || FT->getReturnType() != B.getVoidTy() ||
FT->getParamType(0) != VoidPtrTy ||
!isa<IntegerType>(FT->getParamType(1)) ||
Expand Down
16 changes: 7 additions & 9 deletions gen/rttibuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,16 @@
#include "ir/iraggr.h"
#include "ir/irfunction.h"

RTTIBuilder::RTTIBuilder(AggregateDeclaration *base_class) {
DtoResolveDsymbol(base_class);
RTTIBuilder::RTTIBuilder(Type *baseType) {
const auto ad = isAggregate(baseType);
assert(ad && "not an aggregate type");

base = base_class;
basetype = static_cast<TypeClass *>(base->type);
DtoResolveDsymbol(ad);

baseir = getIrAggr(base);
assert(baseir && "no IrStruct for TypeInfo base class");
if (ad->isClassDeclaration()) {
const auto baseir = getIrAggr(ad);
assert(baseir && "no IrAggr for TypeInfo base class");

prevFieldEnd = 0;

if (base->isClassDeclaration()) {
// just start with adding the vtbl
push(baseir->getVtblSymbol());
// and monitor
Expand Down
12 changes: 2 additions & 10 deletions gen/rttibuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,25 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/Constant.h"

class AggregateDeclaration;
class ClassDeclaration;
class Dsymbol;
class FuncDeclaration;
struct IrGlobal;
struct IrAggr;
class Type;
class TypeClass;
namespace llvm {
class StructType;
class GlobalVariable;
}

class RTTIBuilder {
AggregateDeclaration *base;
TypeClass *basetype;
IrAggr *baseir;

/// The offset (in bytes) at which the previously pushed field ended.
uint64_t prevFieldEnd;
uint64_t prevFieldEnd = 0;

public:
// 15 is enough for any D2 ClassInfo including 64 bit pointer alignment
// padding
llvm::SmallVector<llvm::Constant *, 15> inits;

explicit RTTIBuilder(AggregateDeclaration *base_class);
explicit RTTIBuilder(Type *baseType);

void push(llvm::Constant *C);
void push_null(Type *T);
Expand Down
Loading