The attached patch is a first attempt at extending TBAA to handle OpenCL
address spaces.  Different metadata nodes will be created for the same type
in different address spaces, giving later alias analysis passes the
opportunity to detect that objects in different address spaces cannot alias.
 Note that this is only valid for OpenCL, at the moment.

I would like to get some feedback on this patch.  If possible, I would like
to commit it, or a variant of it, before the branch tonight.

-- 

Thanks,

Justin Holewinski
# HG changeset patch
# User Justin Holewinski <[email protected]>
# Date 1318615158 14400
# Node ID a633a289d2f65ff09ec2bc9c9bf9bd47eacda27d
# Parent  583a737205589254dc3b87c93d16072c01057a84
Extend TBAA to differentiate between memory spaces in OpenCL-mode

diff --git a/lib/CodeGen/CodeGenTBAA.cpp b/lib/CodeGen/CodeGenTBAA.cpp
--- a/lib/CodeGen/CodeGenTBAA.cpp
+++ b/lib/CodeGen/CodeGenTBAA.cpp
@@ -22,13 +22,14 @@
 #include "llvm/Metadata.h"
 #include "llvm/Constants.h"
 #include "llvm/Type.h"
+#include "llvm/ADT/StringExtras.h"
 using namespace clang;
 using namespace CodeGen;
 
 CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, llvm::LLVMContext& VMContext,
                          const LangOptions &Features, MangleContext &MContext)
   : Context(Ctx), VMContext(VMContext), Features(Features), MContext(MContext),
-    Root(0), Char(0) {
+    Root(0) {
 }
 
 CodeGenTBAA::~CodeGenTBAA() {
@@ -45,15 +46,37 @@
   return Root;
 }
 
-llvm::MDNode *CodeGenTBAA::getChar() {
+llvm::MDNode *CodeGenTBAA::getChar(Qualifiers& Quals) {
   // Define the root of the tree for user-accessible memory. C and C++
   // give special powers to char and certain similar types. However,
   // these special powers only cover user-accessible memory, and doesn't
   // include things like vtables.
-  if (!Char)
-    Char = getTBAAInfoForNamedType("omnipotent char", getRoot());
 
-  return Char;
+  // If we are not in OpenCL mode, treat everything as address space 0.
+  unsigned AS = 0;
+  if (Context.getLangOptions().OpenCL)
+    AS = Quals.getAddressSpace();
+
+  if (CharCache.count(AS)) {
+    return CharCache.lookup(AS);
+  } else {
+    std::string Name = "omnipotent char";
+    // If we are in OpenCL mode, add an address space identifier to the name.
+    if (Context.getLangOptions().OpenCL) {
+      switch (AS) {
+      default:
+        Name += " - OCL default";
+        break;
+      case LangAS::opencl_local:
+        Name += " - OCL local";
+        break;
+      case LangAS::opencl_global:
+        Name += " - OCL global";
+        break;
+      }
+    }
+    return CharCache[AS] = getTBAAInfoForNamedType(Name, getRoot());
+  }
 }
 
 /// getTBAAInfoForNamedType - Create a TBAA tree node with the given string
@@ -95,19 +118,32 @@
 }
 
 llvm::MDNode *
-CodeGenTBAA::getTBAAInfo(QualType QTy) {
+CodeGenTBAA::getTBAAInfo(QualType QTy, Qualifiers *Override) {
+
+  // Retrieve the canonical type and the qualifiers for this QualType.
+  const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
+
+  Qualifiers Quals;
+  if (Override)
+    Quals = *Override;
+  else
+    Quals = QTy.getQualifiers();
+
+  // Construct a tuple that represents this QualType.
+  std::pair<const Type *, unsigned> TypePair =
+    std::make_pair(Ty, Quals.getAsOpaqueValue());
+
   // If the type has the may_alias attribute (even on a typedef), it is
   // effectively in the general char alias class.
   if (TypeHasMayAlias(QTy))
-    return getChar();
+    return getChar(Quals);
 
-  const Type *Ty = Context.getCanonicalType(QTy).getTypePtr();
-
-  if (llvm::MDNode *N = MetadataCache[Ty])
+  if (llvm::MDNode *N = MetadataCache[TypePair])
     return N;
 
   // Handle builtin types.
   if (const BuiltinType *BTy = dyn_cast<BuiltinType>(Ty)) {
+    QualType NewTy;
     switch (BTy->getKind()) {
     // Character types are special and can alias anything.
     // In C++, this technically only includes "char" and "unsigned char",
@@ -118,26 +154,28 @@
     case BuiltinType::Char_S:
     case BuiltinType::UChar:
     case BuiltinType::SChar:
-      return getChar();
+      return getChar(Quals);
 
     // Unsigned types can alias their corresponding signed types.
+    // We copy over the qualifiers so the right metadata is emitted in OpenCL
+    // mode.
     case BuiltinType::UShort:
-      return getTBAAInfo(Context.ShortTy);
+      return getTBAAInfo(Context.ShortTy, &Quals);
     case BuiltinType::UInt:
-      return getTBAAInfo(Context.IntTy);
+      return getTBAAInfo(Context.IntTy, &Quals);
     case BuiltinType::ULong:
-      return getTBAAInfo(Context.LongTy);
+      return getTBAAInfo(Context.LongTy, &Quals);
     case BuiltinType::ULongLong:
-      return getTBAAInfo(Context.LongLongTy);
+      return getTBAAInfo(Context.LongLongTy, &Quals);
     case BuiltinType::UInt128:
-      return getTBAAInfo(Context.Int128Ty);
+      return getTBAAInfo(Context.Int128Ty, &Quals);
 
     // Treat all other builtin types as distinct types. This includes
     // treating wchar_t, char16_t, and char32_t as distinct from their
     // "underlying types".
     default:
-      return MetadataCache[Ty] =
-               getTBAAInfoForNamedType(BTy->getName(Features), getChar());
+      return MetadataCache[TypePair] =
+               getTBAAInfoForNamedType(BTy->getName(Features), getChar(Quals));
     }
   }
 
@@ -145,8 +183,8 @@
   // TODO: Implement C++'s type "similarity" and consider dis-"similar"
   // pointers distinct.
   if (Ty->isPointerType())
-    return MetadataCache[Ty] = getTBAAInfoForNamedType("any pointer",
-                                                       getChar());
+    return MetadataCache[TypePair] = getTBAAInfoForNamedType("any pointer",
+                                                       getChar(Quals));
 
   // Enum types are distinct types. In C++ they have "underlying types",
   // however they aren't related for TBAA.
@@ -157,7 +195,7 @@
     // members into a single identifying MDNode.
     if (!Features.CPlusPlus &&
         ETy->getDecl()->getTypedefNameForAnonDecl())
-      return MetadataCache[Ty] = getChar();
+      return MetadataCache[TypePair] = getChar(Quals);
 
     // In C++ mode, types have linkage, so we can rely on the ODR and
     // on their mangled names, if they're external.
@@ -165,7 +203,7 @@
     // decl with local linkage or no linkage?
     if (Features.CPlusPlus &&
         ETy->getDecl()->getLinkage() != ExternalLinkage)
-      return MetadataCache[Ty] = getChar();
+      return MetadataCache[TypePair] = getChar(Quals);
 
     // TODO: This is using the RTTI name. Is there a better way to get
     // a unique string for a type?
@@ -173,9 +211,10 @@
     llvm::raw_svector_ostream Out(OutName);
     MContext.mangleCXXRTTIName(QualType(ETy, 0), Out);
     Out.flush();
-    return MetadataCache[Ty] = getTBAAInfoForNamedType(OutName, getChar());
+    return MetadataCache[TypePair] = getTBAAInfoForNamedType(OutName,
+                                                             getChar(Quals));
   }
 
   // For now, handle any other kind of type conservatively.
-  return MetadataCache[Ty] = getChar();
+  return MetadataCache[TypePair] = getChar(Quals);
 }
diff --git a/lib/CodeGen/CodeGenTBAA.h b/lib/CodeGen/CodeGenTBAA.h
--- a/lib/CodeGen/CodeGenTBAA.h
+++ b/lib/CodeGen/CodeGenTBAA.h
@@ -28,6 +28,7 @@
   class LangOptions;
   class MangleContext;
   class QualType;
+  class Qualifiers;
   class Type;
 
 namespace CodeGen {
@@ -42,10 +43,12 @@
   MangleContext &MContext;
 
   /// MetadataCache - This maps clang::Types to llvm::MDNodes describing them.
-  llvm::DenseMap<const Type *, llvm::MDNode *> MetadataCache;
+  llvm::DenseMap<std::pair<const Type *, unsigned>, llvm::MDNode *>
+    MetadataCache;
 
   llvm::MDNode *Root;
-  llvm::MDNode *Char;
+
+  llvm::DenseMap<unsigned, llvm::MDNode *> CharCache;
 
   /// getRoot - This is the mdnode for the root of the metadata type graph
   /// for this translation unit.
@@ -53,7 +56,7 @@
 
   /// getChar - This is the mdnode for "char", which is special, and any types
   /// considered to be equivalent to it.
-  llvm::MDNode *getChar();
+  llvm::MDNode *getChar(Qualifiers& Quals);
 
   llvm::MDNode *getTBAAInfoForNamedType(StringRef NameStr,
                                         llvm::MDNode *Parent,
@@ -67,7 +70,7 @@
 
   /// getTBAAInfo - Get the TBAA MDNode to be used for a dereference
   /// of the given type.
-  llvm::MDNode *getTBAAInfo(QualType QTy);
+  llvm::MDNode *getTBAAInfo(QualType QTy, Qualifiers* Override = 0);
 };
 
 }  // end namespace CodeGen
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to