aeubanks updated this revision to Diff 406077.
aeubanks added a comment.

fix more issues, ready to review
I've split the OpenCL change out into D119011 
<https://reviews.llvm.org/D119011>, will rebase once that's submitted


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D118744/new/

https://reviews.llvm.org/D118744

Files:
  clang/lib/CodeGen/CGBuilder.h
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CGOpenCLRuntime.cpp
  clang/lib/CodeGen/CGOpenCLRuntime.h
  clang/lib/CodeGen/CodeGenTypes.cpp
  clang/test/CodeGenCXX/type-cache-2.cpp
  clang/test/CodeGenCXX/type-cache-3.cpp
  clang/test/CodeGenCXX/type-cache.cpp

Index: clang/test/CodeGenCXX/type-cache.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/type-cache.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -mllvm -verify-type-cache -emit-llvm %s -o - -triple i386-pc-windows-msvc19.16.0 | FileCheck %s
+// REQUIRES: asserts, x86-registered-target
+
+// CHECK: call {}* @"?f@@YA?AUz@@XZ"()
+
+struct z {
+  z (*p)();
+};
+
+z f();
+
+void g() {
+  f();
+}
Index: clang/test/CodeGenCXX/type-cache-3.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/type-cache-3.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -mllvm -verify-type-cache -emit-llvm %s -o - -triple i386-pc-windows-msvc19.16.0 | FileCheck %s
+// REQUIRES: asserts, x86-registered-target
+
+// CHECK-LABEL: define {{.*}}@"?f@@YAXXZ"(
+// CHECK: call void @"?dc@z@@SAXU1@@Z"
+
+// CHECK-LABEL: define {{.*}}@"?dc@z@@SAXU1@@Z"(
+// CHECK: store void ({}*)* %{{.*}}, void ({}*)** %{{.*}}
+struct z {
+  static void dc(z) {}
+  void (*p)(z);
+};
+
+void f() {
+  z::dc({});
+}
Index: clang/test/CodeGenCXX/type-cache-2.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/type-cache-2.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -mllvm -verify-type-cache -emit-llvm %s -o - -triple i386-pc-windows-msvc19.16.0 | FileCheck %s
+// REQUIRES: asserts, x86-registered-target
+
+// CHECK: call void @"?dc@z@@SAXU1@@Z"
+struct z {
+  static void dc(z);
+  void (*p)(z);
+};
+
+void f() {
+  z::dc({});
+}
Index: clang/lib/CodeGen/CodeGenTypes.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenTypes.cpp
+++ clang/lib/CodeGen/CodeGenTypes.cpp
@@ -25,9 +25,20 @@
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Module.h"
+
 using namespace clang;
 using namespace CodeGen;
 
+#ifndef NDEBUG
+#include "llvm/Support/CommandLine.h"
+// TODO: turn on by default when defined(EXPENSIVE_CHECKS) once check-clang is
+// -verify-type-cache clean.
+static llvm::cl::opt<bool> VerifyTypeCache(
+    "verify-type-cache",
+    llvm::cl::desc("Verify that the type cache matches the computed type"),
+    llvm::cl::init(false), llvm::cl::Hidden);
+#endif
+
 CodeGenTypes::CodeGenTypes(CodeGenModule &cgm)
   : CGM(cgm), Context(cgm.getContext()), TheModule(cgm.getModule()),
     Target(cgm.getTarget()), TheCXXABI(cgm.getCXXABI()),
@@ -382,9 +393,6 @@
 
   RecordsBeingLaidOut.erase(Ty);
 
-  if (SkippedLayout)
-    TypeCache.clear();
-
   if (RecordsBeingLaidOut.empty())
     while (!DeferredRecords.empty())
       ConvertRecordDeclType(DeferredRecords.pop_back_val());
@@ -415,11 +423,29 @@
   if (const RecordType *RT = dyn_cast<RecordType>(Ty))
     return ConvertRecordDeclType(RT->getDecl());
 
-  // See if type is already cached.
-  llvm::DenseMap<const Type *, llvm::Type *>::iterator TCI = TypeCache.find(Ty);
-  // If type is found in map then use it. Otherwise, convert type T.
-  if (TCI != TypeCache.end())
-    return TCI->second;
+  // The LLVM type we return for a given Clang type may not always be the same,
+  // most notably when dealing with recursive structs. We mark these potential
+  // cases with ShouldUseCache below. Builtin types cannot be recursive.
+  // TODO: when clang uses LLVM opaque pointers we won't be able to represent
+  // recursive types with LLVM types, making this logic much simpler.
+  llvm::Type *CachedType = nullptr;
+  bool ShouldUseCache =
+      Ty->isBuiltinType() ||
+      (noRecordsBeingLaidOut() && FunctionsBeingProcessed.empty());
+  if (ShouldUseCache) {
+    llvm::DenseMap<const Type *, llvm::Type *>::iterator TCI =
+        TypeCache.find(Ty);
+    if (TCI != TypeCache.end())
+      CachedType = TCI->second;
+    if (CachedType) {
+#ifndef NDEBUG
+      if (!VerifyTypeCache)
+        return CachedType;
+#else
+      return CachedType;
+#endif
+    }
+  }
 
   // If we don't have it in the cache, convert it now.
   llvm::Type *ResultType = nullptr;
@@ -797,7 +823,15 @@
 
   assert(ResultType && "Didn't convert a type?");
 
-  TypeCache[Ty] = ResultType;
+#ifndef NDEBUG
+  if (CachedType) {
+    assert(CachedType == ResultType &&
+           "Cached type doesn't match computed type");
+  }
+#endif
+
+  if (ShouldUseCache)
+    TypeCache[Ty] = ResultType;
   return ResultType;
 }
 
Index: clang/lib/CodeGen/CGOpenCLRuntime.h
===================================================================
--- clang/lib/CodeGen/CGOpenCLRuntime.h
+++ clang/lib/CodeGen/CGOpenCLRuntime.h
@@ -18,6 +18,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/Type.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/IR/Type.h"
 #include "llvm/IR/Value.h"
 
@@ -38,6 +39,7 @@
   llvm::Type *PipeROTy;
   llvm::Type *PipeWOTy;
   llvm::PointerType *SamplerTy;
