mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-14 23:29:10 +03:00
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:
parent
e3e2f4b2e9
commit
c1c285782d
5 changed files with 34 additions and 80 deletions
|
@ -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");
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
46
gen/dvalue.h
46
gen/dvalue.h
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue