mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-10 12:59:21 +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();
|
||||
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");
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
46
gen/dvalue.h
46
gen/dvalue.h
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue