[PATCH] D50436: Correctly initialise global blocks on Windows.

David Chisnall via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 9 01:03:27 PDT 2018


This revision was automatically updated to reflect the committed changes.
Closed by commit rL339317: Correctly initialise global blocks on Windows. (authored by theraven, committed by ).
Herald added a subscriber: llvm-commits.

Repository:
  rL LLVM

https://reviews.llvm.org/D50436

Files:
  cfe/trunk/lib/CodeGen/CGBlocks.cpp
  cfe/trunk/test/CodeGen/global-blocks-win32.c


Index: cfe/trunk/test/CodeGen/global-blocks-win32.c
===================================================================
--- cfe/trunk/test/CodeGen/global-blocks-win32.c
+++ cfe/trunk/test/CodeGen/global-blocks-win32.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fblocks -triple i386-pc-windows-msvc %s -emit-llvm -o - -fblocks | FileCheck %s
+
+
+int (^x)(void) = ^() { return 21; };
+
+
+// Check that the block literal is emitted with a null isa pointer
+// CHECK: @__block_literal_global = internal global { i8**, i32, i32, i8*, %struct.__block_descriptor* } { i8** null, 
+
+// Check that _NSConcreteGlobalBlock has the correct dllimport specifier.
+// CHECK: @_NSConcreteGlobalBlock = external dllimport global i8*
+// Check that we create an initialiser pointer in the correct section (early library initialisation).
+// CHECK: @.block_isa_init_ptr = internal constant void ()* @.block_isa_init, section ".CRT$XCLa"
+
+// Check that we emit an initialiser for it.
+// CHECK: define internal void @.block_isa_init() {
+// CHECK: store i8** @_NSConcreteGlobalBlock, i8*** getelementptr inbounds ({ i8**, i32, i32, i8*, %struct.__block_descriptor* }, { i8**, i32, i32, i8*, %struct.__block_descriptor* }* @__block_literal_global, i32 0, i32 0), align 4
+
Index: cfe/trunk/lib/CodeGen/CGBlocks.cpp
===================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp
@@ -1213,9 +1213,13 @@
   auto fields = builder.beginStruct();
 
   bool IsOpenCL = CGM.getLangOpts().OpenCL;
+  bool IsWindows = CGM.getTarget().getTriple().isOSWindows();
   if (!IsOpenCL) {
     // isa
-    fields.add(CGM.getNSConcreteGlobalBlock());
+    if (IsWindows)
+      fields.addNullPointer(CGM.Int8PtrPtrTy);
+    else
+      fields.add(CGM.getNSConcreteGlobalBlock());
 
     // __flags
     BlockFlags flags = BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE;
@@ -1250,7 +1254,27 @@
 
   llvm::Constant *literal = fields.finishAndCreateGlobal(
       "__block_literal_global", blockInfo.BlockAlign,
-      /*constant*/ true, llvm::GlobalVariable::InternalLinkage, AddrSpace);
+      /*constant*/ !IsWindows, llvm::GlobalVariable::InternalLinkage, AddrSpace);
+
+  // Windows does not allow globals to be initialised to point to globals in
+  // different DLLs.  Any such variables must run code to initialise them.
+  if (IsWindows) {
+    auto *Init = llvm::Function::Create(llvm::FunctionType::get(CGM.VoidTy,
+          {}), llvm::GlobalValue::InternalLinkage, ".block_isa_init",
+        &CGM.getModule());
+    llvm::IRBuilder<> b(llvm::BasicBlock::Create(CGM.getLLVMContext(), "entry",
+          Init));
+    b.CreateAlignedStore(CGM.getNSConcreteGlobalBlock(),
+        b.CreateStructGEP(literal, 0), CGM.getPointerAlign().getQuantity());
+    b.CreateRetVoid();
+    // We can't use the normal LLVM global initialisation array, because we
+    // need to specify that this runs early in library initialisation.
+    auto *InitVar = new llvm::GlobalVariable(CGM.getModule(), Init->getType(),
+        /*isConstant*/true, llvm::GlobalValue::InternalLinkage,
+        Init, ".block_isa_init_ptr");
+    InitVar->setSection(".CRT$XCLa");
+    CGM.addUsedGlobal(InitVar);
+  }
 
   // Return a constant of the appropriately-casted type.
   llvm::Type *RequiredType =


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D50436.159867.patch
Type: text/x-patch
Size: 3315 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180809/22a73963/attachment.bin>


More information about the llvm-commits mailing list