Streamline DSliceValue

All DValues are now required to have a (main) LL value, which allows
to conveniently refactor the DValue hierarchy.

DSliceValue now represents a LL struct instead of separate values for
length and pointer.
This commit is contained in:
Martin 2016-05-31 21:02:13 +02:00
parent e3e2f4b2e9
commit c1c285782d
5 changed files with 34 additions and 80 deletions

View file

@ -1021,9 +1021,6 @@ LLValue *DtoArrayLen(DValue *v) {
Type *t = v->type->toBasetype(); Type *t = v->type->toBasetype();
if (t->ty == Tarray) { if (t->ty == Tarray) {
if (DSliceValue *s = v->isSlice()) {
return s->len;
}
if (v->isNull()) { if (v->isNull()) {
return DtoConstSize_t(0); return DtoConstSize_t(0);
} }
@ -1054,9 +1051,7 @@ LLValue *DtoArrayPtr(DValue *v) {
LLValue *ptr = nullptr; LLValue *ptr = nullptr;
if (t->ty == Tarray) { if (t->ty == Tarray) {
if (DSliceValue *s = v->isSlice()) { if (v->isNull()) {
ptr = s->ptr;
} else if (v->isNull()) {
ptr = getNullPtr(wantedLLPtrType); ptr = getNullPtr(wantedLLPtrType);
} else if (v->isLVal()) { } else if (v->isLVal()) {
ptr = DtoLoad(DtoGEPi(v->getLVal(), 0, 1), ".ptr"); ptr = DtoLoad(DtoGEPi(v->getLVal(), 0, 1), ".ptr");

View file

@ -16,7 +16,7 @@
#include "gen/tollvm.h" #include "gen/tollvm.h"
namespace { namespace {
bool isDefinedInFuncEntryBB(llvm::Value *v) { bool isDefinedInFuncEntryBB(LLValue *v) {
auto instr = llvm::dyn_cast<llvm::Instruction>(v); auto instr = llvm::dyn_cast<llvm::Instruction>(v);
if (!instr) { if (!instr) {
// Global, constant, ... // Global, constant, ...
@ -36,7 +36,11 @@ bool isDefinedInFuncEntryBB(llvm::Value *v) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool DImValue::definedInFuncEntryBB() { return isDefinedInFuncEntryBB(val); } bool DValue::definedInFuncEntryBB() { return isDefinedInFuncEntryBB(val); }
////////////////////////////////////////////////////////////////////////////////
DConstValue::DConstValue(Type *t, llvm::Constant *con) : DValue(t, con) {}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -72,9 +76,7 @@ DVarValue::DVarValue(Type *t, LLValue *v, bool isSpecialRefVar)
LLValue *DVarValue::getLVal() { return isSpecialRefVar ? DtoLoad(val) : val; } LLValue *DVarValue::getLVal() { return isSpecialRefVar ? DtoLoad(val) : val; }
LLValue *DVarValue::getRVal() { LLValue *DVarValue::getRVal() {
assert(val); LLValue *storage = val;
llvm::Value *storage = val;
if (isSpecialRefVar) { if (isSpecialRefVar) {
storage = DtoLoad(storage); storage = DtoLoad(storage);
} }
@ -83,7 +85,7 @@ LLValue *DVarValue::getRVal() {
return storage; return storage;
} }
llvm::Value *rawValue = DtoLoad(storage); LLValue *rawValue = DtoLoad(storage);
if (type->toBasetype()->ty == Tbool) { if (type->toBasetype()->ty == Tbool) {
assert(rawValue->getType() == llvm::Type::getInt8Ty(gIR->context())); assert(rawValue->getType() == llvm::Type::getInt8Ty(gIR->context()));
@ -99,19 +101,14 @@ LLValue *DVarValue::getRefStorage() {
return val; return val;
} }
bool DVarValue::definedInFuncEntryBB() { return isDefinedInFuncEntryBB(val); }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
LLValue *DSliceValue::getRVal() { DSliceValue::DSliceValue(Type *t, LLValue *length, LLValue *ptr)
assert(len); : DValue(t, DtoAggrPair(length, ptr)) {}
assert(ptr);
return DtoAggrPair(len, ptr);
}
bool DSliceValue::definedInFuncEntryBB() { LLValue *DSliceValue::getLength() { return DtoExtractValue(val, 0, ".len"); }
return isDefinedInFuncEntryBB(len) && isDefinedInFuncEntryBB(ptr);
} LLValue *DSliceValue::getPtr() { return DtoExtractValue(val, 1, ".ptr"); }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -121,29 +118,7 @@ DFuncValue::DFuncValue(Type *t, FuncDeclaration *fd, LLValue *v, LLValue *vt)
DFuncValue::DFuncValue(FuncDeclaration *fd, LLValue *v, LLValue *vt) DFuncValue::DFuncValue(FuncDeclaration *fd, LLValue *v, LLValue *vt)
: DValue(fd->type, v), func(fd), vthis(vt) {} : DValue(fd->type, v), func(fd), vthis(vt) {}
LLValue *DFuncValue::getRVal() {
assert(val);
return val;
}
bool DFuncValue::definedInFuncEntryBB() { bool DFuncValue::definedInFuncEntryBB() {
if (!isDefinedInFuncEntryBB(val)) { return isDefinedInFuncEntryBB(val) &&
return false; (!vthis || isDefinedInFuncEntryBB(vthis));
}
if (vthis && !isDefinedInFuncEntryBB(vthis)) {
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
DConstValue::DConstValue(Type *t, llvm::Constant *con)
: DValue(t, static_cast<LLValue *>(con)) {}
LLValue *DConstValue::getRVal() {
assert(val);
return val;
} }

View file

@ -50,10 +50,7 @@ public:
assert(0); assert(0);
return nullptr; return nullptr;
} }
virtual llvm::Value *getRVal() { virtual llvm::Value *getRVal() { return val; }
assert(0);
return nullptr;
}
virtual bool isLVal() { return false; } virtual bool isLVal() { return false; }
@ -65,7 +62,7 @@ public:
/// In other words, whatever value the result of getLVal()/getRVal() might be /// In other words, whatever value the result of getLVal()/getRVal() might be
/// derived from then certainly dominates uses in all other basic blocks of /// derived from then certainly dominates uses in all other basic blocks of
/// the function. /// the function.
virtual bool definedInFuncEntryBB() = 0; virtual bool definedInFuncEntryBB();
virtual DImValue *isIm() { return nullptr; } virtual DImValue *isIm() { return nullptr; }
virtual DConstValue *isConst() { return nullptr; } virtual DConstValue *isConst() { return nullptr; }
@ -75,7 +72,10 @@ public:
virtual DFuncValue *isFunc() { return nullptr; } virtual DFuncValue *isFunc() { return nullptr; }
protected: protected:
DValue(Type *t, llvm::Value *v) : type(t), val(v) {} DValue(Type *t, llvm::Value *v) : type(t), val(v) {
assert(type);
assert(val);
}
}; };
// immediate d-value // immediate d-value
@ -83,13 +83,6 @@ class DImValue : public DValue {
public: public:
DImValue(Type *t, llvm::Value *v) : DValue(t, v) {} DImValue(Type *t, llvm::Value *v) : DValue(t, v) {}
llvm::Value *getRVal() override {
assert(val);
return val;
}
bool definedInFuncEntryBB() override;
DImValue *isIm() override { return this; } DImValue *isIm() override { return this; }
}; };
@ -98,8 +91,6 @@ class DConstValue : public DValue {
public: public:
DConstValue(Type *t, llvm::Constant *con); DConstValue(Type *t, llvm::Constant *con);
llvm::Value *getRVal() override;
bool definedInFuncEntryBB() override { return true; } bool definedInFuncEntryBB() override { return true; }
DConstValue *isConst() override { return this; } DConstValue *isConst() override { return this; }
@ -109,6 +100,7 @@ public:
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) {}
DNullValue *isNull() override { return this; } DNullValue *isNull() override { return this; }
}; };
@ -122,6 +114,7 @@ public:
DVarValue(Type *t, llvm::Value *v, bool isSpecialRefVar = false); DVarValue(Type *t, llvm::Value *v, bool isSpecialRefVar = false);
bool isLVal() override { return true; } bool isLVal() override { return true; }
llvm::Value *getLVal() override; llvm::Value *getLVal() override;
llvm::Value *getRVal() override; llvm::Value *getRVal() override;
@ -129,45 +122,36 @@ public:
/// Illegal to call on any other value. /// Illegal to call on any other value.
llvm::Value *getRefStorage(); llvm::Value *getRefStorage();
bool definedInFuncEntryBB() override;
DVarValue *isVar() override { return this; } DVarValue *isVar() override { return this; }
protected: protected:
bool const isSpecialRefVar; const bool isSpecialRefVar;
}; };
// slice d-value // slice d-value
class DSliceValue : public DValue { class DSliceValue : public DValue {
public: public:
DSliceValue(Type *t, llvm::Value *l, llvm::Value *p) DSliceValue(Type *t, llvm::Value *length, llvm::Value *ptr);
: DValue(t, nullptr), len(l), ptr(p) {}
llvm::Value *getRVal() override;
bool definedInFuncEntryBB() override;
DSliceValue *isSlice() override { return this; } DSliceValue *isSlice() override { return this; }
llvm::Value *len; llvm::Value *getLength();
llvm::Value *ptr; llvm::Value *getPtr();
}; };
// function d-value // function d-value
class DFuncValue : public DValue { class DFuncValue : public DValue {
public: public:
FuncDeclaration *func;
llvm::Value *vthis;
DFuncValue(Type *t, FuncDeclaration *fd, llvm::Value *v, DFuncValue(Type *t, FuncDeclaration *fd, llvm::Value *v,
llvm::Value *vt = nullptr); llvm::Value *vt = nullptr);
DFuncValue(FuncDeclaration *fd, llvm::Value *v, llvm::Value *vt = nullptr); DFuncValue(FuncDeclaration *fd, llvm::Value *v, llvm::Value *vt = nullptr);
llvm::Value *getRVal() override;
bool definedInFuncEntryBB() override; bool definedInFuncEntryBB() override;
DFuncValue *isFunc() override { return this; } DFuncValue *isFunc() override { return this; }
FuncDeclaration *func;
llvm::Value *vthis;
}; };
#endif // LDC_GEN_DVALUE_H #endif // LDC_GEN_DVALUE_H

View file

@ -699,8 +699,8 @@ DValue *DtoPaintType(Loc &loc, DValue *val, Type *to) {
assert(at->ty == Tarray); assert(at->ty == Tarray);
Type *elem = at->nextOf()->pointerTo(); Type *elem = at->nextOf()->pointerTo();
if (DSliceValue *slice = val->isSlice()) { if (DSliceValue *slice = val->isSlice()) {
return new DSliceValue(to, slice->len, return new DSliceValue(to, slice->getLength(),
DtoBitCast(slice->ptr, DtoType(elem))); DtoBitCast(slice->getPtr(), DtoType(elem)));
} }
if (val->isLVal()) { if (val->isLVal()) {
LLValue *ptr = val->getLVal(); LLValue *ptr = val->getLVal();

View file

@ -2491,7 +2491,7 @@ public:
e->loc, arrayType, e->loc, arrayType,
new DConstValue(Type::tsize_t, DtoConstSize_t(len)), false); new DConstValue(Type::tsize_t, DtoConstSize_t(len)), false);
initializeArrayLiteral( initializeArrayLiteral(
p, e, DtoBitCast(dynSlice->ptr, getPtrToType(llStoType))); p, e, DtoBitCast(dynSlice->getPtr(), getPtrToType(llStoType)));
result = dynSlice; result = dynSlice;
} }
} else { } else {