mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-07 11:26:02 +03:00
Merge pull request #1562 from kinke/dvalue
Continue with DValue refactoring and fix issue #1327
This commit is contained in:
commit
a2fdffaf0d
8 changed files with 180 additions and 158 deletions
|
@ -18,11 +18,10 @@
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
DValue *DtoBinAdd(DValue *lhs, DValue *rhs) {
|
DImValue *DtoBinAdd(DRValue *lhs, DRValue *rhs) {
|
||||||
Type *t = lhs->type;
|
Type *t = lhs->type;
|
||||||
LLValue *l, *r;
|
LLValue *l = DtoRVal(lhs);
|
||||||
l = DtoRVal(lhs);
|
LLValue *r = DtoRVal(rhs);
|
||||||
r = DtoRVal(rhs);
|
|
||||||
|
|
||||||
LLValue *res;
|
LLValue *res;
|
||||||
if (t->isfloating()) {
|
if (t->isfloating()) {
|
||||||
|
@ -36,11 +35,10 @@ DValue *DtoBinAdd(DValue *lhs, DValue *rhs) {
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
DValue *DtoBinSub(DValue *lhs, DValue *rhs) {
|
DImValue *DtoBinSub(DRValue *lhs, DRValue *rhs) {
|
||||||
Type *t = lhs->type;
|
Type *t = lhs->type;
|
||||||
LLValue *l, *r;
|
LLValue *l = DtoRVal(lhs);
|
||||||
l = DtoRVal(lhs);
|
LLValue *r = DtoRVal(rhs);
|
||||||
r = DtoRVal(rhs);
|
|
||||||
|
|
||||||
LLValue *res;
|
LLValue *res;
|
||||||
if (t->isfloating()) {
|
if (t->isfloating()) {
|
||||||
|
@ -54,11 +52,10 @@ DValue *DtoBinSub(DValue *lhs, DValue *rhs) {
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
DValue *DtoBinMul(Type *targettype, DValue *lhs, DValue *rhs) {
|
DImValue *DtoBinMul(Type *targettype, DRValue *lhs, DRValue *rhs) {
|
||||||
Type *t = lhs->type;
|
Type *t = lhs->type;
|
||||||
LLValue *l, *r;
|
LLValue *l = DtoRVal(lhs);
|
||||||
l = DtoRVal(lhs);
|
LLValue *r = DtoRVal(rhs);
|
||||||
r = DtoRVal(rhs);
|
|
||||||
|
|
||||||
LLValue *res;
|
LLValue *res;
|
||||||
if (t->isfloating()) {
|
if (t->isfloating()) {
|
||||||
|
@ -66,16 +63,16 @@ DValue *DtoBinMul(Type *targettype, DValue *lhs, DValue *rhs) {
|
||||||
} else {
|
} else {
|
||||||
res = gIR->ir->CreateMul(l, r);
|
res = gIR->ir->CreateMul(l, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DImValue(targettype, res);
|
return new DImValue(targettype, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
DValue *DtoBinDiv(Type *targettype, DValue *lhs, DValue *rhs) {
|
DImValue *DtoBinDiv(Type *targettype, DRValue *lhs, DRValue *rhs) {
|
||||||
Type *t = lhs->type;
|
Type *t = lhs->type;
|
||||||
LLValue *l, *r;
|
LLValue *l = DtoRVal(lhs);
|
||||||
l = DtoRVal(lhs);
|
LLValue *r = DtoRVal(rhs);
|
||||||
r = DtoRVal(rhs);
|
|
||||||
|
|
||||||
LLValue *res;
|
LLValue *res;
|
||||||
if (t->isfloating()) {
|
if (t->isfloating()) {
|
||||||
|
@ -85,16 +82,17 @@ DValue *DtoBinDiv(Type *targettype, DValue *lhs, DValue *rhs) {
|
||||||
} else {
|
} else {
|
||||||
res = gIR->ir->CreateUDiv(l, r);
|
res = gIR->ir->CreateUDiv(l, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DImValue(targettype, res);
|
return new DImValue(targettype, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
DValue *DtoBinRem(Type *targettype, DValue *lhs, DValue *rhs) {
|
DImValue *DtoBinRem(Type *targettype, DRValue *lhs, DRValue *rhs) {
|
||||||
Type *t = lhs->type;
|
Type *t = lhs->type;
|
||||||
LLValue *l, *r;
|
LLValue *l = DtoRVal(lhs);
|
||||||
l = DtoRVal(lhs);
|
LLValue *r = DtoRVal(rhs);
|
||||||
r = DtoRVal(rhs);
|
|
||||||
LLValue *res;
|
LLValue *res;
|
||||||
if (t->isfloating()) {
|
if (t->isfloating()) {
|
||||||
res = gIR->ir->CreateFRem(l, r);
|
res = gIR->ir->CreateFRem(l, r);
|
||||||
|
@ -103,6 +101,7 @@ DValue *DtoBinRem(Type *targettype, DValue *lhs, DValue *rhs) {
|
||||||
} else {
|
} else {
|
||||||
res = gIR->ir->CreateURem(l, r);
|
res = gIR->ir->CreateURem(l, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DImValue(targettype, res);
|
return new DImValue(targettype, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,7 @@ void DtoGetComplexParts(Loc &loc, Type *to, DValue *val, LLValue *&re,
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
DValue *DtoComplexAdd(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
|
DImValue *DtoComplexAdd(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs) {
|
||||||
llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
|
llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
|
||||||
|
|
||||||
// lhs values
|
// lhs values
|
||||||
|
@ -212,7 +212,7 @@ DValue *DtoComplexAdd(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
DValue *DtoComplexSub(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
|
DImValue *DtoComplexSub(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs) {
|
||||||
llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
|
llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
|
||||||
|
|
||||||
// lhs values
|
// lhs values
|
||||||
|
@ -243,7 +243,7 @@ DValue *DtoComplexSub(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
DValue *DtoComplexMul(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
|
DImValue *DtoComplexMul(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs) {
|
||||||
llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
|
llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
|
||||||
|
|
||||||
// lhs values
|
// lhs values
|
||||||
|
@ -296,7 +296,7 @@ DValue *DtoComplexMul(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
DValue *DtoComplexDiv(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
|
DImValue *DtoComplexDiv(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs) {
|
||||||
llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
|
llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im;
|
||||||
|
|
||||||
// lhs values
|
// lhs values
|
||||||
|
@ -369,7 +369,7 @@ DValue *DtoComplexDiv(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
DValue *DtoComplexRem(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
|
DImValue *DtoComplexRem(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs) {
|
||||||
llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im, *divisor;
|
llvm::Value *lhs_re, *lhs_im, *rhs_re, *rhs_im, *res_re, *res_im, *divisor;
|
||||||
|
|
||||||
// lhs values
|
// lhs values
|
||||||
|
@ -390,7 +390,7 @@ DValue *DtoComplexRem(Loc &loc, Type *type, DValue *lhs, DValue *rhs) {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
DValue *DtoComplexNeg(Loc &loc, Type *type, DValue *val) {
|
DImValue *DtoComplexNeg(Loc &loc, Type *type, DRValue *val) {
|
||||||
llvm::Value *a, *b, *re, *im;
|
llvm::Value *a, *b, *re, *im;
|
||||||
|
|
||||||
// values
|
// values
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
|
|
||||||
#include "tokens.h"
|
#include "tokens.h"
|
||||||
#include "longdouble.h"
|
#include "longdouble.h"
|
||||||
|
#include "dvalue.h"
|
||||||
|
|
||||||
class DValue;
|
|
||||||
struct Loc;
|
struct Loc;
|
||||||
class Type;
|
class Type;
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
@ -43,12 +43,12 @@ void DtoGetComplexParts(Loc &loc, Type *to, DValue *c, DValue *&re,
|
||||||
void DtoGetComplexParts(Loc &loc, Type *to, DValue *c, llvm::Value *&re,
|
void DtoGetComplexParts(Loc &loc, Type *to, DValue *c, llvm::Value *&re,
|
||||||
llvm::Value *&im);
|
llvm::Value *&im);
|
||||||
|
|
||||||
DValue *DtoComplexAdd(Loc &loc, Type *type, DValue *lhs, DValue *rhs);
|
DImValue *DtoComplexAdd(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs);
|
||||||
DValue *DtoComplexSub(Loc &loc, Type *type, DValue *lhs, DValue *rhs);
|
DImValue *DtoComplexSub(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs);
|
||||||
DValue *DtoComplexMul(Loc &loc, Type *type, DValue *lhs, DValue *rhs);
|
DImValue *DtoComplexMul(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs);
|
||||||
DValue *DtoComplexDiv(Loc &loc, Type *type, DValue *lhs, DValue *rhs);
|
DImValue *DtoComplexDiv(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs);
|
||||||
DValue *DtoComplexRem(Loc &loc, Type *type, DValue *lhs, DValue *rhs);
|
DImValue *DtoComplexRem(Loc &loc, Type *type, DRValue *lhs, DRValue *rhs);
|
||||||
DValue *DtoComplexNeg(Loc &loc, Type *type, DValue *val);
|
DImValue *DtoComplexNeg(Loc &loc, Type *type, DRValue *val);
|
||||||
|
|
||||||
llvm::Value *DtoComplexEquals(Loc &loc, TOK op, DValue *lhs, DValue *rhs);
|
llvm::Value *DtoComplexEquals(Loc &loc, TOK op, DValue *lhs, DValue *rhs);
|
||||||
|
|
||||||
|
|
|
@ -36,18 +36,53 @@ bool isDefinedInFuncEntryBB(LLValue *v) {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool DValue::definedInFuncEntryBB() { return isDefinedInFuncEntryBB(val); }
|
LLValue *DtoLVal(DValue *v) {
|
||||||
|
auto lval = v->isLVal();
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
assert(lval);
|
||||||
|
return lval->getLVal()->val;
|
||||||
DImValue::DImValue(Type *t, llvm::Value *v) : DValue(t, v) {
|
|
||||||
assert(!DtoIsInMemoryOnly(t) &&
|
|
||||||
"Cannot represent memory-only type as immediate DValue");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
DConstValue::DConstValue(Type *t, llvm::Constant *con) : DValue(t, con) {}
|
DValue::DValue(Type *t, LLValue *v) : type(t), val(v) {
|
||||||
|
assert(type);
|
||||||
|
assert(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DValue::definedInFuncEntryBB() { return isDefinedInFuncEntryBB(val); }
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
DRValue::DRValue(Type *t, LLValue *v) : DValue(t, v) {
|
||||||
|
assert(!DtoIsInMemoryOnly(t) &&
|
||||||
|
"Cannot represent memory-only type as DRValue");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
DConstValue::DConstValue(Type *t, LLConstant *con) : DRValue(t, con) {}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
DSliceValue::DSliceValue(Type *t, LLValue *length, LLValue *ptr)
|
||||||
|
: DRValue(t, DtoAggrPair(length, ptr)) {}
|
||||||
|
|
||||||
|
LLValue *DSliceValue::getLength() { return DtoExtractValue(val, 0, ".len"); }
|
||||||
|
|
||||||
|
LLValue *DSliceValue::getPtr() { return DtoExtractValue(val, 1, ".ptr"); }
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
DFuncValue::DFuncValue(Type *t, FuncDeclaration *fd, LLValue *v, LLValue *vt)
|
||||||
|
: DRValue(t, v), func(fd), vthis(vt) {}
|
||||||
|
|
||||||
|
DFuncValue::DFuncValue(FuncDeclaration *fd, LLValue *v, LLValue *vt)
|
||||||
|
: DRValue(fd->type, v), func(fd), vthis(vt) {}
|
||||||
|
|
||||||
|
bool DFuncValue::definedInFuncEntryBB() {
|
||||||
|
return isDefinedInFuncEntryBB(val) &&
|
||||||
|
(!vthis || isDefinedInFuncEntryBB(vthis));
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -78,18 +113,19 @@ DLValue::DLValue(Type *t, LLValue *v) : DValue(t, v) {
|
||||||
assert(checkVarValueType(v->getType(), false));
|
assert(checkVarValueType(v->getType(), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
LLValue *DLValue::getRVal() {
|
DRValue *DLValue::getRVal() {
|
||||||
if (DtoIsInMemoryOnly(type->toBasetype())) {
|
if (DtoIsInMemoryOnly(type)) {
|
||||||
llvm_unreachable("getRVal() for memory-only type");
|
llvm_unreachable("getRVal() for memory-only type");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
LLValue *rawValue = DtoLoad(val);
|
LLValue *rval = DtoLoad(val);
|
||||||
if (type->toBasetype()->ty != Tbool)
|
if (type->toBasetype()->ty == Tbool) {
|
||||||
return rawValue;
|
assert(rval->getType() == llvm::Type::getInt8Ty(gIR->context()));
|
||||||
|
rval = gIR->ir->CreateTrunc(rval, llvm::Type::getInt1Ty(gIR->context()));
|
||||||
|
}
|
||||||
|
|
||||||
assert(rawValue->getType() == llvm::Type::getInt8Ty(gIR->context()));
|
return new DImValue(type, rval);
|
||||||
return gIR->ir->CreateTrunc(rawValue, llvm::Type::getInt1Ty(gIR->context()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -98,30 +134,8 @@ DSpecialRefValue::DSpecialRefValue(Type *t, LLValue *v) : DLValue(v, t) {
|
||||||
assert(checkVarValueType(v->getType(), true));
|
assert(checkVarValueType(v->getType(), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
LLValue *DSpecialRefValue::getLVal() { return DtoLoad(val); }
|
DRValue *DSpecialRefValue::getRVal() {
|
||||||
|
return DLValue(type, DtoLoad(val)).getRVal();
|
||||||
LLValue *DSpecialRefValue::getRVal() {
|
|
||||||
return DLValue(type, getLVal()).getRVal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
DLValue *DSpecialRefValue::getLVal() { return new DLValue(type, DtoLoad(val)); }
|
||||||
|
|
||||||
DSliceValue::DSliceValue(Type *t, LLValue *length, LLValue *ptr)
|
|
||||||
: DValue(t, DtoAggrPair(length, ptr)) {}
|
|
||||||
|
|
||||||
LLValue *DSliceValue::getLength() { return DtoExtractValue(val, 0, ".len"); }
|
|
||||||
|
|
||||||
LLValue *DSliceValue::getPtr() { return DtoExtractValue(val, 1, ".ptr"); }
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
DFuncValue::DFuncValue(Type *t, FuncDeclaration *fd, LLValue *v, LLValue *vt)
|
|
||||||
: DValue(t, v), func(fd), vthis(vt) {}
|
|
||||||
|
|
||||||
DFuncValue::DFuncValue(FuncDeclaration *fd, LLValue *v, LLValue *vt)
|
|
||||||
: DValue(fd->type, v), func(fd), vthis(vt) {}
|
|
||||||
|
|
||||||
bool DFuncValue::definedInFuncEntryBB() {
|
|
||||||
return isDefinedInFuncEntryBB(val) &&
|
|
||||||
(!vthis || isDefinedInFuncEntryBB(vthis));
|
|
||||||
}
|
|
||||||
|
|
121
gen/dvalue.h
121
gen/dvalue.h
|
@ -18,7 +18,6 @@
|
||||||
#define LDC_GEN_DVALUE_H
|
#define LDC_GEN_DVALUE_H
|
||||||
|
|
||||||
#include "root.h"
|
#include "root.h"
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
class Type;
|
class Type;
|
||||||
class Dsymbol;
|
class Dsymbol;
|
||||||
|
@ -31,35 +30,38 @@ class Type;
|
||||||
class Constant;
|
class Constant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DValue;
|
||||||
|
class DRValue;
|
||||||
class DImValue;
|
class DImValue;
|
||||||
class DConstValue;
|
class DConstValue;
|
||||||
class DNullValue;
|
class DNullValue;
|
||||||
class DLValue;
|
class DLValue;
|
||||||
class DSpecialRefValue;
|
class DSpecialRefValue;
|
||||||
class DFuncValue;
|
|
||||||
class DSliceValue;
|
class DSliceValue;
|
||||||
|
class DFuncValue;
|
||||||
|
|
||||||
// base class for d-values
|
/// Represents an immutable pair of LLVM value and associated D type.
|
||||||
class DValue {
|
class DValue {
|
||||||
public:
|
public:
|
||||||
Type *const type;
|
Type *const type;
|
||||||
|
|
||||||
virtual ~DValue() = default;
|
virtual ~DValue() = default;
|
||||||
|
|
||||||
virtual llvm::Value *getRVal() { return val; }
|
|
||||||
|
|
||||||
/// Returns true iff the value can be accessed at the end of the entry basic
|
/// Returns true iff the value can be accessed at the end of the entry basic
|
||||||
/// block of the current function, in the sense that it is either not derived
|
/// block of the current function, in the sense that it is either not derived
|
||||||
/// from an llvm::Instruction (but from a global, constant, etc.) or that
|
/// from an llvm::Instruction (but from a global, constant, etc.) or that
|
||||||
/// instruction is part of the entry basic block.
|
/// instruction is part of the entry basic block.
|
||||||
///
|
///
|
||||||
/// In other words, whatever value the result of getLVal()/getRVal() might be
|
/// In other words, whatever the value might be derived from then certainly
|
||||||
/// derived from then certainly dominates uses in all other basic blocks of
|
/// dominates uses in all other basic blocks of the function.
|
||||||
/// the function.
|
|
||||||
virtual bool definedInFuncEntryBB();
|
virtual bool definedInFuncEntryBB();
|
||||||
|
|
||||||
|
virtual DRValue *getRVal() { return nullptr; }
|
||||||
|
|
||||||
virtual DLValue *isLVal() { return nullptr; }
|
virtual DLValue *isLVal() { return nullptr; }
|
||||||
virtual DSpecialRefValue *isSpecialRef() { return nullptr; }
|
virtual DSpecialRefValue *isSpecialRef() { return nullptr; }
|
||||||
|
|
||||||
|
virtual DRValue *isRVal() { return nullptr; }
|
||||||
virtual DImValue *isIm() { return nullptr; }
|
virtual DImValue *isIm() { return nullptr; }
|
||||||
virtual DConstValue *isConst() { return nullptr; }
|
virtual DConstValue *isConst() { return nullptr; }
|
||||||
virtual DNullValue *isNull() { return nullptr; }
|
virtual DNullValue *isNull() { return nullptr; }
|
||||||
|
@ -69,22 +71,35 @@ public:
|
||||||
protected:
|
protected:
|
||||||
llvm::Value *const val;
|
llvm::Value *const val;
|
||||||
|
|
||||||
DValue(Type *t, llvm::Value *v) : type(t), val(v) {
|
DValue(Type *t, llvm::Value *v);
|
||||||
assert(type);
|
|
||||||
assert(val);
|
friend llvm::Value *DtoRVal(DValue *v);
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// immediate d-value
|
/// Represents a D rvalue via a low-level rvalue.
|
||||||
class DImValue : public DValue {
|
class DRValue : public DValue {
|
||||||
public:
|
public:
|
||||||
DImValue(Type *t, llvm::Value *v);
|
DRValue *getRVal() override { return this; }
|
||||||
|
|
||||||
|
DRValue *isRVal() override { return this; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DRValue(Type *t, llvm::Value *v);
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents an immediate D value (simple rvalue with no special properties
|
||||||
|
/// like being a compile-time constant) via a low-level rvalue.
|
||||||
|
/// Restricted to primitive types such as pointers (incl. class references),
|
||||||
|
/// integral and floating-point types.
|
||||||
|
class DImValue : public DRValue {
|
||||||
|
public:
|
||||||
|
DImValue(Type *t, llvm::Value *v) : DRValue(t, v) {}
|
||||||
|
|
||||||
DImValue *isIm() override { return this; }
|
DImValue *isIm() override { return this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// constant d-value
|
/// Represents a D compile-time constant via a low-level constant.
|
||||||
class DConstValue : public DValue {
|
class DConstValue : public DRValue {
|
||||||
public:
|
public:
|
||||||
DConstValue(Type *t, llvm::Constant *con);
|
DConstValue(Type *t, llvm::Constant *con);
|
||||||
|
|
||||||
|
@ -93,7 +108,7 @@ public:
|
||||||
DConstValue *isConst() override { return this; }
|
DConstValue *isConst() override { return this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// null d-value
|
/// Represents a D compile-time null constant.
|
||||||
class DNullValue : public DConstValue {
|
class DNullValue : public DConstValue {
|
||||||
public:
|
public:
|
||||||
DNullValue(Type *t, llvm::Constant *con) : DConstValue(t, con) {}
|
DNullValue(Type *t, llvm::Constant *con) : DConstValue(t, con) {}
|
||||||
|
@ -101,36 +116,8 @@ public:
|
||||||
DNullValue *isNull() override { return this; }
|
DNullValue *isNull() override { return this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Represents a D value in memory via a low-level lvalue.
|
/// Represents a D slice (dynamic array).
|
||||||
/// This doesn't imply that the D value is an lvalue too - e.g., we always
|
class DSliceValue : public DRValue {
|
||||||
/// keep structs and static arrays in memory.
|
|
||||||
class DLValue : public DValue {
|
|
||||||
public:
|
|
||||||
DLValue(Type *t, llvm::Value *v);
|
|
||||||
|
|
||||||
virtual llvm::Value *getLVal() { return val; }
|
|
||||||
llvm::Value *getRVal() override;
|
|
||||||
|
|
||||||
DLValue *isLVal() override { return this; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
DLValue(llvm::Value *v, Type *t) : DValue(t, v) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Represents special internal ref variables.
|
|
||||||
class DSpecialRefValue : public DLValue {
|
|
||||||
public:
|
|
||||||
DSpecialRefValue(Type *t, llvm::Value *v);
|
|
||||||
|
|
||||||
llvm::Value *getRefStorage() { return val; }
|
|
||||||
llvm::Value *getLVal() override;
|
|
||||||
llvm::Value *getRVal() override;
|
|
||||||
|
|
||||||
DSpecialRefValue *isSpecialRef() override { return this; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// slice d-value
|
|
||||||
class DSliceValue : public DValue {
|
|
||||||
public:
|
public:
|
||||||
DSliceValue(Type *t, llvm::Value *length, llvm::Value *ptr);
|
DSliceValue(Type *t, llvm::Value *length, llvm::Value *ptr);
|
||||||
|
|
||||||
|
@ -140,8 +127,8 @@ public:
|
||||||
llvm::Value *getPtr();
|
llvm::Value *getPtr();
|
||||||
};
|
};
|
||||||
|
|
||||||
// function d-value
|
/// Represents a D function value with optional this/context pointer.
|
||||||
class DFuncValue : public DValue {
|
class DFuncValue : public DRValue {
|
||||||
public:
|
public:
|
||||||
FuncDeclaration *func;
|
FuncDeclaration *func;
|
||||||
llvm::Value *vthis;
|
llvm::Value *vthis;
|
||||||
|
@ -155,4 +142,38 @@ public:
|
||||||
DFuncValue *isFunc() override { return this; }
|
DFuncValue *isFunc() override { return this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Represents a D value in memory via a low-level lvalue (pointer).
|
||||||
|
/// This doesn't imply that the D value is an lvalue too - e.g., we always
|
||||||
|
/// keep structs and static arrays in memory.
|
||||||
|
class DLValue : public DValue {
|
||||||
|
public:
|
||||||
|
DLValue(Type *t, llvm::Value *v);
|
||||||
|
|
||||||
|
DRValue *getRVal() override;
|
||||||
|
virtual DLValue *getLVal() { return this; }
|
||||||
|
|
||||||
|
DLValue *isLVal() override { return this; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DLValue(llvm::Value *v, Type *t) : DValue(t, v) {}
|
||||||
|
|
||||||
|
friend llvm::Value *DtoLVal(DValue *v);
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents special internal ref variables.
|
||||||
|
class DSpecialRefValue : public DLValue {
|
||||||
|
public:
|
||||||
|
DSpecialRefValue(Type *t, llvm::Value *v);
|
||||||
|
|
||||||
|
DRValue *getRVal() override;
|
||||||
|
DLValue *getLVal() override;
|
||||||
|
llvm::Value *getRefStorage() { return val; }
|
||||||
|
|
||||||
|
DSpecialRefValue *isSpecialRef() override { return this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline llvm::Value *DtoRVal(DValue *v) { return v->getRVal()->val; }
|
||||||
|
llvm::Value *DtoLVal(DValue *v);
|
||||||
|
|
||||||
#endif // LDC_GEN_DVALUE_H
|
#endif // LDC_GEN_DVALUE_H
|
||||||
|
|
|
@ -1866,13 +1866,3 @@ DValue *makeVarDValue(Type *type, VarDeclaration *vd, llvm::Value *storage) {
|
||||||
|
|
||||||
return new DLValue(type, val);
|
return new DLValue(type, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLValue *DtoRVal(DValue *v) { return v->getRVal(); }
|
|
||||||
LLValue *DtoLVal(DValue *v) {
|
|
||||||
auto lval = v->isLVal();
|
|
||||||
assert(lval);
|
|
||||||
return lval->getLVal();
|
|
||||||
}
|
|
||||||
|
|
||||||
LLValue *DtoRVal(Expression *e) { return DtoRVal(toElem(e)); }
|
|
||||||
LLValue *DtoLVal(Expression *e) { return DtoLVal(toElem(e)); }
|
|
||||||
|
|
|
@ -129,13 +129,13 @@ LLConstant *DtoConstExpInit(Loc &loc, Type *targetType, Expression *exp);
|
||||||
LLConstant *DtoTypeInfoOf(Type *ty, bool base = true);
|
LLConstant *DtoTypeInfoOf(Type *ty, bool base = true);
|
||||||
|
|
||||||
// binary operations
|
// binary operations
|
||||||
DValue *DtoBinAdd(DValue *lhs, DValue *rhs);
|
DImValue *DtoBinAdd(DRValue *lhs, DRValue *rhs);
|
||||||
DValue *DtoBinSub(DValue *lhs, DValue *rhs);
|
DImValue *DtoBinSub(DRValue *lhs, DRValue *rhs);
|
||||||
// these binops need an explicit result type to handling
|
// these binops need an explicit result type to handling
|
||||||
// to give 'ifloat op float' and 'float op ifloat' the correct type
|
// to give 'ifloat op float' and 'float op ifloat' the correct type
|
||||||
DValue *DtoBinMul(Type *resulttype, DValue *lhs, DValue *rhs);
|
DImValue *DtoBinMul(Type *resulttype, DRValue *lhs, DRValue *rhs);
|
||||||
DValue *DtoBinDiv(Type *resulttype, DValue *lhs, DValue *rhs);
|
DImValue *DtoBinDiv(Type *resulttype, DRValue *lhs, DRValue *rhs);
|
||||||
DValue *DtoBinRem(Type *resulttype, DValue *lhs, DValue *rhs);
|
DImValue *DtoBinRem(Type *resulttype, DRValue *lhs, DRValue *rhs);
|
||||||
LLValue *DtoBinNumericEquals(Loc &loc, DValue *lhs, DValue *rhs, TOK op);
|
LLValue *DtoBinNumericEquals(Loc &loc, DValue *lhs, DValue *rhs, TOK op);
|
||||||
LLValue *DtoBinFloatsEquals(Loc &loc, DValue *lhs, DValue *rhs, TOK op);
|
LLValue *DtoBinFloatsEquals(Loc &loc, DValue *lhs, DValue *rhs, TOK op);
|
||||||
|
|
||||||
|
@ -280,10 +280,8 @@ DValue *toElem(Expression *e, bool tryGetLvalue);
|
||||||
DValue *toElemDtor(Expression *e);
|
DValue *toElemDtor(Expression *e);
|
||||||
LLConstant *toConstElem(Expression *e, IRState *p);
|
LLConstant *toConstElem(Expression *e, IRState *p);
|
||||||
|
|
||||||
llvm::Value *DtoRVal(DValue *v);
|
inline llvm::Value *DtoRVal(Expression *e) { return DtoRVal(toElem(e)); }
|
||||||
llvm::Value *DtoRVal(Expression *e);
|
inline llvm::Value *DtoLVal(Expression *e) { return DtoLVal(toElem(e)); }
|
||||||
llvm::Value *DtoLVal(DValue *v);
|
|
||||||
llvm::Value *DtoLVal(Expression *e);
|
|
||||||
|
|
||||||
/// Creates a DLValue for the given VarDeclaration.
|
/// Creates a DLValue for the given VarDeclaration.
|
||||||
///
|
///
|
||||||
|
|
32
gen/toir.cpp
32
gen/toir.cpp
|
@ -165,7 +165,7 @@ static void write_struct_literal(Loc loc, LLValue *mem, StructDeclaration *sd,
|
||||||
DtoAssign(loc, &field, val, TOKconstruct, true);
|
DtoAssign(loc, &field, val, TOKconstruct, true);
|
||||||
|
|
||||||
if (expr && expr->isLvalue()) {
|
if (expr && expr->isLvalue()) {
|
||||||
callPostblit(loc, expr, field.getLVal());
|
callPostblit(loc, expr, DtoLVal(&field));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also zero out padding bytes counted as being part of the type in DMD
|
// Also zero out padding bytes counted as being part of the type in DMD
|
||||||
|
@ -776,7 +776,7 @@ public:
|
||||||
auto &PGO = gIR->func()->pgo;
|
auto &PGO = gIR->func()->pgo;
|
||||||
PGO.setCurrentStmt(e);
|
PGO.setCurrentStmt(e);
|
||||||
|
|
||||||
DValue *l = toElem(e->e1);
|
DRValue *l = toElem(e->e1)->getRVal();
|
||||||
|
|
||||||
Type *t = e->type->toBasetype();
|
Type *t = e->type->toBasetype();
|
||||||
Type *e1type = e->e1->type->toBasetype();
|
Type *e1type = e->e1->type->toBasetype();
|
||||||
|
@ -788,9 +788,9 @@ public:
|
||||||
Logger::println("Adding integer to pointer");
|
Logger::println("Adding integer to pointer");
|
||||||
result = emitPointerOffset(p, e->loc, l, e->e2, false, e->type);
|
result = emitPointerOffset(p, e->loc, l, e->e2, false, e->type);
|
||||||
} else if (t->iscomplex()) {
|
} else if (t->iscomplex()) {
|
||||||
result = DtoComplexAdd(e->loc, e->type, l, toElem(e->e2));
|
result = DtoComplexAdd(e->loc, e->type, l, toElem(e->e2)->getRVal());
|
||||||
} else {
|
} else {
|
||||||
result = DtoBinAdd(l, toElem(e->e2));
|
result = DtoBinAdd(l, toElem(e->e2)->getRVal());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -802,7 +802,7 @@ public:
|
||||||
auto &PGO = gIR->func()->pgo;
|
auto &PGO = gIR->func()->pgo;
|
||||||
PGO.setCurrentStmt(e);
|
PGO.setCurrentStmt(e);
|
||||||
|
|
||||||
DValue *l = toElem(e->e1);
|
DRValue *l = toElem(e->e1)->getRVal();
|
||||||
|
|
||||||
Type *t = e->type->toBasetype();
|
Type *t = e->type->toBasetype();
|
||||||
Type *t1 = e->e1->type->toBasetype();
|
Type *t1 = e->e1->type->toBasetype();
|
||||||
|
@ -825,9 +825,9 @@ public:
|
||||||
Logger::println("Subtracting integer from pointer");
|
Logger::println("Subtracting integer from pointer");
|
||||||
result = emitPointerOffset(p, e->loc, l, e->e2, true, e->type);
|
result = emitPointerOffset(p, e->loc, l, e->e2, true, e->type);
|
||||||
} else if (t->iscomplex()) {
|
} else if (t->iscomplex()) {
|
||||||
result = DtoComplexSub(e->loc, e->type, l, toElem(e->e2));
|
result = DtoComplexSub(e->loc, e->type, l, toElem(e->e2)->getRVal());
|
||||||
} else {
|
} else {
|
||||||
result = DtoBinSub(l, toElem(e->e2));
|
result = DtoBinSub(l, toElem(e->e2)->getRVal());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -841,8 +841,8 @@ public:
|
||||||
auto &PGO = gIR->func()->pgo;
|
auto &PGO = gIR->func()->pgo;
|
||||||
PGO.setCurrentStmt(e);
|
PGO.setCurrentStmt(e);
|
||||||
|
|
||||||
DValue *l = toElem(e->e1);
|
DRValue *l = toElem(e->e1)->getRVal();
|
||||||
DValue *r = toElem(e->e2);
|
DRValue *r = toElem(e->e2)->getRVal();
|
||||||
|
|
||||||
errorOnIllegalArrayOp(e, e->e1, e->e2);
|
errorOnIllegalArrayOp(e, e->e1, e->e2);
|
||||||
|
|
||||||
|
@ -863,8 +863,8 @@ public:
|
||||||
auto &PGO = gIR->func()->pgo;
|
auto &PGO = gIR->func()->pgo;
|
||||||
PGO.setCurrentStmt(e);
|
PGO.setCurrentStmt(e);
|
||||||
|
|
||||||
DValue *l = toElem(e->e1);
|
DRValue *l = toElem(e->e1)->getRVal();
|
||||||
DValue *r = toElem(e->e2);
|
DRValue *r = toElem(e->e2)->getRVal();
|
||||||
|
|
||||||
errorOnIllegalArrayOp(e, e->e1, e->e2);
|
errorOnIllegalArrayOp(e, e->e1, e->e2);
|
||||||
|
|
||||||
|
@ -885,8 +885,8 @@ public:
|
||||||
auto &PGO = gIR->func()->pgo;
|
auto &PGO = gIR->func()->pgo;
|
||||||
PGO.setCurrentStmt(e);
|
PGO.setCurrentStmt(e);
|
||||||
|
|
||||||
DValue *l = toElem(e->e1);
|
DRValue *l = toElem(e->e1)->getRVal();
|
||||||
DValue *r = toElem(e->e2);
|
DRValue *r = toElem(e->e2)->getRVal();
|
||||||
|
|
||||||
errorOnIllegalArrayOp(e, e->e1, e->e2);
|
errorOnIllegalArrayOp(e, e->e1, e->e2);
|
||||||
|
|
||||||
|
@ -2418,14 +2418,14 @@ public:
|
||||||
e->type->toChars());
|
e->type->toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
|
||||||
DValue *l = toElem(e->e1);
|
DRValue *dval = toElem(e->e1)->getRVal();
|
||||||
|
|
||||||
if (e->type->iscomplex()) {
|
if (e->type->iscomplex()) {
|
||||||
result = DtoComplexNeg(e->loc, e->type, l);
|
result = DtoComplexNeg(e->loc, e->type, dval);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LLValue *val = DtoRVal(l);
|
LLValue *val = DtoRVal(dval);
|
||||||
|
|
||||||
if (e->type->isintegral()) {
|
if (e->type->isintegral()) {
|
||||||
val = p->ir->CreateNeg(val, "negval");
|
val = p->ir->CreateNeg(val, "negval");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue