Skip to content

Commit

Permalink
Merge pull request #4664 from kinke/opaque_bitcast
Browse files Browse the repository at this point in the history
Skip superfluous IR pointer bitcasts, now that they are always opaque
  • Loading branch information
kinke committed May 23, 2024
2 parents 4260031 + 4eff494 commit dedd0c2
Show file tree
Hide file tree
Showing 41 changed files with 262 additions and 592 deletions.
49 changes: 15 additions & 34 deletions gen/aa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,11 @@
using namespace dmd;

// returns the keytype typeinfo
static LLConstant *to_keyti(const Loc &loc, DValue *aa, LLType *targetType) {
static LLConstant *to_keyti(const Loc &loc, DValue *aa) {
// keyti param
assert(aa->type->toBasetype()->ty == TY::Taarray);
TypeAArray *aatype = static_cast<TypeAArray *>(aa->type->toBasetype());
LLConstant *ti = DtoTypeInfoOf(loc, aatype->index, /*base=*/false);
return DtoBitCast(ti, targetType);
return DtoTypeInfoOf(loc, aatype->index);
}

////////////////////////////////////////////////////////////////////////////////
Expand All @@ -49,35 +48,28 @@ DLValue *DtoAAIndex(const Loc &loc, Type *type, DValue *aa, DValue *key,
// first get the runtime function
llvm::Function *func =
getRuntimeFunction(loc, gIR->module, lvalue ? "_aaGetY" : "_aaInX");
LLFunctionType *funcTy = func->getFunctionType();

// aa param
LLValue *aaval = lvalue ? DtoLVal(aa) : DtoRVal(aa);
aaval = DtoBitCast(aaval, funcTy->getParamType(0));
assert(aaval->getType()->isPointerTy());

// pkey param
LLValue *pkey = makeLValue(loc, key);
pkey = DtoBitCast(pkey, funcTy->getParamType(lvalue ? 3 : 2));

// call runtime
LLValue *ret;
if (lvalue) {
auto t = mutableOf(unSharedOf(aa->type));
LLValue *rawAATI = DtoTypeInfoOf(loc, t, /*base=*/false);
LLValue *castedAATI = DtoBitCast(rawAATI, funcTy->getParamType(1));
LLValue *aati = DtoTypeInfoOf(loc, t);
LLValue *valsize = DtoConstSize_t(getTypeAllocSize(DtoType(type)));
ret = gIR->CreateCallOrInvoke(func, aaval, castedAATI, valsize, pkey,
ret = gIR->CreateCallOrInvoke(func, aaval, aati, valsize, pkey,
"aa.index");
} else {
LLValue *keyti = to_keyti(loc, aa, funcTy->getParamType(1));
LLValue *keyti = to_keyti(loc, aa);
ret = gIR->CreateCallOrInvoke(func, aaval, keyti, pkey, "aa.index");
}

// cast return value
LLType *targettype = DtoPtrToType(type);
if (ret->getType() != targettype) {
ret = DtoBitCast(ret, targettype);
}
assert(ret->getType()->isPointerTy());

// Only check bounds for rvalues ('aa[key]').
// Lvalue use ('aa[key] = value') auto-adds an element.
Expand Down Expand Up @@ -112,34 +104,25 @@ DValue *DtoAAIn(const Loc &loc, Type *type, DValue *aa, DValue *key) {

// first get the runtime function
llvm::Function *func = getRuntimeFunction(loc, gIR->module, "_aaInX");
LLFunctionType *funcTy = func->getFunctionType();

IF_LOG Logger::cout() << "_aaIn = " << *func << '\n';

// aa param
LLValue *aaval = DtoRVal(aa);
assert(aaval->getType()->isPointerTy());
IF_LOG {
Logger::cout() << "aaval: " << *aaval << '\n';
Logger::cout() << "totype: " << *funcTy->getParamType(0) << '\n';
}
aaval = DtoBitCast(aaval, funcTy->getParamType(0));

// keyti param
LLValue *keyti = to_keyti(loc, aa, funcTy->getParamType(1));
LLValue *keyti = to_keyti(loc, aa);

// pkey param
LLValue *pkey = makeLValue(loc, key);
pkey = DtoBitCast(pkey, getVoidPtrType());

// call runtime
LLValue *ret = gIR->CreateCallOrInvoke(func, aaval, keyti, pkey, "aa.in");

// cast return value
LLType *targettype = DtoType(type);
if (ret->getType() != targettype) {
ret = DtoBitCast(ret, targettype);
}

return new DImValue(type, ret);
}

Expand All @@ -156,24 +139,21 @@ DValue *DtoAARemove(const Loc &loc, DValue *aa, DValue *key) {

// first get the runtime function
llvm::Function *func = getRuntimeFunction(loc, gIR->module, "_aaDelX");
LLFunctionType *funcTy = func->getFunctionType();

IF_LOG Logger::cout() << "_aaDel = " << *func << '\n';

// aa param
LLValue *aaval = DtoRVal(aa);
assert(aaval->getType()->isPointerTy());
IF_LOG {
Logger::cout() << "aaval: " << *aaval << '\n';
Logger::cout() << "totype: " << *funcTy->getParamType(0) << '\n';
}
aaval = DtoBitCast(aaval, funcTy->getParamType(0));

// keyti param
LLValue *keyti = to_keyti(loc, aa, funcTy->getParamType(1));
LLValue *keyti = to_keyti(loc, aa);

// pkey param
LLValue *pkey = makeLValue(loc, key);
pkey = DtoBitCast(pkey, funcTy->getParamType(2));

// call runtime
LLValue *res = gIR->CreateCallOrInvoke(func, aaval, keyti, pkey);
Expand All @@ -188,10 +168,11 @@ LLValue *DtoAAEquals(const Loc &loc, EXP op, DValue *l, DValue *r) {
assert(t == r->type->toBasetype() &&
"aa equality is only defined for aas of same type");
llvm::Function *func = getRuntimeFunction(loc, gIR->module, "_aaEqual");
LLFunctionType *funcTy = func->getFunctionType();

LLValue *aaval = DtoBitCast(DtoRVal(l), funcTy->getParamType(1));
LLValue *abval = DtoBitCast(DtoRVal(r), funcTy->getParamType(2));
LLValue *aaval = DtoRVal(l);
assert(aaval->getType()->isPointerTy());
LLValue *abval = DtoRVal(r);
assert(abval->getType()->isPointerTy());
LLValue *aaTypeInfo = DtoTypeInfoOf(loc, t);
LLValue *res =
gIR->CreateCallOrInvoke(func, aaTypeInfo, aaval, abval, "aaEqRes");
Expand Down
10 changes: 5 additions & 5 deletions gen/abi/abi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ using namespace dmd;

llvm::Value *ABIRewrite::getRVal(Type *dty, LLValue *v) {
llvm::Type *t = DtoType(dty);
return DtoLoad(t, DtoBitCast(getLVal(dty, v), t->getPointerTo()));
return DtoLoad(t, getLVal(dty, v));
}

//////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -191,8 +191,8 @@ void TargetABI::rewriteVarargs(IrFuncTy &fty,
//////////////////////////////////////////////////////////////////////////////

LLValue *TargetABI::prepareVaStart(DLValue *ap) {
// pass a i8* pointer to ap to LLVM's va_start intrinsic
return DtoBitCast(DtoLVal(ap), getVoidPtrType());
// pass an opaque pointer to ap to LLVM's va_start intrinsic
return DtoLVal(ap);
}

//////////////////////////////////////////////////////////////////////////////
Expand All @@ -209,8 +209,8 @@ void TargetABI::vaCopy(DLValue *dest, DValue *src) {
//////////////////////////////////////////////////////////////////////////////

LLValue *TargetABI::prepareVaArg(DLValue *ap) {
// pass a i8* pointer to ap to LLVM's va_arg intrinsic
return DtoBitCast(DtoLVal(ap), getVoidPtrType());
// pass an opaque pointer to ap to LLVM's va_arg intrinsic
return DtoLVal(ap);
}

//////////////////////////////////////////////////////////////////////////////
Expand Down
3 changes: 1 addition & 2 deletions gen/abi/generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ struct BaseBitcastABIRewrite : ABIRewrite {
return DtoLoad(asType, paddedDump, name);
}

address = DtoBitCast(address, getPtrToType(asType));
return DtoLoad(asType, address, name);
}

Expand Down Expand Up @@ -248,7 +247,7 @@ struct IndirectByvalRewrite : ABIRewrite {
}

LLValue *getLVal(Type *dty, LLValue *v) override {
return DtoBitCast(v, DtoPtrToType(dty));
return v;
}

LLType *type(Type *t) override { return DtoPtrToType(t); }
Expand Down
6 changes: 2 additions & 4 deletions gen/abi/riscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,7 @@ struct HardfloatRewrite : ABIRewrite {
DtoRawAlloca(asType, alignment, ".HardfloatRewrite_arg_storage");
for (unsigned i = 0; i < (unsigned)flat.length; ++i) {
DtoMemCpy(DtoGEP(asType, buffer, 0, i),
DtoGEP1(getI8Type(), DtoBitCast(address, getVoidPtrType()),
flat.fields[i].offset),
DtoGEP1(getI8Type(), address, flat.fields[i].offset),
DtoConstSize_t(flat.fields[i].ty->size()));
}
return DtoLoad(asType, buffer, ".HardfloatRewrite_arg");
Expand All @@ -126,8 +125,7 @@ struct HardfloatRewrite : ABIRewrite {
LLValue *ret = DtoRawAlloca(DtoType(dty), alignment,
".HardfloatRewrite_param_storage");
for (unsigned i = 0; i < (unsigned)flat.length; ++i) {
DtoMemCpy(DtoGEP1(getI8Type(), DtoBitCast(ret, getVoidPtrType()),
flat.fields[i].offset),
DtoMemCpy(DtoGEP1(getI8Type(), ret, flat.fields[i].offset),
DtoGEP(asType, buffer, 0, i),
DtoConstSize_t(flat.fields[i].ty->size()));
}
Expand Down
14 changes: 6 additions & 8 deletions gen/abi/x86-64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,27 +352,25 @@ LLValue *X86_64TargetABI::prepareVaStart(DLValue *ap) {
// invoking va_start, we first need to allocate the actual __va_list_tag struct
// and set `ap` to its address.
LLValue *valistmem = DtoRawAlloca(getValistType(), 0, "__va_list_mem");
DtoStore(valistmem,
DtoBitCast(DtoLVal(ap), getPtrToType(valistmem->getType())));
// Pass a i8* pointer to the actual struct to LLVM's va_start intrinsic.
return DtoBitCast(valistmem, getVoidPtrType());
DtoStore(valistmem, DtoLVal(ap));
// Pass an opaque pointer to the actual struct to LLVM's va_start intrinsic.
return valistmem;
}

void X86_64TargetABI::vaCopy(DLValue *dest, DValue *src) {
// Analog to va_start, we first need to allocate a new __va_list_tag struct on
// the stack and set `dest` to its address.
LLValue *valistmem = DtoRawAlloca(getValistType(), 0, "__va_list_mem");
DtoStore(valistmem,
DtoBitCast(DtoLVal(dest), getPtrToType(valistmem->getType())));
DtoStore(valistmem, DtoLVal(dest));
// Then fill the new struct with a bitcopy of the source struct.
// `src` is a __va_list_tag* pointer to the source struct.
DtoMemCpy(getValistType(), valistmem, DtoRVal(src));
}

LLValue *X86_64TargetABI::prepareVaArg(DLValue *ap) {
// Pass a i8* pointer to the actual __va_list_tag struct to LLVM's va_arg
// Pass an opaque pointer to the actual __va_list_tag struct to LLVM's va_arg
// intrinsic.
return DtoBitCast(DtoRVal(ap), getVoidPtrType());
return DtoRVal(ap);
}

Type *X86_64TargetABI::vaListType() {
Expand Down
Loading

0 comments on commit dedd0c2

Please sign in to comment.