Slightly refactor ABIRewrite interface for clarification

* put(): pass DValue alone, without explicit D type
* get(): pass LLValue instead of a faked DValue
This commit is contained in:
Martin 2015-09-25 18:37:28 +02:00
parent 9e194bfe2c
commit 80c677be46
9 changed files with 68 additions and 76 deletions

View file

@ -82,24 +82,23 @@ struct LLTypeMemoryLayout
/// Removes padding fields for (non-union-containing!) structs
struct RemoveStructPadding : ABIRewrite {
/// get a rewritten value back to its original form
LLValue* get(Type* dty, DValue* v) {
LLValue* get(Type* dty, LLValue* v) {
LLValue* lval = DtoAlloca(dty, ".rewritetmp");
getL(dty, v, lval);
return lval;
}
/// get a rewritten value back to its original form and store result in provided lvalue
/// this one is optional and defaults to calling the one above
void getL(Type* dty, DValue* v, LLValue* lval) {
void getL(Type* dty, LLValue* v, LLValue* lval) {
// Make sure the padding is zero, so struct comparisons work.
// TODO: Only do this if there's padding, and/or only initialize padding.
DtoMemSetZero(lval, DtoConstSize_t(getTypePaddedSize(DtoType(dty))));
DtoPaddedStruct(dty->toBasetype(), v->getRVal(), lval);
DtoPaddedStruct(dty->toBasetype(), v, lval);
}
/// put out rewritten value
LLValue* put(Type* dty, DValue* v) {
return DtoUnpaddedStruct(dty->toBasetype(), v->getRVal());
LLValue* put(DValue* v) {
return DtoUnpaddedStruct(v->getType()->toBasetype(), v->getRVal());
}
/// return the transformed type for this rewrite
@ -154,25 +153,22 @@ struct IntegerRewrite : ABIRewrite
return LLTypeMemoryLayout::typesAreEquivalent(llType, integerType);
}
LLValue* get(Type* dty, DValue* dv)
LLValue* get(Type* dty, LLValue* v)
{
LLValue* integerDump = DtoAllocaDump(dv, ".IntegerRewrite_dump");
LLValue* integerDump = DtoAllocaDump(v, dty, ".IntegerRewrite_dump");
LLType* type = DtoType(dty);
return loadFromMemory(integerDump, type, ".IntegerRewrite_getResult");
}
void getL(Type* dty, DValue* dv, LLValue* lval)
void getL(Type* dty, LLValue* v, LLValue* lval)
{
LLValue* integer = dv->getRVal();
storeToMemory(integer, lval);
storeToMemory(v, lval);
}
LLValue* put(Type* dty, DValue* dv)
LLValue* put(DValue* dv)
{
assert(dty == dv->getType());
LLValue* address = getAddressOf(dv);
LLType* integerType = getIntegerType(dty->size());
LLType* integerType = getIntegerType(dv->getType()->size());
return loadFromMemory(address, integerType, ".IntegerRewrite_putResult");
}
@ -204,21 +200,19 @@ struct ExplicitByvalRewrite : ABIRewrite
ExplicitByvalRewrite(size_t alignment = 16) : alignment(alignment)
{ }
LLValue* get(Type* dty, DValue* v)
LLValue* get(Type* dty, LLValue* v)
{
LLValue* pointer = v->getRVal();
return DtoLoad(pointer, ".ExplicitByvalRewrite_getResult");
return DtoLoad(v, ".ExplicitByvalRewrite_getResult");
}
void getL(Type* dty, DValue* v, LLValue* lval)
void getL(Type* dty, LLValue* v, LLValue* lval)
{
LLValue* pointer = v->getRVal();
DtoAggrCopy(lval, pointer);
DtoAggrCopy(lval, v);
}
LLValue* put(Type* dty, DValue* v)
LLValue* put(DValue* v)
{
if (DtoIsPassedByRef(dty))
if (DtoIsPassedByRef(v->getType()))
{
LLValue* originalPointer = v->getRVal();
LLType* type = originalPointer->getType()->getPointerElementType();
@ -227,8 +221,7 @@ struct ExplicitByvalRewrite : ABIRewrite
return copyForCallee;
}
LLValue* copyForCallee = DtoAllocaDump(v->getRVal(), alignment, ".ExplicitByvalRewrite_putResult");
return copyForCallee;
return DtoAllocaDump(v->getRVal(), alignment, ".ExplicitByvalRewrite_putResult");
}
LLType* type(Type* dty, LLType* t)

View file

@ -160,22 +160,21 @@ namespace {
* memory so that it's then readable as the other type (i.e., bit-casting).
*/
struct X86_64_C_struct_rewrite : ABIRewrite {
LLValue* get(Type* dty, DValue* v)
LLValue* get(Type* dty, LLValue* v)
{
LLValue* address = DtoAllocaDump(v, ".X86_64_C_struct_rewrite_dump");
LLValue* address = DtoAllocaDump(v, dty, ".X86_64_C_struct_rewrite_dump");
LLType* type = DtoType(dty);
return loadFromMemory(address, type, ".X86_64_C_struct_rewrite_getResult");
}
void getL(Type* dty, DValue* v, LLValue* lval) {
storeToMemory(v->getRVal(), lval);
void getL(Type* dty, LLValue* v, LLValue* lval) {
storeToMemory(v, lval);
}
LLValue* put(Type* dty, DValue* v) {
assert(dty == v->getType());
LLValue* put(DValue* v) {
LLValue* address = getAddressOf(v);
LLType* abiTy = getAbiType(dty);
LLType* abiTy = getAbiType(v->getType());
assert(abiTy && "Why are we rewriting a non-rewritten type?");
return loadFromMemory(address, abiTy, ".X86_64_C_struct_rewrite_putResult");
@ -195,18 +194,15 @@ struct X86_64_C_struct_rewrite : ABIRewrite {
* the ByVal LLVM attribute.
*/
struct ImplicitByvalRewrite : ABIRewrite {
LLValue* get(Type* dty, DValue* v) {
LLValue* pointer = v->getRVal();
return DtoLoad(pointer, ".ImplicitByvalRewrite_getResult");
LLValue* get(Type* dty, LLValue* v) {
return DtoLoad(v, ".ImplicitByvalRewrite_getResult");
}
void getL(Type* dty, DValue* v, LLValue* lval) {
LLValue* pointer = v->getRVal();
DtoAggrCopy(lval, pointer);
void getL(Type* dty, LLValue* v, LLValue* lval) {
DtoAggrCopy(lval, v);
}
LLValue* put(Type* dty, DValue* v) {
assert(dty == v->getType());
LLValue* put(DValue* v) {
return getAddressOf(v);
}

View file

@ -28,7 +28,7 @@
//////////////////////////////////////////////////////////////////////////////
void ABIRewrite::getL(Type* dty, DValue* v, LLValue* lval)
void ABIRewrite::getL(Type* dty, LLValue* v, LLValue* lval)
{
LLValue* rval = get(dty, v);
assert(rval->getType() == lval->getType()->getContainedType(0));

View file

@ -44,14 +44,14 @@ struct ABIRewrite
virtual ~ABIRewrite() {}
/// get a rewritten value back to its original form
virtual llvm::Value* get(Type* dty, DValue* v) = 0;
virtual llvm::Value* get(Type* dty, llvm::Value* v) = 0;
/// get a rewritten value back to its original form and store result in provided lvalue
/// this one is optional and defaults to calling the one above
virtual void getL(Type* dty, DValue* v, llvm::Value* lval);
virtual void getL(Type* dty, llvm::Value* v, llvm::Value* lval);
/// put out rewritten value
virtual llvm::Value* put(Type* dty, DValue* v) = 0;
virtual llvm::Value* put(DValue* v) = 0;
/// should return the transformed type for this rewrite
virtual llvm::Type* type(Type* dty, llvm::Type* t) = 0;

View file

@ -867,8 +867,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
LLValue* mem = DtoAlloca(irparam->arg->type, vd->ident->toChars());
// let the abi transform the argument back first
DImValue arg_dval(vd->type, irparam->value);
irFty.getParam(vd->type, llArgIdx, &arg_dval, mem);
irFty.getParam(vd->type, llArgIdx, irparam->value, mem);
// set the arg var value to the alloca
irparam->value = mem;

View file

@ -191,7 +191,7 @@ public:
dval = toElemDtor(ae);
}
// do abi specific transformations on the return value
returnValue = getIrFunc(irs->func()->decl)->irFty.putRet(stmt->exp->type, dval);
returnValue = getIrFunc(irs->func()->decl)->irFty.putRet(dval);
}
IF_LOG Logger::cout() << "return value is '" << returnValue << "'\n";

View file

@ -166,9 +166,9 @@ static void addExplicitArguments(std::vector<LLValue*>& args, AttrSet& attrs,
llvm::Value* llVal = NULL;
if (isVararg)
llVal = irFty.putParam(argType, *irArg, argval);
llVal = irFty.putParam(*irArg, argval);
else
llVal = irFty.putParam(argType, i, argval);
llVal = irFty.putParam(i, argval);
const size_t llArgIdx = implicitLLArgCount +
(irFty.reverseParams ? explicitLLArgCount - i - 1 : i);
@ -806,18 +806,17 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
if (!intrinsic && !retinptr)
{
// do abi specific return value fixups
DImValue dretval(returntype, retllval);
if (storeReturnValueOnStack)
{
Logger::println("Storing return value to stack slot");
LLValue* mem = DtoAlloca(returntype);
irFty.getRet(returntype, &dretval, mem);
irFty.getRet(returntype, retllval, mem);
retllval = mem;
storeReturnValueOnStack = false;
}
else
{
retllval = irFty.getRet(returntype, &dretval);
retllval = irFty.getRet(returntype, retllval);
storeReturnValueOnStack =
(returnTy == Tstruct && !isaPointer(retllval)) ||
(returnTy == Tsarray && isaArray(retllval));

View file

@ -19,65 +19,70 @@ IrFuncTyArg::IrFuncTyArg(Type* t, bool bref, const AttrBuilder& a)
: type(t), parametersIdx(0),
ltype(t != Type::tvoid && bref ? DtoType(t->pointerTo()) : DtoType(t)),
attrs(a), byref(bref), rewrite(0)
{
}
{}
bool IrFuncTyArg::isInReg() const { return attrs.contains(LDC_ATTRIBUTE(InReg)); }
bool IrFuncTyArg::isSRet() const { return attrs.contains(LDC_ATTRIBUTE(StructRet)); }
bool IrFuncTyArg::isByVal() const { return attrs.contains(LDC_ATTRIBUTE(ByVal)); }
llvm::Value* IrFuncTy::putRet(Type* dty, DValue* val)
llvm::Value* IrFuncTy::putRet(DValue* dval)
{
assert(!arg_sret);
if (ret->rewrite) {
Logger::println("Rewrite: putRet");
LOG_SCOPE
return ret->rewrite->put(dty, val);
return ret->rewrite->put(dval);
}
return val->getRVal();
return dval->getRVal();
}
llvm::Value* IrFuncTy::getRet(Type* dty, DValue* val)
llvm::Value* IrFuncTy::getRet(Type* dty, LLValue* val)
{
assert(!arg_sret);
if (ret->rewrite) {
Logger::println("Rewrite: getRet");
LOG_SCOPE
return ret->rewrite->get(dty, val);
}
return val->getRVal();
return val;
}
void IrFuncTy::getRet(Type* dty, DValue* val, llvm::Value* lval)
void IrFuncTy::getRet(Type* dty, LLValue* val, LLValue* address)
{
assert(!arg_sret);
if (ret->rewrite) {
Logger::println("Rewrite: getRet (getL)");
LOG_SCOPE
ret->rewrite->getL(dty, val, lval);
ret->rewrite->getL(dty, val, address);
return;
}
DtoStoreZextI8(val->getRVal(), lval);
DtoStoreZextI8(val, address);
}
llvm::Value* IrFuncTy::putParam(Type* dty, size_t idx, DValue* val)
llvm::Value* IrFuncTy::putParam(size_t idx, DValue* dval)
{
assert(idx < args.size() && "invalid putParam");
return putParam(dty, *args[idx], val);
return putParam(*args[idx], dval);
}
llvm::Value* IrFuncTy::putParam(Type* dty, const IrFuncTyArg& arg, DValue* val)
llvm::Value* IrFuncTy::putParam(const IrFuncTyArg& arg, DValue* dval)
{
if (arg.rewrite) {
Logger::println("Rewrite: putParam");
LOG_SCOPE
return arg.rewrite->put(dty, val);
return arg.rewrite->put(dval);
}
return val->getRVal();
return dval->getRVal();
}
void IrFuncTy::getParam(Type* dty, size_t idx, DValue* val, llvm::Value* lval)
void IrFuncTy::getParam(Type* dty, size_t idx, LLValue* val, LLValue* address)
{
assert(idx < args.size() && "invalid getParam");
@ -85,9 +90,9 @@ void IrFuncTy::getParam(Type* dty, size_t idx, DValue* val, llvm::Value* lval)
{
Logger::println("Rewrite: getParam (getL)");
LOG_SCOPE
args[idx]->rewrite->getL(dty, val, lval);
args[idx]->rewrite->getL(dty, val, address);
return;
}
DtoStoreZextI8(val->getRVal(), lval);
DtoStoreZextI8(val, address);
}

View file

@ -133,13 +133,13 @@ struct IrFuncTy
tag(NULL)
{}
llvm::Value* putRet(Type* dty, DValue* dval);
llvm::Value* getRet(Type* dty, DValue* dval);
void getRet(Type* dty, DValue* dval, llvm::Value* lval);
llvm::Value* putRet(DValue* dval);
llvm::Value* getRet(Type* dty, llvm::Value* val);
void getRet(Type* dty, llvm::Value* val, llvm::Value* address);
llvm::Value* putParam(Type* dty, size_t idx, DValue* dval);
llvm::Value* putParam(Type* dty, const IrFuncTyArg& arg, DValue* dval);
void getParam(Type* dty, size_t idx, DValue* dval, llvm::Value* lval);
llvm::Value* putParam(size_t idx, DValue* dval);
llvm::Value* putParam(const IrFuncTyArg& arg, DValue* dval);
void getParam(Type* dty, size_t idx, llvm::Value* val, llvm::Value* address);
};
#endif