[pkg-d-commits] [ldc] 32/74: [NFC] [dcompute] Make LDC somewhat aware of addrspaces. (#2122)
Matthias Klumpp
mak at moszumanska.debian.org
Thu Jul 13 20:54:16 UTC 2017
This is an automated email from the git hooks/post-receive script.
mak pushed a commit to annotated tag v1.3.0-beta2
in repository ldc.
commit 6c7f1b616e36a9770e75660775030bca08f13f92
Author: Nicholas Wilson <thewilsonator at users.noreply.github.com>
Date: Sun May 21 08:43:04 2017 +0800
[NFC] [dcompute] Make LDC somewhat aware of addrspaces. (#2122)
* [NFC] Make LDC somewhat aware of addrspaces.
Required so that we don't generate invalid code when dealing with pointer to addrspaces other than zero.
---
gen/dvalue.cpp | 14 +++++++++++---
gen/irstate.cpp | 2 +-
gen/irstate.h | 4 ++++
gen/tollvm.cpp | 28 ++++++++++++++++++++++++++--
gen/tollvm.h | 5 +++++
5 files changed, 47 insertions(+), 6 deletions(-)
diff --git a/gen/dvalue.cpp b/gen/dvalue.cpp
index 91a80d7..5671adb 100644
--- a/gen/dvalue.cpp
+++ b/gen/dvalue.cpp
@@ -62,7 +62,10 @@ DRValue::DRValue(Type *t, LLValue *v) : DValue(t, v) {
DImValue::DImValue(Type *t, llvm::Value *v) : DRValue(t, v) {
// TODO: get rid of Tfunction exception
- assert(t->toBasetype()->ty == Tfunction || v->getType() == DtoType(t));
+ // v may be an addrspace qualified pointer so strip it before doing a pointer
+ // equality check.
+ assert(t->toBasetype()->ty == Tfunction ||
+ stripAddrSpaces(v->getType()) == DtoType(t));
}
////////////////////////////////////////////////////////////////////////////////
@@ -75,7 +78,9 @@ DConstValue::DConstValue(Type *t, LLConstant *con) : DRValue(t, con) {
DSliceValue::DSliceValue(Type *t, LLValue *pair) : DRValue(t, pair) {
assert(t->toBasetype()->ty == Tarray);
- assert(pair->getType() == DtoType(t));
+ // v may be an addrspace qualified pointer so strip it before doing a pointer
+ // equality check.
+ assert(stripAddrSpaces(pair->getType()) == DtoType(t));
}
DSliceValue::DSliceValue(Type *t, LLValue *length, LLValue *ptr)
@@ -101,7 +106,10 @@ bool DFuncValue::definedInFuncEntryBB() {
////////////////////////////////////////////////////////////////////////////////
DLValue::DLValue(Type *t, LLValue *v) : DValue(t, v) {
- assert(t->toBasetype()->ty == Ttuple || v->getType() == DtoPtrToType(t));
+ // v may be an addrspace qualified pointer so strip it before doing a pointer
+ // equality check.
+ assert(t->toBasetype()->ty == Ttuple ||
+ stripAddrSpaces(v->getType()) == DtoPtrToType(t));
}
DRValue *DLValue::getRVal() {
diff --git a/gen/irstate.cpp b/gen/irstate.cpp
index e6d1f3e..d41e244 100644
--- a/gen/irstate.cpp
+++ b/gen/irstate.cpp
@@ -35,7 +35,7 @@ IRScope &IRScope::operator=(const IRScope &rhs) {
////////////////////////////////////////////////////////////////////////////////
IRState::IRState(const char *name, llvm::LLVMContext &context)
- : module(name, context), DBuilder(this) {
+ : module(name, context), DBuilder(this), dcomputetarget(nullptr) {
moduleRefType = nullptr;
dmodule = nullptr;
diff --git a/gen/irstate.h b/gen/irstate.h
index 3c73dc3..1e2f503 100644
--- a/gen/irstate.h
+++ b/gen/irstate.h
@@ -38,6 +38,7 @@ class IndexedInstrProfReader;
class FuncGenState;
struct IRState;
struct TargetABI;
+class DComputeTarget;
extern IRState *gIR;
extern llvm::TargetMachine *gTargetMachine;
@@ -210,6 +211,9 @@ struct IRState {
llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
llvm::DenseMap<llvm::Constant *, llvm::GlobalVariable *> TypeDescriptorMap;
#endif
+
+ //Target for dcompute. If not nullptr, it owns this.
+ DComputeTarget *dcomputetarget;
};
void Statement_toIR(Statement *s, IRState *irs);
diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp
index dbbecfd..c76c890 100644
--- a/gen/tollvm.cpp
+++ b/gen/tollvm.cpp
@@ -528,8 +528,31 @@ void DtoAlignedStore(LLValue *src, LLValue *dst) {
////////////////////////////////////////////////////////////////////////////////
+LLType *stripAddrSpaces(LLType *t)
+{
+ // Fastpath for normal compilation.
+ if(gIR->dcomputetarget == nullptr)
+ return t;
+
+ int indirections = 0;
+ while (t->isPointerTy()) {
+ indirections++;
+ t = t->getPointerElementType();
+ }
+ while (indirections-- != 0)
+ t = t->getPointerTo(0);
+
+ return t;
+}
+
LLValue *DtoBitCast(LLValue *v, LLType *t, const llvm::Twine &name) {
- if (v->getType() == t) {
+ // Strip addrspace qualifications from v before comparing types by pointer
+ // equality. This avoids the case where the pointer in { T addrspace(n)* }
+ // is dereferenced and generates a GEP -> (invalid) bitcast -> load sequence.
+ // Bitcasting of pointers between addrspaces is invalid in LLVM IR. Even if
+ // it were valid, it wouldn't be the desired outcome as we would always load
+ // from addrspace(0), instead of the addrspace of the pointer.
+ if (stripAddrSpaces(v->getType()) == t) {
return v;
}
assert(!isaStruct(t));
@@ -537,7 +560,8 @@ LLValue *DtoBitCast(LLValue *v, LLType *t, const llvm::Twine &name) {
}
LLConstant *DtoBitCast(LLConstant *v, LLType *t) {
- if (v->getType() == t) {
+ // Refer to the explanation in the other DtoBitCast overloaded function.
+ if (stripAddrSpaces(v->getType()) == t) {
return v;
}
return llvm::ConstantExpr::getBitCast(v, t);
diff --git a/gen/tollvm.h b/gen/tollvm.h
index ce3c64c..2c17265 100644
--- a/gen/tollvm.h
+++ b/gen/tollvm.h
@@ -41,6 +41,11 @@ LLPointerType *DtoPtrToType(Type *t);
LLType *voidToI8(LLType *t);
LLType *i1ToI8(LLType *t);
+// Removes all addrspace qualifications. float addrspace(1)** -> float**
+// Use when comparing pointers LLType* for equality with `== ` when one side
+// may be addrspace qualified.
+LLType *stripAddrSpaces(LLType *v);
+
// Returns true if the type is a value type which LDC keeps exclusively in
// memory, referencing all values via LL pointers (structs and static arrays).
bool DtoIsInMemoryOnly(Type *type);
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-d/ldc.git
More information about the pkg-d-commits
mailing list