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 /// Removes padding fields for (non-union-containing!) structs
struct RemoveStructPadding : ABIRewrite { struct RemoveStructPadding : ABIRewrite {
/// get a rewritten value back to its original form /// 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"); LLValue* lval = DtoAlloca(dty, ".rewritetmp");
getL(dty, v, lval); getL(dty, v, lval);
return lval; return lval;
} }
/// get a rewritten value back to its original form and store result in provided lvalue /// 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, LLValue* v, LLValue* lval) {
void getL(Type* dty, DValue* v, LLValue* lval) {
// Make sure the padding is zero, so struct comparisons work. // Make sure the padding is zero, so struct comparisons work.
// TODO: Only do this if there's padding, and/or only initialize padding. // TODO: Only do this if there's padding, and/or only initialize padding.
DtoMemSetZero(lval, DtoConstSize_t(getTypePaddedSize(DtoType(dty)))); DtoMemSetZero(lval, DtoConstSize_t(getTypePaddedSize(DtoType(dty))));
DtoPaddedStruct(dty->toBasetype(), v->getRVal(), lval); DtoPaddedStruct(dty->toBasetype(), v, lval);
} }
/// put out rewritten value /// put out rewritten value
LLValue* put(Type* dty, DValue* v) { LLValue* put(DValue* v) {
return DtoUnpaddedStruct(dty->toBasetype(), v->getRVal()); return DtoUnpaddedStruct(v->getType()->toBasetype(), v->getRVal());
} }
/// return the transformed type for this rewrite /// return the transformed type for this rewrite
@ -154,25 +153,22 @@ struct IntegerRewrite : ABIRewrite
return LLTypeMemoryLayout::typesAreEquivalent(llType, integerType); 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); LLType* type = DtoType(dty);
return loadFromMemory(integerDump, type, ".IntegerRewrite_getResult"); 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(v, lval);
storeToMemory(integer, lval);
} }
LLValue* put(Type* dty, DValue* dv) LLValue* put(DValue* dv)
{ {
assert(dty == dv->getType());
LLValue* address = getAddressOf(dv); LLValue* address = getAddressOf(dv);
LLType* integerType = getIntegerType(dty->size()); LLType* integerType = getIntegerType(dv->getType()->size());
return loadFromMemory(address, integerType, ".IntegerRewrite_putResult"); return loadFromMemory(address, integerType, ".IntegerRewrite_putResult");
} }
@ -204,21 +200,19 @@ struct ExplicitByvalRewrite : ABIRewrite
ExplicitByvalRewrite(size_t alignment = 16) : alignment(alignment) 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(v, ".ExplicitByvalRewrite_getResult");
return DtoLoad(pointer, ".ExplicitByvalRewrite_getResult");
} }
void getL(Type* dty, DValue* v, LLValue* lval) void getL(Type* dty, LLValue* v, LLValue* lval)
{ {
LLValue* pointer = v->getRVal(); DtoAggrCopy(lval, v);
DtoAggrCopy(lval, pointer);
} }
LLValue* put(Type* dty, DValue* v) LLValue* put(DValue* v)
{ {
if (DtoIsPassedByRef(dty)) if (DtoIsPassedByRef(v->getType()))
{ {
LLValue* originalPointer = v->getRVal(); LLValue* originalPointer = v->getRVal();
LLType* type = originalPointer->getType()->getPointerElementType(); LLType* type = originalPointer->getType()->getPointerElementType();
@ -227,8 +221,7 @@ struct ExplicitByvalRewrite : ABIRewrite
return copyForCallee; return copyForCallee;
} }
LLValue* copyForCallee = DtoAllocaDump(v->getRVal(), alignment, ".ExplicitByvalRewrite_putResult"); return DtoAllocaDump(v->getRVal(), alignment, ".ExplicitByvalRewrite_putResult");
return copyForCallee;
} }
LLType* type(Type* dty, LLType* t) 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). * memory so that it's then readable as the other type (i.e., bit-casting).
*/ */
struct X86_64_C_struct_rewrite : ABIRewrite { 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); LLType* type = DtoType(dty);
return loadFromMemory(address, type, ".X86_64_C_struct_rewrite_getResult"); return loadFromMemory(address, type, ".X86_64_C_struct_rewrite_getResult");
} }
void getL(Type* dty, DValue* v, LLValue* lval) { void getL(Type* dty, LLValue* v, LLValue* lval) {
storeToMemory(v->getRVal(), lval); storeToMemory(v, lval);
} }
LLValue* put(Type* dty, DValue* v) { LLValue* put(DValue* v) {
assert(dty == v->getType());
LLValue* address = getAddressOf(v); LLValue* address = getAddressOf(v);
LLType* abiTy = getAbiType(dty); LLType* abiTy = getAbiType(v->getType());
assert(abiTy && "Why are we rewriting a non-rewritten type?"); assert(abiTy && "Why are we rewriting a non-rewritten type?");
return loadFromMemory(address, abiTy, ".X86_64_C_struct_rewrite_putResult"); 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. * the ByVal LLVM attribute.
*/ */
struct ImplicitByvalRewrite : ABIRewrite { struct ImplicitByvalRewrite : ABIRewrite {
LLValue* get(Type* dty, DValue* v) { LLValue* get(Type* dty, LLValue* v) {
LLValue* pointer = v->getRVal(); return DtoLoad(v, ".ImplicitByvalRewrite_getResult");
return DtoLoad(pointer, ".ImplicitByvalRewrite_getResult");
} }
void getL(Type* dty, DValue* v, LLValue* lval) { void getL(Type* dty, LLValue* v, LLValue* lval) {
LLValue* pointer = v->getRVal(); DtoAggrCopy(lval, v);
DtoAggrCopy(lval, pointer);
} }
LLValue* put(Type* dty, DValue* v) { LLValue* put(DValue* v) {
assert(dty == v->getType());
return getAddressOf(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); LLValue* rval = get(dty, v);
assert(rval->getType() == lval->getType()->getContainedType(0)); assert(rval->getType() == lval->getType()->getContainedType(0));

View file

@ -44,14 +44,14 @@ struct ABIRewrite
virtual ~ABIRewrite() {} virtual ~ABIRewrite() {}
/// get a rewritten value back to its original form /// 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 /// 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 /// 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 /// 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 /// should return the transformed type for this rewrite
virtual llvm::Type* type(Type* dty, llvm::Type* t) = 0; 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()); LLValue* mem = DtoAlloca(irparam->arg->type, vd->ident->toChars());
// let the abi transform the argument back first // let the abi transform the argument back first
DImValue arg_dval(vd->type, irparam->value); irFty.getParam(vd->type, llArgIdx, irparam->value, mem);
irFty.getParam(vd->type, llArgIdx, &arg_dval, mem);
// set the arg var value to the alloca // set the arg var value to the alloca
irparam->value = mem; irparam->value = mem;

View file

@ -191,7 +191,7 @@ public:
dval = toElemDtor(ae); dval = toElemDtor(ae);
} }
// do abi specific transformations on the return value // 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"; 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; llvm::Value* llVal = NULL;
if (isVararg) if (isVararg)
llVal = irFty.putParam(argType, *irArg, argval); llVal = irFty.putParam(*irArg, argval);
else else
llVal = irFty.putParam(argType, i, argval); llVal = irFty.putParam(i, argval);
const size_t llArgIdx = implicitLLArgCount + const size_t llArgIdx = implicitLLArgCount +
(irFty.reverseParams ? explicitLLArgCount - i - 1 : i); (irFty.reverseParams ? explicitLLArgCount - i - 1 : i);
@ -806,18 +806,17 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
if (!intrinsic && !retinptr) if (!intrinsic && !retinptr)
{ {
// do abi specific return value fixups // do abi specific return value fixups
DImValue dretval(returntype, retllval);
if (storeReturnValueOnStack) if (storeReturnValueOnStack)
{ {
Logger::println("Storing return value to stack slot"); Logger::println("Storing return value to stack slot");
LLValue* mem = DtoAlloca(returntype); LLValue* mem = DtoAlloca(returntype);
irFty.getRet(returntype, &dretval, mem); irFty.getRet(returntype, retllval, mem);
retllval = mem; retllval = mem;
storeReturnValueOnStack = false; storeReturnValueOnStack = false;
} }
else else
{ {
retllval = irFty.getRet(returntype, &dretval); retllval = irFty.getRet(returntype, retllval);
storeReturnValueOnStack = storeReturnValueOnStack =
(returnTy == Tstruct && !isaPointer(retllval)) || (returnTy == Tstruct && !isaPointer(retllval)) ||
(returnTy == Tsarray && isaArray(retllval)); (returnTy == Tsarray && isaArray(retllval));

View file

@ -19,65 +19,70 @@ IrFuncTyArg::IrFuncTyArg(Type* t, bool bref, const AttrBuilder& a)
: type(t), parametersIdx(0), : type(t), parametersIdx(0),
ltype(t != Type::tvoid && bref ? DtoType(t->pointerTo()) : DtoType(t)), ltype(t != Type::tvoid && bref ? DtoType(t->pointerTo()) : DtoType(t)),
attrs(a), byref(bref), rewrite(0) attrs(a), byref(bref), rewrite(0)
{ {}
}
bool IrFuncTyArg::isInReg() const { return attrs.contains(LDC_ATTRIBUTE(InReg)); } bool IrFuncTyArg::isInReg() const { return attrs.contains(LDC_ATTRIBUTE(InReg)); }
bool IrFuncTyArg::isSRet() const { return attrs.contains(LDC_ATTRIBUTE(StructRet)); } bool IrFuncTyArg::isSRet() const { return attrs.contains(LDC_ATTRIBUTE(StructRet)); }
bool IrFuncTyArg::isByVal() const { return attrs.contains(LDC_ATTRIBUTE(ByVal)); } 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); assert(!arg_sret);
if (ret->rewrite) { if (ret->rewrite) {
Logger::println("Rewrite: putRet"); Logger::println("Rewrite: putRet");
LOG_SCOPE 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); assert(!arg_sret);
if (ret->rewrite) { if (ret->rewrite) {
Logger::println("Rewrite: getRet"); Logger::println("Rewrite: getRet");
LOG_SCOPE LOG_SCOPE
return ret->rewrite->get(dty, val); 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); assert(!arg_sret);
if (ret->rewrite) { if (ret->rewrite) {
Logger::println("Rewrite: getRet (getL)"); Logger::println("Rewrite: getRet (getL)");
LOG_SCOPE LOG_SCOPE
ret->rewrite->getL(dty, val, lval); ret->rewrite->getL(dty, val, address);
return; 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"); 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) { if (arg.rewrite) {
Logger::println("Rewrite: putParam"); Logger::println("Rewrite: putParam");
LOG_SCOPE 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"); 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)"); Logger::println("Rewrite: getParam (getL)");
LOG_SCOPE LOG_SCOPE
args[idx]->rewrite->getL(dty, val, lval); args[idx]->rewrite->getL(dty, val, address);
return; return;
} }
DtoStoreZextI8(val->getRVal(), lval); DtoStoreZextI8(val, address);
} }

View file

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