mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-02 16:11:08 +03:00
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:
parent
c01dfc3db8
commit
92913d4c08
16 changed files with 51 additions and 38 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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 ®Count);
|
||||
|
@ -289,7 +289,7 @@ void X86_64TargetABI::rewriteArgument(IrFuncTyArg &arg, RegCount ®Count) {
|
|||
}
|
||||
}
|
||||
|
||||
void X86_64TargetABI::rewriteFunctionType(TypeFunction *tf, IrFuncTy &fty) {
|
||||
void X86_64TargetABI::rewriteFunctionType(IrFuncTy &fty) {
|
||||
RegCount ®Count = 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue