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

View file

@ -16,7 +16,7 @@
#include "gen/tollvm.h"
namespace {
bool isDefinedInFuncEntryBB(llvm::Value *v) {
bool isDefinedInFuncEntryBB(LLValue *v) {
auto instr = llvm::dyn_cast<llvm::Instruction>(v);
if (!instr) {
// 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::getRVal() {
assert(val);
llvm::Value *storage = val;
LLValue *storage = val;
if (isSpecialRefVar) {
storage = DtoLoad(storage);
}
@ -83,7 +85,7 @@ LLValue *DVarValue::getRVal() {
return storage;
}
llvm::Value *rawValue = DtoLoad(storage);
LLValue *rawValue = DtoLoad(storage);
if (type->toBasetype()->ty == Tbool) {
assert(rawValue->getType() == llvm::Type::getInt8Ty(gIR->context()));
@ -99,19 +101,14 @@ LLValue *DVarValue::getRefStorage() {
return val;
}
bool DVarValue::definedInFuncEntryBB() { return isDefinedInFuncEntryBB(val); }
////////////////////////////////////////////////////////////////////////////////
LLValue *DSliceValue::getRVal() {
assert(len);
assert(ptr);
return DtoAggrPair(len, ptr);
}
DSliceValue::DSliceValue(Type *t, LLValue *length, LLValue *ptr)
: DValue(t, DtoAggrPair(length, ptr)) {}
bool DSliceValue::definedInFuncEntryBB() {
return isDefinedInFuncEntryBB(len) && isDefinedInFuncEntryBB(ptr);
}
LLValue *DSliceValue::getLength() { return DtoExtractValue(val, 0, ".len"); }
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)
: DValue(fd->type, v), func(fd), vthis(vt) {}
LLValue *DFuncValue::getRVal() {
assert(val);
return val;
}
bool DFuncValue::definedInFuncEntryBB() {
if (!isDefinedInFuncEntryBB(val)) {
return false;
}
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;
return isDefinedInFuncEntryBB(val) &&
(!vthis || isDefinedInFuncEntryBB(vthis));
}

View file

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

View file

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

View file

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