+  llvm::StringMap<llvm::PointerType *> Tys;
 
   /// Structure for enqueued block information.
   struct EnqueuedBlockInfo {
@@ -50,6 +52,7 @@
 
   virtual llvm::Type *getPipeType(const PipeType *T, StringRef Name,
                                   llvm::Type *&PipeTy);
+  llvm::PointerType *getType(const Type *T, StringRef Name);
 
 public:
   CGOpenCLRuntime(CodeGenModule &CGM) : CGM(CGM),
Index: clang/lib/CodeGen/CGOpenCLRuntime.cpp
===================================================================
--- clang/lib/CodeGen/CGOpenCLRuntime.cpp
+++ clang/lib/CodeGen/CGOpenCLRuntime.cpp
@@ -34,41 +34,45 @@
   assert(T->isOpenCLSpecificType() &&
          "Not an OpenCL specific type!");
 
-  llvm::LLVMContext& Ctx = CGM.getLLVMContext();
-  uint32_t AddrSpc = CGM.getContext().getTargetAddressSpace(
-      CGM.getContext().getOpenCLTypeAddrSpace(T));
   switch (cast<BuiltinType>(T)->getKind()) {
   default:
     llvm_unreachable("Unexpected opencl builtin type!");
     return nullptr;
-#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
-  case BuiltinType::Id: \
-    return llvm::PointerType::get( \
-        llvm::StructType::create(Ctx, "opencl." #ImgType "_" #Suffix "_t"), \
-        AddrSpc);
+#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix)                   \
+  case BuiltinType::Id:                                                        \
+    return getType(T, "opencl." #ImgType "_" #Suffix "_t");
 #include "clang/Basic/OpenCLImageTypes.def"
   case BuiltinType::OCLSampler:
     return getSamplerType(T);
   case BuiltinType::OCLEvent:
-    return llvm::PointerType::get(
-        llvm::StructType::create(Ctx, "opencl.event_t"), AddrSpc);
+    return getType(T, "opencl.event_t");
   case BuiltinType::OCLClkEvent:
-    return llvm::PointerType::get(
-        llvm::StructType::create(Ctx, "opencl.clk_event_t"), AddrSpc);
+    return getType(T, "opencl.clk_event_t");
   case BuiltinType::OCLQueue:
-    return llvm::PointerType::get(
-        llvm::StructType::create(Ctx, "opencl.queue_t"), AddrSpc);
+    return getType(T, "opencl.queue_t");
   case BuiltinType::OCLReserveID:
-    return llvm::PointerType::get(
-        llvm::StructType::create(Ctx, "opencl.reserve_id_t"), AddrSpc);
-#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
-  case BuiltinType::Id: \
-    return llvm::PointerType::get( \
-        llvm::StructType::create(Ctx, "opencl." #ExtType), AddrSpc);
+    return getType(T, "opencl.reserve_id_t");
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext)                                      \
+  case BuiltinType::Id:                                                        \
+    return getType(T, "opencl." #ExtType);
 #include "clang/Basic/OpenCLExtensionTypes.def"
   }
 }
 
+llvm::PointerType *CGOpenCLRuntime::getType(const Type *T, StringRef Name) {
+  auto I = Tys.find(Name);
+  if (I != Tys.end())
+    return I->second;
+
+  llvm::LLVMContext &Ctx = CGM.getLLVMContext();
+  uint32_t AddrSpc = CGM.getContext().getTargetAddressSpace(
+      CGM.getContext().getOpenCLTypeAddrSpace(T));
+  auto *PTy =
+      llvm::PointerType::get(llvm::StructType::create(Ctx, Name), AddrSpc);
+  Tys[Name] = PTy;
+  return PTy;
+}
+
 llvm::Type *CGOpenCLRuntime::getPipeType(const PipeType *T) {
   if (T->isReadOnly())
     return getPipeType(T, "opencl.pipe_ro_t", PipeROTy);
Index: clang/lib/CodeGen/CGCall.cpp
===================================================================
--- clang/lib/CodeGen/CGCall.cpp
+++ clang/lib/CodeGen/CGCall.cpp
@@ -38,6 +38,7 @@
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Type.h"
 #include "llvm/Transforms/Utils/Local.h"
 using namespace clang;
 using namespace CodeGen;
@@ -1056,10 +1057,19 @@
     // Call EmitStoreOfScalar except when the lvalue is a bitfield to emit a
     // primitive store.
     assert(isa<NoExpansion>(Exp.get()));
-    if (LV.isBitField())
-      EmitStoreThroughLValue(RValue::get(&*AI++), LV);
-    else
-      EmitStoreOfScalar(&*AI++, LV);
+    llvm::Value *Arg = &*AI++;
+    if (LV.isBitField()) {
+      EmitStoreThroughLValue(RValue::get(Arg), LV);
+    } else {
+      // TODO: currently there are some places are inconsistent in what LLVM
+      // pointer type they use (see D118744). Once clang uses opaque pointers
+      // all LLVM pointer types will be the same and we can remove this check.
+      if (Arg->getType()->isPointerTy()) {
+        Address Addr = LV.getAddress(*this);
+        Arg = Builder.CreateBitCast(Arg, Addr.getElementType());
+      }
+      EmitStoreOfScalar(Arg, LV);
+    }
   }
 }
 
Index: clang/lib/CodeGen/CGBuilder.h
===================================================================
--- clang/lib/CodeGen/CGBuilder.h
+++ clang/lib/CodeGen/CGBuilder.h
@@ -9,10 +9,11 @@
 #ifndef LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H
 #define LLVM_CLANG_LIB_CODEGEN_CGBUILDER_H
 
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/IRBuilder.h"
 #include "Address.h"
 #include "CodeGenTypeCache.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Type.h"
 
 namespace clang {
 namespace CodeGen {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to