[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