Store front-end D function type in IrFuncTy

As we do for IrFuncTyArg. We'll need access to the front-end linkage for
the Posix ABIs too in order to implement indirect-by-value passing of
non-PODs for `extern(C++)`.
This commit is contained in:
Martin Kinkelin 2018-05-29 21:32:58 +02:00
parent c01dfc3db8
commit 92913d4c08
16 changed files with 51 additions and 38 deletions

View file

@ -41,7 +41,7 @@ struct AArch64TargetABI : TargetABI {
(t->ty == Tstruct && t->size() > 16 && !isHFA((TypeStruct *)t));
}
void rewriteFunctionType(TypeFunction *tf, IrFuncTy &fty) override {
void rewriteFunctionType(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
@ -59,7 +59,8 @@ struct AArch64TargetABI : TargetABI {
}
// extern(D): reverse parameter order for non variadics, for DMD-compliance
if (tf->linkage == LINKd && tf->varargs != 1 && fty.args.size() > 1) {
if (fty.type->linkage == LINKd && fty.type->varargs != 1 &&
fty.args.size() > 1) {
fty.reverseParams = true;
}
}

View file

@ -68,7 +68,7 @@ struct ArmTargetABI : TargetABI {
// problem is better understood.
}
void rewriteFunctionType(TypeFunction *tf, IrFuncTy &fty) override {
void rewriteFunctionType(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
@ -86,7 +86,8 @@ struct ArmTargetABI : TargetABI {
}
// extern(D): reverse parameter order for non variadics, for DMD-compliance
if (tf->linkage == LINKd && tf->varargs != 1 && fty.args.size() > 1) {
if (fty.type->linkage == LINKd && fty.type->varargs != 1 &&
fty.args.size() > 1) {
fty.reverseParams = true;
}
}

View file

@ -47,7 +47,7 @@ struct MIPS64TargetABI : TargetABI {
return ty == Tstruct || ty == Tsarray;
}
void rewriteFunctionType(TypeFunction *tf, IrFuncTy &fty) override {
void rewriteFunctionType(IrFuncTy &fty) override {
if (!fty.ret->byref) {
rewriteArgument(fty, *fty.ret);
}
@ -59,7 +59,8 @@ struct MIPS64TargetABI : TargetABI {
}
// extern(D): reverse parameter order for non variadics, for DMD-compliance
if (tf->linkage == LINKd && tf->varargs != 1 && fty.args.size() > 1) {
if (fty.type->linkage == LINKd && fty.type->varargs != 1 &&
fty.args.size() > 1) {
fty.reverseParams = true;
}
}

View file

@ -28,7 +28,7 @@ struct NVPTXTargetABI : TargetABI {
t = t->toBasetype();
return ((t->ty == Tsarray || t->ty == Tstruct) && t->size() > 64);
}
void rewriteFunctionType(TypeFunction *t, IrFuncTy &fty) override {
void rewriteFunctionType(IrFuncTy &fty) override {
for (auto arg : fty.args) {
if (!arg->byref)
rewriteArgument(fty, *arg);

View file

@ -58,7 +58,7 @@ struct PPCTargetABI : TargetABI {
(!Is64Bit || t->size() > 64);
}
void rewriteFunctionType(TypeFunction *tf, IrFuncTy &fty) override {
void rewriteFunctionType(IrFuncTy &fty) override {
// return value
if (!fty.ret->byref) {
rewriteArgument(fty, *fty.ret);
@ -72,7 +72,8 @@ struct PPCTargetABI : TargetABI {
}
// extern(D): reverse parameter order for non variadics, for DMD-compliance
if (tf->linkage == LINKd && tf->varargs != 1 && fty.args.size() > 1) {
if (fty.type->linkage == LINKd && fty.type->varargs != 1 &&
fty.args.size() > 1) {
fty.reverseParams = true;
}
}

View file

@ -47,7 +47,7 @@ struct PPC64LETargetABI : TargetABI {
!isHFA((TypeStruct *)t, nullptr, 8));
}
void rewriteFunctionType(TypeFunction *tf, IrFuncTy &fty) override {
void rewriteFunctionType(IrFuncTy &fty) override {
// return value
if (!fty.ret->byref) {
rewriteArgument(fty, *fty.ret);
@ -61,7 +61,8 @@ struct PPC64LETargetABI : TargetABI {
}
// extern(D): reverse parameter order for non variadics, for DMD-compliance
if (tf->linkage == LINKd && tf->varargs != 1 && fty.args.size() > 1) {
if (fty.type->linkage == LINKd && fty.type->varargs != 1 &&
fty.args.size() > 1) {
fty.reverseParams = true;
}
}

View file

@ -28,7 +28,7 @@ struct SPIRVTargetABI : TargetABI {
t = t->toBasetype();
return ((t->ty == Tsarray || t->ty == Tstruct) && t->size() > 64);
}
void rewriteFunctionType(TypeFunction *t, IrFuncTy &fty) override {
void rewriteFunctionType(IrFuncTy &fty) override {
for (auto arg : fty.args) {
if (!arg->byref)
rewriteArgument(fty, *arg);

View file

@ -80,10 +80,6 @@ private:
return isAggregate(t) && !canRewriteAsInt(t);
}
LINK &getLinkage(IrFuncTy &fty) {
return reinterpret_cast<LINK &>(fty.tag);
}
public:
Win64TargetABI()
: isMSVC(global.params.targetTriple->isWindowsMSVCEnvironment()) {}
@ -111,10 +107,7 @@ public:
return tf->linkage == LINKcpp;
}
void rewriteFunctionType(TypeFunction *tf, IrFuncTy &fty) override {
// store linkage in fty.tag as required by rewriteArgument() later
getLinkage(fty) = tf->linkage;
void rewriteFunctionType(IrFuncTy &fty) override {
// return value
const auto rt = fty.ret->type->toBasetype();
if (!fty.ret->byref && rt->ty != Tvoid) {
@ -129,7 +122,8 @@ public:
}
// extern(D): reverse parameter order for non variadics, for DMD-compliance
if (tf->linkage == LINKd && tf->varargs != 1 && fty.args.size() > 1) {
if (fty.type->linkage == LINKd && fty.type->varargs != 1 &&
fty.args.size() > 1) {
fty.reverseParams = true;
}
}
@ -155,7 +149,7 @@ public:
Type *t = arg.type->toBasetype();
LLType *originalLType = arg.ltype;
if (passPointerToHiddenCopy(t, isReturnValue, getLinkage(fty))) {
if (passPointerToHiddenCopy(t, isReturnValue, fty.type->linkage)) {
// the caller allocates a hidden copy and passes a pointer to that copy
byvalRewrite.applyTo(arg);
} else if (isAggregate(t) && canRewriteAsInt(t) && !isMagicCppStruct(t)) {

View file

@ -222,7 +222,7 @@ struct X86_64TargetABI : TargetABI {
bool passByVal(Type *t) override;
void rewriteFunctionType(TypeFunction *tf, IrFuncTy &fty) override;
void rewriteFunctionType(IrFuncTy &fty) override;
void rewriteVarargs(IrFuncTy &fty, std::vector<IrFuncTyArg *> &args) override;
void rewriteArgument(IrFuncTy &fty, IrFuncTyArg &arg) override;
void rewriteArgument(IrFuncTyArg &arg, RegCount &regCount);
@ -289,7 +289,7 @@ void X86_64TargetABI::rewriteArgument(IrFuncTyArg &arg, RegCount &regCount) {
}
}
void X86_64TargetABI::rewriteFunctionType(TypeFunction *tf, IrFuncTy &fty) {
void X86_64TargetABI::rewriteFunctionType(IrFuncTy &fty) {
RegCount &regCount = getRegCount(fty);
regCount = RegCount(); // initialize
@ -320,7 +320,8 @@ void X86_64TargetABI::rewriteFunctionType(TypeFunction *tf, IrFuncTy &fty) {
LOG_SCOPE;
// extern(D): reverse parameter order for non variadics, for DMD-compliance
if (tf->linkage == LINKd && tf->varargs != 1 && fty.args.size() > 1) {
if (fty.type->linkage == LINKd && fty.type->varargs != 1 &&
fty.args.size() > 1) {
fty.reverseParams = true;
}

View file

@ -123,12 +123,12 @@ struct X86TargetABI : TargetABI {
return DtoIsInMemoryOnly(t);
}
void rewriteFunctionType(TypeFunction *tf, IrFuncTy &fty) override {
const bool externD = (tf->linkage == LINKd && tf->varargs != 1);
void rewriteFunctionType(IrFuncTy &fty) override {
const bool externD = (fty.type->linkage == LINKd && fty.type->varargs != 1);
// return value:
if (!fty.ret->byref) {
Type *rt = tf->next->toBasetype(); // for sret, rt == void
Type *rt = fty.type->next->toBasetype(); // for sret, rt == void
if (isAggregate(rt) && !isMagicCppStruct(rt) && canRewriteAsInt(rt) &&
// don't rewrite cfloat for extern(D)
!(externD && rt->ty == Tcomplex32)) {

View file

@ -304,7 +304,7 @@ struct UnknownTargetABI : TargetABI {
bool passByVal(Type *t) override { return t->toBasetype()->ty == Tstruct; }
void rewriteFunctionType(TypeFunction *t, IrFuncTy &fty) override {
void rewriteFunctionType(IrFuncTy &) override {
// why?
}
};
@ -369,7 +369,7 @@ struct IntrinsicABI : TargetABI {
}
}
void rewriteFunctionType(TypeFunction *tf, IrFuncTy &fty) override {
void rewriteFunctionType(IrFuncTy &fty) override {
if (!fty.arg_sret) {
Type *rt = fty.ret->type->toBasetype();
if (rt->ty == Tstruct) {

View file

@ -144,7 +144,7 @@ struct TargetABI {
virtual bool passThisBeforeSret(TypeFunction *tf) { return false; }
/// Called to give ABI the chance to rewrite the types
virtual void rewriteFunctionType(TypeFunction *t, IrFuncTy &fty) = 0;
virtual void rewriteFunctionType(IrFuncTy &fty) = 0;
virtual void rewriteVarargs(IrFuncTy &fty, std::vector<IrFuncTyArg *> &args);
virtual void rewriteArgument(IrFuncTy &fty, IrFuncTyArg &arg) {}

View file

@ -77,7 +77,7 @@ llvm::FunctionType *DtoFunctionType(Type *type, IrFuncTy &irFty, Type *thistype,
// Do not modify irFty yet; this function may be called recursively if any
// of the argument types refer to this type.
IrFuncTy newIrFty;
IrFuncTy newIrFty(f);
// The index of the next argument on the LLVM level.
unsigned nextLLArgIdx = 0;
@ -188,7 +188,7 @@ llvm::FunctionType *DtoFunctionType(Type *type, IrFuncTy &irFty, Type *thistype,
}
// let the ABI rewrite the types as necessary
abi->rewriteFunctionType(f, newIrFty);
abi->rewriteFunctionType(newIrFty);
// Now we can modify irFty safely.
irFty = std::move(newIrFty);

View file

@ -16,12 +16,15 @@
#include "gen/tollvm.h"
#include "ir/irdsymbol.h"
IrFunction::IrFunction(FuncDeclaration *fd) : FMF(opts::defaultFMF) {
IrFunction::IrFunction(FuncDeclaration *fd)
: FMF(opts::defaultFMF), irFty(nullptr /*set immediately below*/) {
decl = fd;
Type *t = fd->type->toBasetype();
assert(t->ty == Tfunction);
type = static_cast<TypeFunction *>(t);
irFty.type = type;
}
void IrFunction::setNeverInline() {

View file

@ -27,6 +27,7 @@
class DValue;
class Type;
class TypeFunction;
struct ABIRewrite;
namespace llvm {
class Type;
@ -83,6 +84,9 @@ struct IrFuncTyArg {
// represents a function type
struct IrFuncTy {
// D type
TypeFunction *type;
// The final LLVM type
llvm::FunctionType *funcType = nullptr;
@ -116,6 +120,8 @@ struct IrFuncTy {
llvm::Value *getParamLVal(Type *dty, size_t idx, llvm::Value *val);
AttrSet getParamAttrs(bool passThisBeforeSret);
IrFuncTy(TypeFunction *tf) : type(tf) {}
};
#endif

View file

@ -23,8 +23,10 @@ IrTypeFunction *IrTypeFunction::get(Type *dt) {
assert(!dt->ctype);
assert(dt->ty == Tfunction);
IrFuncTy irFty;
llvm::Type *lt = DtoFunctionType(dt, irFty, nullptr, nullptr);
TypeFunction *tf = static_cast<TypeFunction *>(dt);
IrFuncTy irFty(tf);
llvm::Type *lt = DtoFunctionType(tf, irFty, nullptr, nullptr);
// Could have already built the type as part of a struct forward reference,
// just as for pointers and arrays.
@ -44,9 +46,11 @@ IrTypeDelegate *IrTypeDelegate::get(Type *t) {
assert(t->ty == Tdelegate);
assert(t->nextOf()->ty == Tfunction);
IrFuncTy irFty;
TypeFunction *tf = static_cast<TypeFunction *>(t->nextOf());
IrFuncTy irFty(tf);
llvm::Type *ltf =
DtoFunctionType(t->nextOf(), irFty, nullptr, Type::tvoid->pointerTo());
DtoFunctionType(tf, irFty, nullptr, Type::tvoid->pointerTo());
llvm::Type *types[] = {getVoidPtrType(), getPtrToType(ltf)};
LLStructType *lt = LLStructType::get(gIR->context(), types, false);