mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-04-30 23:20:40 +03:00
Adapt to free-standing size(Type*)
function
This commit is contained in:
parent
665e14ac46
commit
c9ac30c236
25 changed files with 80 additions and 59 deletions
|
@ -17,6 +17,8 @@
|
||||||
#include "gen/abi/abi.h"
|
#include "gen/abi/abi.h"
|
||||||
#include "gen/abi/generic.h"
|
#include "gen/abi/generic.h"
|
||||||
|
|
||||||
|
using namespace dmd;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AAPCS64 uses a special native va_list type, a struct aliased as
|
* AAPCS64 uses a special native va_list type, a struct aliased as
|
||||||
* object.__va_list in druntime. Apple diverges and uses a simple char*
|
* object.__va_list in druntime. Apple diverges and uses a simple char*
|
||||||
|
@ -100,7 +102,7 @@ public:
|
||||||
if (!arg->byref) {
|
if (!arg->byref) {
|
||||||
auto tb = arg->type->toBasetype();
|
auto tb = arg->type->toBasetype();
|
||||||
|
|
||||||
if (tb->size() == 0) {
|
if (size(tb) == 0) {
|
||||||
fty.args.erase(fty.args.begin() + i);
|
fty.args.erase(fty.args.begin() + i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,8 +125,8 @@ bool TargetABI::isPOD(Type *t, bool excludeStructsWithCtor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TargetABI::canRewriteAsInt(Type *t, bool include64bit) {
|
bool TargetABI::canRewriteAsInt(Type *t, bool include64bit) {
|
||||||
auto size = t->toBasetype()->size();
|
auto sz = size(t->toBasetype());
|
||||||
return size == 1 || size == 2 || size == 4 || (include64bit && size == 8);
|
return sz == 1 || sz == 2 || sz == 4 || (include64bit && sz == 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TargetABI::isExternD(TypeFunction *tf) {
|
bool TargetABI::isExternD(TypeFunction *tf) {
|
||||||
|
@ -159,7 +159,7 @@ llvm::CallingConv::ID TargetABI::callingConv(FuncDeclaration *fdecl) {
|
||||||
|
|
||||||
bool TargetABI::preferPassByRef(Type *t) {
|
bool TargetABI::preferPassByRef(Type *t) {
|
||||||
// simple base heuristic: use a ref for all types > 2 machine words
|
// simple base heuristic: use a ref for all types > 2 machine words
|
||||||
return t->size() > 2 * target.ptrsize;
|
return size(t) > 2 * target.ptrsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#include "gen/abi/generic.h"
|
#include "gen/abi/generic.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
|
|
||||||
|
using namespace dmd;
|
||||||
|
|
||||||
struct ArmTargetABI : TargetABI {
|
struct ArmTargetABI : TargetABI {
|
||||||
HFVAToArray hfvaToArray;
|
HFVAToArray hfvaToArray;
|
||||||
CompositeToArray32 compositeToArray32;
|
CompositeToArray32 compositeToArray32;
|
||||||
|
@ -36,7 +38,7 @@ struct ArmTargetABI : TargetABI {
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return rt->ty == TY::Tsarray ||
|
return rt->ty == TY::Tsarray ||
|
||||||
(rt->ty == TY::Tstruct && rt->size() > 4 &&
|
(rt->ty == TY::Tstruct && size(rt) > 4 &&
|
||||||
(gTargetMachine->Options.FloatABIType == llvm::FloatABI::Soft ||
|
(gTargetMachine->Options.FloatABIType == llvm::FloatABI::Soft ||
|
||||||
!isHFVA(rt, hfvaToArray.maxElements)));
|
!isHFVA(rt, hfvaToArray.maxElements)));
|
||||||
}
|
}
|
||||||
|
@ -47,7 +49,7 @@ struct ArmTargetABI : TargetABI {
|
||||||
// converts back to non-byval. Without this special handling the
|
// converts back to non-byval. Without this special handling the
|
||||||
// optimzer generates bad code (e.g. std.random unittest crash).
|
// optimzer generates bad code (e.g. std.random unittest crash).
|
||||||
t = t->toBasetype();
|
t = t->toBasetype();
|
||||||
return ((t->ty == TY::Tsarray || t->ty == TY::Tstruct) && t->size() > 64);
|
return ((t->ty == TY::Tsarray || t->ty == TY::Tstruct) && size(t) > 64);
|
||||||
|
|
||||||
// Note: byval can have a codegen problem with -O1 and higher.
|
// Note: byval can have a codegen problem with -O1 and higher.
|
||||||
// What happens is that load instructions are being incorrectly
|
// What happens is that load instructions are being incorrectly
|
||||||
|
|
|
@ -218,7 +218,7 @@ struct IntegerRewrite : BaseBitcastABIRewrite {
|
||||||
return LLIntegerType::get(gIR->context(), size * 8);
|
return LLIntegerType::get(gIR->context(), size * 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLType *type(Type *t) override { return getIntegerType(t->size()); }
|
LLType *type(Type *t) override { return getIntegerType(dmd::size(t)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -292,7 +292,7 @@ struct HFVAToArray : BaseBitcastABIRewrite {
|
||||||
*/
|
*/
|
||||||
template <int elementSize> struct CompositeToArray : BaseBitcastABIRewrite {
|
template <int elementSize> struct CompositeToArray : BaseBitcastABIRewrite {
|
||||||
LLType *type(Type *t) override {
|
LLType *type(Type *t) override {
|
||||||
size_t length = (t->size() + elementSize - 1) / elementSize;
|
size_t length = (dmd::size(t) + elementSize - 1) / elementSize;
|
||||||
return LLArrayType::get(LLIntegerType::get(gIR->context(), elementSize * 8),
|
return LLArrayType::get(LLIntegerType::get(gIR->context(), elementSize * 8),
|
||||||
length);
|
length);
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ FlattenedFields visitStructFields(Type *ty, unsigned baseOffset) {
|
||||||
result.length = 2;
|
result.length = 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (ty->size() > 8) {
|
if (size(ty) > 8) {
|
||||||
// field larger than GRLEN and FRLEN
|
// field larger than GRLEN and FRLEN
|
||||||
result.length = -1;
|
result.length = -1;
|
||||||
break;
|
break;
|
||||||
|
@ -88,7 +88,7 @@ struct HardfloatRewrite : BaseBitcastABIRewrite {
|
||||||
t[i] =
|
t[i] =
|
||||||
flat.fields[i]->isfloating()
|
flat.fields[i]->isfloating()
|
||||||
? DtoType(flat.fields[i])
|
? DtoType(flat.fields[i])
|
||||||
: LLIntegerType::get(gIR->context(), flat.fields[i]->size() * 8);
|
: LLIntegerType::get(gIR->context(), size(flat.fields[i]) * 8);
|
||||||
}
|
}
|
||||||
return LLStructType::get(gIR->context(), {t[0], t[1]}, false);
|
return LLStructType::get(gIR->context(), {t[0], t[1]}, false);
|
||||||
}
|
}
|
||||||
|
@ -126,14 +126,14 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// pass by reference when > 2*GRLEN
|
// pass by reference when > 2*GRLEN
|
||||||
return rt->size() > 16;
|
return size(rt) > 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto passByVal(TypeFunction *, Type *t) -> bool override {
|
auto passByVal(TypeFunction *, Type *t) -> bool override {
|
||||||
if (!isPOD(t)) {
|
if (!isPOD(t)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return t->size() > 16;
|
return size(t) > 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rewriteFunctionType(IrFuncTy &fty) override {
|
void rewriteFunctionType(IrFuncTy &fty) override {
|
||||||
|
@ -174,8 +174,8 @@ public:
|
||||||
// return values should have the `signext` attribute.
|
// return values should have the `signext` attribute.
|
||||||
// C example: https://godbolt.org/z/vcjErxj76
|
// C example: https://godbolt.org/z/vcjErxj76
|
||||||
arg.attrs.addAttribute(LLAttribute::SExt);
|
arg.attrs.addAttribute(LLAttribute::SExt);
|
||||||
} else if (isAggregate(ty) && ty->size() && ty->size() <= 16) {
|
} else if (isAggregate(ty) && size(ty) && size(ty) <= 16) {
|
||||||
if (ty->size() > 8 && DtoAlignment(ty) < 16) {
|
if (size(ty) > 8 && DtoAlignment(ty) < 16) {
|
||||||
// pass the aggregate as {int64, int64} to avoid wrong alignment
|
// pass the aggregate as {int64, int64} to avoid wrong alignment
|
||||||
integer2Rewrite.applyToIfNotObsolete(arg);
|
integer2Rewrite.applyToIfNotObsolete(arg);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include "gen/tollvm.h"
|
#include "gen/tollvm.h"
|
||||||
#include "gen/dcompute/abi-rewrites.h"
|
#include "gen/dcompute/abi-rewrites.h"
|
||||||
|
|
||||||
|
using namespace dmd;
|
||||||
|
|
||||||
struct NVPTXTargetABI : TargetABI {
|
struct NVPTXTargetABI : TargetABI {
|
||||||
DComputePointerRewrite pointerRewite;
|
DComputePointerRewrite pointerRewite;
|
||||||
llvm::CallingConv::ID callingConv(LINK l) override {
|
llvm::CallingConv::ID callingConv(LINK l) override {
|
||||||
|
@ -26,7 +28,7 @@ struct NVPTXTargetABI : TargetABI {
|
||||||
}
|
}
|
||||||
bool passByVal(TypeFunction *, Type *t) override {
|
bool passByVal(TypeFunction *, Type *t) override {
|
||||||
t = t->toBasetype();
|
t = t->toBasetype();
|
||||||
return ((t->ty == TY::Tsarray || t->ty == TY::Tstruct) && t->size() > 64);
|
return ((t->ty == TY::Tsarray || t->ty == TY::Tstruct) && size(t) > 64);
|
||||||
}
|
}
|
||||||
void rewriteFunctionType(IrFuncTy &fty) override {
|
void rewriteFunctionType(IrFuncTy &fty) override {
|
||||||
for (auto arg : fty.args) {
|
for (auto arg : fty.args) {
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include "gen/llvmhelpers.h"
|
#include "gen/llvmhelpers.h"
|
||||||
#include "gen/tollvm.h"
|
#include "gen/tollvm.h"
|
||||||
|
|
||||||
|
using namespace dmd;
|
||||||
|
|
||||||
struct PPCTargetABI : TargetABI {
|
struct PPCTargetABI : TargetABI {
|
||||||
CompositeToArray32 compositeToArray32;
|
CompositeToArray32 compositeToArray32;
|
||||||
CompositeToArray64 compositeToArray64;
|
CompositeToArray64 compositeToArray64;
|
||||||
|
@ -54,7 +56,7 @@ struct PPCTargetABI : TargetABI {
|
||||||
// used byval for type > 64 bytes.
|
// used byval for type > 64 bytes.
|
||||||
t = t->toBasetype();
|
t = t->toBasetype();
|
||||||
return (t->ty == TY::Tsarray || t->ty == TY::Tstruct) &&
|
return (t->ty == TY::Tsarray || t->ty == TY::Tstruct) &&
|
||||||
(!Is64Bit || t->size() > 64);
|
(!Is64Bit || size(t) > 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rewriteFunctionType(IrFuncTy &fty) override {
|
void rewriteFunctionType(IrFuncTy &fty) override {
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include "gen/llvmhelpers.h"
|
#include "gen/llvmhelpers.h"
|
||||||
#include "gen/tollvm.h"
|
#include "gen/tollvm.h"
|
||||||
|
|
||||||
|
using namespace dmd;
|
||||||
|
|
||||||
struct PPC64LETargetABI : TargetABI {
|
struct PPC64LETargetABI : TargetABI {
|
||||||
HFVAToArray hfvaToArray;
|
HFVAToArray hfvaToArray;
|
||||||
CompositeToArray64 compositeToArray64;
|
CompositeToArray64 compositeToArray64;
|
||||||
|
@ -42,7 +44,7 @@ struct PPC64LETargetABI : TargetABI {
|
||||||
|
|
||||||
bool passByVal(TypeFunction *, Type *t) override {
|
bool passByVal(TypeFunction *, Type *t) override {
|
||||||
t = t->toBasetype();
|
t = t->toBasetype();
|
||||||
return t->ty == TY::Tsarray || (t->ty == TY::Tstruct && t->size() > 16 &&
|
return t->ty == TY::Tsarray || (t->ty == TY::Tstruct && size(t) > 16 &&
|
||||||
!isHFVA(t, hfvaToArray.maxElements));
|
!isHFVA(t, hfvaToArray.maxElements));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ FlattenedFields visitStructFields(Type *ty, unsigned baseOffset) {
|
||||||
result.length = 2;
|
result.length = 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (ty->toBasetype()->size() > 8) {
|
if (size(ty->toBasetype()) > 8) {
|
||||||
// field larger than XLEN and FLEN
|
// field larger than XLEN and FLEN
|
||||||
result.length = -1;
|
result.length = -1;
|
||||||
break;
|
break;
|
||||||
|
@ -111,7 +111,7 @@ struct HardfloatRewrite : ABIRewrite {
|
||||||
for (unsigned i = 0; i < (unsigned)flat.length; ++i) {
|
for (unsigned i = 0; i < (unsigned)flat.length; ++i) {
|
||||||
DtoMemCpy(DtoGEP(asType, buffer, 0, i),
|
DtoMemCpy(DtoGEP(asType, buffer, 0, i),
|
||||||
DtoGEP1(getI8Type(), address, flat.fields[i].offset),
|
DtoGEP1(getI8Type(), address, flat.fields[i].offset),
|
||||||
DtoConstSize_t(flat.fields[i].ty->size()));
|
DtoConstSize_t(size(flat.fields[i].ty)));
|
||||||
}
|
}
|
||||||
return DtoLoad(asType, buffer, ".HardfloatRewrite_arg");
|
return DtoLoad(asType, buffer, ".HardfloatRewrite_arg");
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ struct HardfloatRewrite : ABIRewrite {
|
||||||
for (unsigned i = 0; i < (unsigned)flat.length; ++i) {
|
for (unsigned i = 0; i < (unsigned)flat.length; ++i) {
|
||||||
DtoMemCpy(DtoGEP1(getI8Type(), ret, flat.fields[i].offset),
|
DtoMemCpy(DtoGEP1(getI8Type(), ret, flat.fields[i].offset),
|
||||||
DtoGEP(asType, buffer, 0, i),
|
DtoGEP(asType, buffer, 0, i),
|
||||||
DtoConstSize_t(flat.fields[i].ty->size()));
|
DtoConstSize_t(size(flat.fields[i].ty)));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ struct HardfloatRewrite : ABIRewrite {
|
||||||
t[i] = flat.fields[i].ty->isfloating()
|
t[i] = flat.fields[i].ty->isfloating()
|
||||||
? DtoType(flat.fields[i].ty)
|
? DtoType(flat.fields[i].ty)
|
||||||
: LLIntegerType::get(gIR->context(),
|
: LLIntegerType::get(gIR->context(),
|
||||||
flat.fields[i].ty->size() * 8);
|
size(flat.fields[i].ty) * 8);
|
||||||
}
|
}
|
||||||
return LLStructType::get(gIR->context(), {t[0], t[1]}, false);
|
return LLStructType::get(gIR->context(), {t[0], t[1]}, false);
|
||||||
}
|
}
|
||||||
|
@ -167,20 +167,20 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Type *rt = tf->next->toBasetype();
|
Type *rt = tf->next->toBasetype();
|
||||||
if (!rt->size())
|
if (!size(rt))
|
||||||
return false;
|
return false;
|
||||||
if (!isPOD(rt))
|
if (!isPOD(rt))
|
||||||
return true;
|
return true;
|
||||||
return rt->size() > 16;
|
return size(rt) > 16;
|
||||||
}
|
}
|
||||||
bool passByVal(TypeFunction *, Type *t) override {
|
bool passByVal(TypeFunction *, Type *t) override {
|
||||||
if (!t->size())
|
if (!size(t))
|
||||||
return false;
|
return false;
|
||||||
if (t->toBasetype()->ty == TY::Tcomplex80) {
|
if (t->toBasetype()->ty == TY::Tcomplex80) {
|
||||||
// rewrite it later to bypass the RVal problem
|
// rewrite it later to bypass the RVal problem
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return t->size() > 16;
|
return size(t) > 16;
|
||||||
}
|
}
|
||||||
void rewriteFunctionType(IrFuncTy &fty) override {
|
void rewriteFunctionType(IrFuncTy &fty) override {
|
||||||
if (!fty.ret->byref) {
|
if (!fty.ret->byref) {
|
||||||
|
@ -224,8 +224,8 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAggregate(ty) && ty->size() && ty->size() <= 16) {
|
if (isAggregate(ty) && size(ty) && size(ty) <= 16) {
|
||||||
if (ty->size() > 8 && DtoAlignment(ty) < 16) {
|
if (size(ty) > 8 && DtoAlignment(ty) < 16) {
|
||||||
// pass the aggregate as {int64, int64} to avoid wrong alignment
|
// pass the aggregate as {int64, int64} to avoid wrong alignment
|
||||||
integer2Rewrite.applyToIfNotObsolete(arg);
|
integer2Rewrite.applyToIfNotObsolete(arg);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include "gen/tollvm.h"
|
#include "gen/tollvm.h"
|
||||||
#include "gen/dcompute/abi-rewrites.h"
|
#include "gen/dcompute/abi-rewrites.h"
|
||||||
|
|
||||||
|
using namespace dmd;
|
||||||
|
|
||||||
struct SPIRVTargetABI : TargetABI {
|
struct SPIRVTargetABI : TargetABI {
|
||||||
DComputePointerRewrite pointerRewite;
|
DComputePointerRewrite pointerRewite;
|
||||||
llvm::CallingConv::ID callingConv(LINK l) override {
|
llvm::CallingConv::ID callingConv(LINK l) override {
|
||||||
|
@ -26,7 +28,7 @@ struct SPIRVTargetABI : TargetABI {
|
||||||
}
|
}
|
||||||
bool passByVal(TypeFunction *, Type *t) override {
|
bool passByVal(TypeFunction *, Type *t) override {
|
||||||
t = t->toBasetype();
|
t = t->toBasetype();
|
||||||
return ((t->ty == TY::Tsarray || t->ty == TY::Tstruct) && t->size() > 64);
|
return ((t->ty == TY::Tsarray || t->ty == TY::Tstruct) && size(t) > 64);
|
||||||
}
|
}
|
||||||
void rewriteFunctionType(IrFuncTy &fty) override {
|
void rewriteFunctionType(IrFuncTy &fty) override {
|
||||||
for (auto arg : fty.args) {
|
for (auto arg : fty.args) {
|
||||||
|
|
|
@ -216,7 +216,7 @@ bool X86_64TargetABI::returnInArg(TypeFunction *tf, bool) {
|
||||||
// Prefer a ref if the POD cannot be passed in registers, i.e., if the LLVM
|
// Prefer a ref if the POD cannot be passed in registers, i.e., if the LLVM
|
||||||
// ByVal attribute would be applied, *and* the size is > 16.
|
// ByVal attribute would be applied, *and* the size is > 16.
|
||||||
bool X86_64TargetABI::preferPassByRef(Type *t) {
|
bool X86_64TargetABI::preferPassByRef(Type *t) {
|
||||||
return t->size() > 16 && passInMemory(t->toBasetype());
|
return size(t) > 16 && passInMemory(t->toBasetype());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool X86_64TargetABI::passByVal(TypeFunction *tf, Type *t) {
|
bool X86_64TargetABI::passByVal(TypeFunction *tf, Type *t) {
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include "ir/irfunction.h"
|
#include "ir/irfunction.h"
|
||||||
#include "ir/irfuncty.h"
|
#include "ir/irfuncty.h"
|
||||||
|
|
||||||
|
using namespace dmd;
|
||||||
|
|
||||||
struct X86TargetABI : TargetABI {
|
struct X86TargetABI : TargetABI {
|
||||||
const bool isDarwin;
|
const bool isDarwin;
|
||||||
const bool isMSVC;
|
const bool isMSVC;
|
||||||
|
@ -208,7 +210,7 @@ struct X86TargetABI : TargetABI {
|
||||||
first.attrs.addAttribute(LLAttribute::InReg);
|
first.attrs.addAttribute(LLAttribute::InReg);
|
||||||
} else {
|
} else {
|
||||||
Type *firstTy = first.type->toBasetype();
|
Type *firstTy = first.type->toBasetype();
|
||||||
auto sz = firstTy->size();
|
auto sz = size(firstTy);
|
||||||
if (!firstTy->isfloating() && (sz == 1 || sz == 2 || sz == 4)) {
|
if (!firstTy->isfloating() && (sz == 1 || sz == 2 || sz == 4)) {
|
||||||
// rewrite aggregates as integers to make inreg work
|
// rewrite aggregates as integers to make inreg work
|
||||||
if (firstTy->ty == TY::Tstruct || firstTy->ty == TY::Tsarray) {
|
if (firstTy->ty == TY::Tstruct || firstTy->ty == TY::Tsarray) {
|
||||||
|
|
|
@ -633,7 +633,7 @@ DSliceValue *DtoNewDynArray(const Loc &loc, Type *arrayType, DValue *dim,
|
||||||
|
|
||||||
Type *eltType = arrayType->toBasetype()->nextOf();
|
Type *eltType = arrayType->toBasetype()->nextOf();
|
||||||
|
|
||||||
if (eltType->size() == 0)
|
if (size(eltType) == 0)
|
||||||
return DtoNullValue(arrayType, loc)->isSlice();
|
return DtoNullValue(arrayType, loc)->isSlice();
|
||||||
|
|
||||||
// get runtime function
|
// get runtime function
|
||||||
|
@ -989,8 +989,8 @@ DValue *DtoCastArray(const Loc &loc, DValue *u, Type *to) {
|
||||||
ptr = DtoArrayPtr(u);
|
ptr = DtoArrayPtr(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto fsize = fromtype->nextOf()->size();
|
const auto fsize = size(fromtype->nextOf());
|
||||||
const auto tsize = totype->nextOf()->size();
|
const auto tsize = size(totype->nextOf());
|
||||||
if (fsize != tsize) {
|
if (fsize != tsize) {
|
||||||
if (auto constLength = isaConstantInt(length)) {
|
if (auto constLength = isaConstantInt(length)) {
|
||||||
// compute new constant length: (constLength * fsize) / tsize
|
// compute new constant length: (constLength * fsize) / tsize
|
||||||
|
@ -1023,7 +1023,7 @@ DValue *DtoCastArray(const Loc &loc, DValue *u, Type *to) {
|
||||||
} else {
|
} else {
|
||||||
size_t tosize = static_cast<TypeSArray *>(totype)->dim->toInteger();
|
size_t tosize = static_cast<TypeSArray *>(totype)->dim->toInteger();
|
||||||
size_t i =
|
size_t i =
|
||||||
(tosize * totype->nextOf()->size() - 1) / fromtype->nextOf()->size();
|
(tosize * size(totype->nextOf()) - 1) / size(fromtype->nextOf());
|
||||||
DConstValue index(Type::tsize_t, DtoConstSize_t(i));
|
DConstValue index(Type::tsize_t, DtoConstSize_t(i));
|
||||||
DtoIndexBoundsCheck(loc, u, &index);
|
DtoIndexBoundsCheck(loc, u, &index);
|
||||||
ptr = DtoArrayPtr(u);
|
ptr = DtoArrayPtr(u);
|
||||||
|
|
|
@ -3240,7 +3240,7 @@ struct AsmProcessor {
|
||||||
(ty == TY::Tfloat80 || ty == TY::Timaginary80) &&
|
(ty == TY::Tfloat80 || ty == TY::Timaginary80) &&
|
||||||
!global.params.targetTriple->isWindowsMSVCEnvironment()
|
!global.params.targetTriple->isWindowsMSVCEnvironment()
|
||||||
? Extended_Ptr
|
? Extended_Ptr
|
||||||
: static_cast<PtrType>(v->type->size(Loc()));
|
: static_cast<PtrType>(dmd::size(v->type));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!operand->symbolDisplacement.length) {
|
if (!operand->symbolDisplacement.length) {
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
#include "gen/logger.h"
|
#include "gen/logger.h"
|
||||||
#include "gen/tollvm.h"
|
#include "gen/tollvm.h"
|
||||||
|
|
||||||
|
using namespace dmd;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -91,7 +93,7 @@ DValue *emitPointerOffset(Loc loc, DValue *base, Expression *offset,
|
||||||
if (byteOffset == 0) {
|
if (byteOffset == 0) {
|
||||||
llResult = llBase;
|
llResult = llBase;
|
||||||
} else {
|
} else {
|
||||||
const auto pointeeSize = pointeeType->size(loc);
|
const auto pointeeSize = size(pointeeType, loc);
|
||||||
if (pointeeSize && byteOffset % pointeeSize == 0) { // can do a nice GEP
|
if (pointeeSize && byteOffset % pointeeSize == 0) { // can do a nice GEP
|
||||||
llOffset = DtoConstSize_t(byteOffset / pointeeSize);
|
llOffset = DtoConstSize_t(byteOffset / pointeeSize);
|
||||||
} else { // need to cast base to i8*
|
} else { // need to cast base to i8*
|
||||||
|
@ -101,7 +103,7 @@ DValue *emitPointerOffset(Loc loc, DValue *base, Expression *offset,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Expression *noStrideInc =
|
Expression *noStrideInc =
|
||||||
extractNoStrideInc(offset, pointeeType->size(loc), negateOffset);
|
extractNoStrideInc(offset, size(pointeeType, loc), negateOffset);
|
||||||
auto rvals =
|
auto rvals =
|
||||||
evalSides(base, noStrideInc ? noStrideInc : offset, loadLhsAfterRhs);
|
evalSides(base, noStrideInc ? noStrideInc : offset, loadLhsAfterRhs);
|
||||||
llBase = DtoRVal(rvals.lhs);
|
llBase = DtoRVal(rvals.lhs);
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include "gen/logger.h"
|
#include "gen/logger.h"
|
||||||
#include "gen/tollvm.h"
|
#include "gen/tollvm.h"
|
||||||
|
|
||||||
|
using namespace dmd;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
llvm::StructType *DtoComplexType(Type *type) {
|
llvm::StructType *DtoComplexType(Type *type) {
|
||||||
|
@ -435,7 +437,7 @@ DValue *DtoCastComplex(const Loc &loc, DValue *val, Type *_to) {
|
||||||
Type *to = _to->toBasetype();
|
Type *to = _to->toBasetype();
|
||||||
Type *vty = val->type->toBasetype();
|
Type *vty = val->type->toBasetype();
|
||||||
if (to->iscomplex()) {
|
if (to->iscomplex()) {
|
||||||
if (vty->size() == to->size()) {
|
if (size(vty) == size(to)) {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,7 +445,7 @@ DValue *DtoCastComplex(const Loc &loc, DValue *val, Type *_to) {
|
||||||
DtoGetComplexParts(loc, val->type, val, re, im);
|
DtoGetComplexParts(loc, val->type, val, re, im);
|
||||||
LLType *toty = DtoComplexBaseType(to);
|
LLType *toty = DtoComplexBaseType(to);
|
||||||
|
|
||||||
if (to->size() < vty->size()) {
|
if (size(to) < size(vty)) {
|
||||||
re = gIR->ir->CreateFPTrunc(re, toty);
|
re = gIR->ir->CreateFPTrunc(re, toty);
|
||||||
im = gIR->ir->CreateFPTrunc(im, toty);
|
im = gIR->ir->CreateFPTrunc(im, toty);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -39,6 +39,8 @@
|
||||||
"-v128:128:128-v192:256:256-v256:256:256" \
|
"-v128:128:128-v192:256:256-v256:256:256" \
|
||||||
"-v512:512:512-v1024:1024:1024"
|
"-v512:512:512-v1024:1024:1024"
|
||||||
|
|
||||||
|
using namespace dmd;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class TargetOCL : public DComputeTarget {
|
class TargetOCL : public DComputeTarget {
|
||||||
bool usedImage;
|
bool usedImage;
|
||||||
|
@ -157,7 +159,6 @@ public:
|
||||||
ss << "uchar";
|
ss << "uchar";
|
||||||
else if (ty == TY::Tvector) {
|
else if (ty == TY::Tvector) {
|
||||||
TypeVector *vec = static_cast<TypeVector *>(t);
|
TypeVector *vec = static_cast<TypeVector *>(t);
|
||||||
auto size = vec->size(Loc());
|
|
||||||
auto basety = vec->basetype->ty;
|
auto basety = vec->basetype->ty;
|
||||||
if (basety == TY::Tint8)
|
if (basety == TY::Tint8)
|
||||||
ss << "char";
|
ss << "char";
|
||||||
|
@ -165,7 +166,7 @@ public:
|
||||||
ss << "uchar";
|
ss << "uchar";
|
||||||
else
|
else
|
||||||
ss << vec->basetype->toChars();
|
ss << vec->basetype->toChars();
|
||||||
ss << (int)size;
|
ss << (int)size(vec);
|
||||||
} else
|
} else
|
||||||
ss << t->toChars();
|
ss << t->toChars();
|
||||||
return ss.str();
|
return ss.str();
|
||||||
|
|
|
@ -198,7 +198,7 @@ llvm::FunctionType *DtoFunctionType(Type *type, IrFuncTy &irFty, Type *thistype,
|
||||||
attrs.addAttribute(LLAttribute::NonNull);
|
attrs.addAttribute(LLAttribute::NonNull);
|
||||||
attrs.addAttribute(LLAttribute::NoUndef);
|
attrs.addAttribute(LLAttribute::NoUndef);
|
||||||
} else {
|
} else {
|
||||||
attrs.addDereferenceableAttr(loweredDType->size());
|
attrs.addDereferenceableAttr(size(loweredDType));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (abi->passByVal(f, loweredDType)) {
|
if (abi->passByVal(f, loweredDType)) {
|
||||||
|
|
|
@ -501,8 +501,8 @@ DValue *DtoCastInt(const Loc &loc, DValue *val, Type *_to) {
|
||||||
return new DImValue(_to, rval);
|
return new DImValue(_to, rval);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t fromsz = from->size();
|
size_t fromsz = size(from);
|
||||||
size_t tosz = to->size();
|
size_t tosz = size(to);
|
||||||
|
|
||||||
if (to->ty == TY::Tbool) {
|
if (to->ty == TY::Tbool) {
|
||||||
LLValue *zero = LLConstantInt::get(rval->getType(), 0, false);
|
LLValue *zero = LLConstantInt::get(rval->getType(), 0, false);
|
||||||
|
@ -584,8 +584,8 @@ DValue *DtoCastFloat(const Loc &loc, DValue *val, Type *to) {
|
||||||
Type *fromtype = val->type->toBasetype();
|
Type *fromtype = val->type->toBasetype();
|
||||||
assert(fromtype->isfloating());
|
assert(fromtype->isfloating());
|
||||||
|
|
||||||
size_t fromsz = fromtype->size();
|
size_t fromsz = size(fromtype);
|
||||||
size_t tosz = totype->size();
|
size_t tosz = size(totype);
|
||||||
|
|
||||||
LLValue *rval;
|
LLValue *rval;
|
||||||
|
|
||||||
|
@ -656,7 +656,7 @@ DValue *DtoCastVector(const Loc &loc, DValue *val, Type *to) {
|
||||||
LLValue *array = DtoAllocaDump(vector, tolltype, DtoAlignment(val->type));
|
LLValue *array = DtoAllocaDump(vector, tolltype, DtoAlignment(val->type));
|
||||||
return new DLValue(to, array);
|
return new DLValue(to, array);
|
||||||
}
|
}
|
||||||
if (totype->ty == TY::Tvector && to->size() == val->type->size()) {
|
if (totype->ty == TY::Tvector && size(to) == size(val->type)) {
|
||||||
return new DImValue(to, DtoBitCast(DtoRVal(val), tolltype));
|
return new DImValue(to, DtoBitCast(DtoRVal(val), tolltype));
|
||||||
}
|
}
|
||||||
error(loc, "invalid cast from `%s` to `%s`", val->type->toChars(),
|
error(loc, "invalid cast from `%s` to `%s`", val->type->toChars(),
|
||||||
|
@ -918,7 +918,7 @@ void DtoVarDeclaration(VarDeclaration *vd) {
|
||||||
if (isRealAlloca) {
|
if (isRealAlloca) {
|
||||||
// The lifetime of a stack variable starts from the point it is declared
|
// The lifetime of a stack variable starts from the point it is declared
|
||||||
gIR->funcGen().localVariableLifetimeAnnotator.addLocalVariable(
|
gIR->funcGen().localVariableLifetimeAnnotator.addLocalVariable(
|
||||||
allocainst, DtoConstUlong(type->size()));
|
allocainst, DtoConstUlong(size(type)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1146,9 +1146,9 @@ LLConstant *DtoConstExpInit(const Loc &loc, Type *targetType, Expression *exp) {
|
||||||
if (baseTargetType->ty == TY::Tsarray) {
|
if (baseTargetType->ty == TY::Tsarray) {
|
||||||
Logger::println("Building constant array initializer from scalar.");
|
Logger::println("Building constant array initializer from scalar.");
|
||||||
|
|
||||||
assert(baseValType->size() > 0);
|
assert(size(baseValType) > 0);
|
||||||
const auto numTotalVals = baseTargetType->size() / baseValType->size();
|
const auto numTotalVals = size(baseTargetType) / size(baseValType);
|
||||||
assert(baseTargetType->size() % baseValType->size() == 0);
|
assert(size(baseTargetType) % size(baseValType) == 0);
|
||||||
|
|
||||||
// may be a multi-dimensional array init, e.g., `char[2][3] x = 0xff`
|
// may be a multi-dimensional array init, e.g., `char[2][3] x = 0xff`
|
||||||
baseValType = stripModifiers(baseValType);
|
baseValType = stripModifiers(baseValType);
|
||||||
|
|
|
@ -272,7 +272,7 @@ void emitABIReturnAsmStmt(IRAsmBlock *asmblock, const Loc &loc,
|
||||||
if (triple.getArch() == llvm::Triple::x86) {
|
if (triple.getArch() == llvm::Triple::x86) {
|
||||||
if (rt->isintegral() || rt->ty == TY::Tpointer || rt->ty == TY::Tclass ||
|
if (rt->isintegral() || rt->ty == TY::Tpointer || rt->ty == TY::Tclass ||
|
||||||
rt->ty == TY::Taarray) {
|
rt->ty == TY::Taarray) {
|
||||||
if (rt->size() == 8) {
|
if (size(rt) == 8) {
|
||||||
as->out.c = "=A,";
|
as->out.c = "=A,";
|
||||||
} else {
|
} else {
|
||||||
as->out.c = "={ax},";
|
as->out.c = "={ax},";
|
||||||
|
|
|
@ -199,7 +199,7 @@ public:
|
||||||
const dinteger_t byteOffset = e->e2->toInteger();
|
const dinteger_t byteOffset = e->e2->toInteger();
|
||||||
|
|
||||||
LLConstant *llResult = nullptr;
|
LLConstant *llResult = nullptr;
|
||||||
const auto pointeeSize = pointeeType->size(e->loc);
|
const auto pointeeSize = size(pointeeType, e->loc);
|
||||||
if (pointeeSize && byteOffset % pointeeSize == 0) { // can do a nice GEP
|
if (pointeeSize && byteOffset % pointeeSize == 0) { // can do a nice GEP
|
||||||
LLConstant *llOffset = DtoConstSize_t(byteOffset / pointeeSize);
|
LLConstant *llOffset = DtoConstSize_t(byteOffset / pointeeSize);
|
||||||
if (negateOffset)
|
if (negateOffset)
|
||||||
|
@ -286,11 +286,11 @@ public:
|
||||||
StringExp *strexp = static_cast<StringExp*>(e1);
|
StringExp *strexp = static_cast<StringExp*>(e1);
|
||||||
size_t datalen = strexp->sz * strexp->len;
|
size_t datalen = strexp->sz * strexp->len;
|
||||||
Type* eltype = tb->nextOf()->toBasetype();
|
Type* eltype = tb->nextOf()->toBasetype();
|
||||||
if (datalen % eltype->size() != 0) {
|
if (datalen % size(eltype) != 0) {
|
||||||
error("the sizes don't line up");
|
error("the sizes don't line up");
|
||||||
return e1->toConstElem(p);
|
return e1->toConstElem(p);
|
||||||
}
|
}
|
||||||
size_t arrlen = datalen / eltype->size();
|
size_t arrlen = datalen / size(eltype);
|
||||||
#endif
|
#endif
|
||||||
error(
|
error(
|
||||||
e->loc,
|
e->loc,
|
||||||
|
|
|
@ -97,7 +97,7 @@ static void write_struct_literal(Loc loc, LLValue *mem, StructDeclaration *sd,
|
||||||
|
|
||||||
// Skip zero-sized fields such as zero-length static arrays: `ubyte[0]
|
// Skip zero-sized fields such as zero-length static arrays: `ubyte[0]
|
||||||
// data`.
|
// data`.
|
||||||
if (field->type->size() == 0)
|
if (size(field->type) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// the initializer expression may be null for overridden overlapping fields
|
// the initializer expression may be null for overridden overlapping fields
|
||||||
|
|
|
@ -58,7 +58,7 @@ bool DtoIsReturnInArg(CallExp *ce) {
|
||||||
|
|
||||||
void DtoAddExtendAttr(Type *type, llvm::AttrBuilder &attrs) {
|
void DtoAddExtendAttr(Type *type, llvm::AttrBuilder &attrs) {
|
||||||
type = type->toBasetype();
|
type = type->toBasetype();
|
||||||
if (type->isintegral() && type->ty != TY::Tvector && type->size() <= 2) {
|
if (type->isintegral() && type->ty != TY::Tvector && size(type) <= 2) {
|
||||||
attrs.addAttribute(type->isunsigned() ? LLAttribute::ZExt
|
attrs.addAttribute(type->isunsigned() ? LLAttribute::ZExt
|
||||||
: LLAttribute::SExt);
|
: LLAttribute::SExt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,7 +171,7 @@ static llvm::Constant *FillSArrayDims(Type *arrTypeD, llvm::Constant *init) {
|
||||||
// the size without doing an expensive recursive D <-> LLVM type comparison.
|
// the size without doing an expensive recursive D <-> LLVM type comparison.
|
||||||
// The better way to solve this would be to just fix the initializer
|
// The better way to solve this would be to just fix the initializer
|
||||||
// codegen in any place where a scalar initializer might still be generated.
|
// codegen in any place where a scalar initializer might still be generated.
|
||||||
if (gDataLayout->getTypeAllocSize(init->getType()) >= arrTypeD->size()) {
|
if (gDataLayout->getTypeAllocSize(init->getType()) >= size(arrTypeD)) {
|
||||||
return init;
|
return init;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include "gen/llvmhelpers.h"
|
#include "gen/llvmhelpers.h"
|
||||||
#include "llvm/IR/DerivedTypes.h"
|
#include "llvm/IR/DerivedTypes.h"
|
||||||
|
|
||||||
|
using namespace dmd;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -97,7 +99,7 @@ void AggrTypeBuilder::addAggregate(
|
||||||
|
|
||||||
bool haveExplicitInit =
|
bool haveExplicitInit =
|
||||||
explicitInits && explicitInits->find(field) != explicitInits->end();
|
explicitInits && explicitInits->find(field) != explicitInits->end();
|
||||||
uint64_t fieldSize = field->type->size();
|
uint64_t fieldSize = size(field->type);
|
||||||
|
|
||||||
const bool isBitField = field->isBitFieldDeclaration() != nullptr;
|
const bool isBitField = field->isBitFieldDeclaration() != nullptr;
|
||||||
if (isBitField) {
|
if (isBitField) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue