[PATCH] D48541: [Function] Use deterministic IDs when mangling unnamed types.

Florian Hahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 25 04:01:52 PDT 2018


fhahn created this revision.
fhahn added reviewers: davide, chandlerc, craig.topper, rnk.
Herald added a subscriber: mgrang.

For generic intrinsics, Intrinsic::getDeclaration expects a unique
declaration for each unique set of parameter types. This means, for each
set of unique parameter types, we need a unique mangled name.

Currently this is not the case, as unnamed types do not have a name, so
different unnamed types will get mangled to the same name. This causes a
crash when using PredicateInfo with the test case attached.

This patch introduces an additional map to LLVMContextImpl, which keeps
track of IDs to use when mangling for unnamed types. It is populated on
demand when mangling. I am not sure if this is the best approach, but it
seems to do the job.


https://reviews.llvm.org/D48541

Files:
  lib/IR/Function.cpp
  lib/IR/LLVMContextImpl.h
  test/Transforms/Util/PredicateInfo/unnamed-types.ll


Index: test/Transforms/Util/PredicateInfo/unnamed-types.ll
===================================================================
--- /dev/null
+++ test/Transforms/Util/PredicateInfo/unnamed-types.ll
@@ -0,0 +1,36 @@
+; RUN: opt < %s -print-predicateinfo 2>&1 | FileCheck %s
+
+; Check we can use ssa.copy with unnamed types.
+
+; CHECK-LABEL: bb:
+; CHECK: Has predicate info
+; CHECK: branch predicate info { TrueEdge: 1 Comparison:  %cmp1 = icmp ne %1* %arg, null Edge: [label %bb,label %bb1] }
+; CHECK-NEXT:  %arg.0 = call %1* @llvm.ssa.copy.p0s_{{.+}}s(%1* %arg)
+
+; CHECK-LABEL: bb1:
+; CHECK: Has predicate info
+; CHECK-NEXT: branch predicate info { TrueEdge: 0 Comparison:  %cmp2 = icmp ne %0* null, %tmp Edge: [label %bb1,label %bb3] }
+; CHECK-NAME: %tmp.0 = call %0* @llvm.ssa.copy.p0s_{{.+}}s(%0* %tmp)
+
+%0 = type opaque
+%1 = type opaque
+
+declare i8* @fun(%1*)
+
+define void @f0(%0* %arg, %1* %tmp) {
+bb:
+  %cmp1 = icmp ne %0* %arg, null
+  br i1 %cmp1, label %bb1, label %bb2
+
+bb1:                                              ; preds = %bb
+  %cmp2 = icmp ne %1* null, %tmp
+  br i1 %cmp2, label %bb2, label %bb3
+
+bb2:                                              ; preds = %bb
+  ret void
+
+bb3:                                              ; preds = %bb
+  call i8* @fun(%1* %tmp)
+  %tmp2 = bitcast %0* %arg to i8*
+  ret void
+}
Index: lib/IR/LLVMContextImpl.h
===================================================================
--- lib/IR/LLVMContextImpl.h
+++ lib/IR/LLVMContextImpl.h
@@ -1306,7 +1306,12 @@
   StructTypeSet AnonStructTypes;
   StringMap<StructType*> NamedStructTypes;
   unsigned NamedStructTypesUniqueID = 0;
-    
+
+  /// Mapping from unnamed struct types to a deterministic ID for mangling.
+  /// It is populated on demand.
+  DenseMap<StructType *, unsigned> AnonStructTypesIDs;
+  unsigned AnonStructTypesUniqueID = 0;
+
   DenseMap<std::pair<Type *, uint64_t>, ArrayType*> ArrayTypes;
   DenseMap<std::pair<Type *, unsigned>, VectorType*> VectorTypes;
   DenseMap<Type*, PointerType*> PointerTypes;  // Pointers in AddrSpace = 0
Index: lib/IR/Function.cpp
===================================================================
--- lib/IR/Function.cpp
+++ lib/IR/Function.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/IR/Function.h"
+#include "LLVMContextImpl.h"
 #include "SymbolTableListTraitsImpl.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseSet.h"
@@ -570,7 +571,21 @@
   } else if (StructType *STyp = dyn_cast<StructType>(Ty)) {
     if (!STyp->isLiteral()) {
       Result += "s_";
-      Result += STyp->getName();
+      if (STyp->hasName())
+        Result += STyp->getName();
+      else {
+        // Different unnamed struct types should get mangled to different names,
+        // so we keep a mapping of types to ids to get deterministic naming.
+        // The mapping is populated on demand here.
+        DenseMap<StructType *, unsigned> &AnonIDs =
+            STyp->getContext().pImpl->AnonStructTypesIDs;
+        unsigned &AnonID = STyp->getContext().pImpl->AnonStructTypesUniqueID;
+        auto I = AnonIDs.insert({STyp, AnonID});
+        if (I.second)
+          AnonID++;
+
+        Result += Twine(I.first->second).str();
+      }
     } else {
       Result += "sl_";
       for (auto Elem : STyp->elements())


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D48541.152653.patch
Type: text/x-patch
Size: 3384 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180625/58fcf317/attachment.bin>


More information about the llvm-commits mailing list