mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-04-28 14:10:42 +03:00
Don't forward-declare magic intrinsics mapping to instructions
It's ugly in general, and apparently causes LTO issues on Windows. This required a larger refactoring.
This commit is contained in:
parent
be00cbb189
commit
078f0532ca
6 changed files with 39 additions and 92 deletions
|
@ -293,37 +293,7 @@ llvm::FunctionType *DtoFunctionType(Type *type, IrFuncTy &irFty, Type *thistype,
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static llvm::FunctionType *DtoVaFunctionType(FuncDeclaration *fdecl) {
|
||||
IrFuncTy &irFty = getIrFunc(fdecl, true)->irFty;
|
||||
if (irFty.funcType) {
|
||||
return irFty.funcType;
|
||||
}
|
||||
|
||||
irFty.ret = new IrFuncTyArg(Type::tvoid, false);
|
||||
|
||||
irFty.args.push_back(new IrFuncTyArg(pointerTo(Type::tvoid), false));
|
||||
|
||||
if (fdecl->llvmInternal == LLVMva_start) {
|
||||
irFty.funcType = GET_INTRINSIC_DECL(vastart)->getFunctionType();
|
||||
} else if (fdecl->llvmInternal == LLVMva_copy) {
|
||||
irFty.funcType = GET_INTRINSIC_DECL(vacopy)->getFunctionType();
|
||||
irFty.args.push_back(new IrFuncTyArg(pointerTo(Type::tvoid), false));
|
||||
} else if (fdecl->llvmInternal == LLVMva_end) {
|
||||
irFty.funcType = GET_INTRINSIC_DECL(vaend)->getFunctionType();
|
||||
}
|
||||
assert(irFty.funcType);
|
||||
|
||||
return irFty.funcType;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::FunctionType *DtoFunctionType(FuncDeclaration *fdecl) {
|
||||
// handle for C vararg intrinsics
|
||||
if (DtoIsVaIntrinsic(fdecl)) {
|
||||
return DtoVaFunctionType(fdecl);
|
||||
}
|
||||
|
||||
Type *dthis = nullptr, *dnest = nullptr;
|
||||
|
||||
if (fdecl->ident == Id::ensure || fdecl->ident == Id::require) {
|
||||
|
@ -366,25 +336,6 @@ llvm::FunctionType *DtoFunctionType(FuncDeclaration *fdecl) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static llvm::Function *DtoDeclareVaFunction(FuncDeclaration *fdecl) {
|
||||
DtoVaFunctionType(fdecl);
|
||||
llvm::Function *func = nullptr;
|
||||
|
||||
if (fdecl->llvmInternal == LLVMva_start) {
|
||||
func = GET_INTRINSIC_DECL(vastart);
|
||||
} else if (fdecl->llvmInternal == LLVMva_copy) {
|
||||
func = GET_INTRINSIC_DECL(vacopy);
|
||||
} else if (fdecl->llvmInternal == LLVMva_end) {
|
||||
func = GET_INTRINSIC_DECL(vaend);
|
||||
}
|
||||
assert(func);
|
||||
|
||||
getIrFunc(fdecl)->setLLVMFunc(func);
|
||||
return func;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DtoResolveFunction(FuncDeclaration *fdecl, const bool willDeclare) {
|
||||
if ((!global.params.useUnitTests || !fdecl->type) &&
|
||||
fdecl->isUnitTestDeclaration()) {
|
||||
|
@ -412,21 +363,7 @@ void DtoResolveFunction(FuncDeclaration *fdecl, const bool willDeclare) {
|
|||
if (TemplateInstance *tinst = fdecl->parent->isTemplateInstance()) {
|
||||
if (TemplateDeclaration *tempdecl =
|
||||
tinst->tempdecl->isTemplateDeclaration()) {
|
||||
if (tempdecl->llvmInternal == LLVMva_arg) {
|
||||
Logger::println("magic va_arg found");
|
||||
fdecl->llvmInternal = LLVMva_arg;
|
||||
fdecl->ir->setDefined();
|
||||
return; // this gets mapped to an instruction so a declaration makes
|
||||
// no sense
|
||||
}
|
||||
if (tempdecl->llvmInternal == LLVMva_start) {
|
||||
Logger::println("magic va_start found");
|
||||
fdecl->llvmInternal = LLVMva_start;
|
||||
} else if (tempdecl->llvmInternal == LLVMintrinsic) {
|
||||
Logger::println("overloaded intrinsic found");
|
||||
assert(fdecl->llvmInternal == LLVMintrinsic);
|
||||
assert(fdecl->mangleOverride.length);
|
||||
} else if (tempdecl->llvmInternal == LLVMinline_asm) {
|
||||
if (tempdecl->llvmInternal == LLVMinline_asm) {
|
||||
Logger::println("magic inline asm found");
|
||||
TypeFunction *tf = static_cast<TypeFunction *>(fdecl->type);
|
||||
if (tf->parameterList.varargs != VARARGvariadic ||
|
||||
|
@ -436,13 +373,13 @@ void DtoResolveFunction(FuncDeclaration *fdecl, const bool willDeclare) {
|
|||
"variadic with no explicit parameters");
|
||||
fatal();
|
||||
}
|
||||
fdecl->llvmInternal = LLVMinline_asm;
|
||||
assert(fdecl->llvmInternal == LLVMinline_asm);
|
||||
fdecl->ir->setDefined();
|
||||
return; // this gets mapped to a special inline asm call, no point in
|
||||
// going on.
|
||||
} else if (tempdecl->llvmInternal == LLVMinline_ir) {
|
||||
Logger::println("magic inline ir found");
|
||||
fdecl->llvmInternal = LLVMinline_ir;
|
||||
assert(fdecl->llvmInternal == LLVMinline_ir);
|
||||
fdecl->_linkage = LINK::c;
|
||||
Type *type = fdecl->type;
|
||||
assert(type->ty == TY::Tfunction);
|
||||
|
@ -457,6 +394,13 @@ void DtoResolveFunction(FuncDeclaration *fdecl, const bool willDeclare) {
|
|||
}
|
||||
}
|
||||
|
||||
// magic intrinsics are mapped to instructions, no point in fwd-declaring some
|
||||
// non-existing function
|
||||
if (DtoIsMagicIntrinsic(fdecl)) {
|
||||
fdecl->ir->setDefined();
|
||||
return;
|
||||
}
|
||||
|
||||
DtoFunctionType(fdecl);
|
||||
|
||||
IF_LOG Logger::println("DtoResolveFunction(%s): %s", fdecl->toPrettyChars(),
|
||||
|
@ -610,24 +554,19 @@ void DtoDeclareFunction(FuncDeclaration *fdecl, const bool willDefine) {
|
|||
// create IrFunction
|
||||
IrFunction *irFunc = getIrFunc(fdecl, true);
|
||||
|
||||
LLFunction *vafunc = nullptr;
|
||||
if (DtoIsVaIntrinsic(fdecl)) {
|
||||
vafunc = DtoDeclareVaFunction(fdecl);
|
||||
}
|
||||
|
||||
// Calling convention.
|
||||
//
|
||||
// DMD treats _Dmain as having C calling convention and this has been
|
||||
// hardcoded into druntime, even if the frontend type has D linkage (Bugzilla
|
||||
// issue 9028).
|
||||
const bool forceC = vafunc || DtoIsIntrinsic(fdecl) || fdecl->isMain();
|
||||
const bool forceC = DtoIsIntrinsic(fdecl) || fdecl->isMain();
|
||||
|
||||
// mangled name
|
||||
const auto irMangle = getIRMangledName(fdecl, forceC ? LINK::c : f->linkage);
|
||||
|
||||
// construct function
|
||||
LLFunctionType *functype = DtoFunctionType(fdecl);
|
||||
LLFunction *func = vafunc ? vafunc : gIR->module.getFunction(irMangle);
|
||||
LLFunction *func = gIR->module.getFunction(irMangle);
|
||||
if (!func) {
|
||||
// All function declarations are "external" - any other linkage type
|
||||
// is set when actually defining the function, except extern_weak.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue