r339317 - Correctly initialise global blocks on Windows.
Hans Wennborg via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 9 05:43:09 PDT 2018
Merged to 7.0 in r339339.
On Thu, Aug 9, 2018 at 10:02 AM, David Chisnall via cfe-commits
<cfe-commits at lists.llvm.org> wrote:
> Author: theraven
> Date: Thu Aug 9 01:02:42 2018
> New Revision: 339317
>
> URL: http://llvm.org/viewvc/llvm-project?rev=339317&view=rev
> Log:
> Correctly initialise global blocks on Windows.
>
> Summary:
> Windows does not allow globals to be initialised to point to globals in
> another DLL. Exported globals may be referenced only from code. Work
> around this by creating an initialiser that runs in early library
> initialisation and sets the isa pointer.
>
> Reviewers: rjmccall
>
> Reviewed By: rjmccall
>
> Subscribers: cfe-commits
>
> Differential Revision: https://reviews.llvm.org/D50436
>
> Added:
> cfe/trunk/test/CodeGen/global-blocks-win32.c
> Modified:
> cfe/trunk/lib/CodeGen/CGBlocks.cpp
>
> Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=339317&r1=339316&r2=339317&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Thu Aug 9 01:02:42 2018
> @@ -1213,9 +1213,13 @@ static llvm::Constant *buildGlobalBlock(
> 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 @@ static llvm::Constant *buildGlobalBlock(
>
> 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 =
>
> Added: cfe/trunk/test/CodeGen/global-blocks-win32.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/global-blocks-win32.c?rev=339317&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGen/global-blocks-win32.c (added)
> +++ cfe/trunk/test/CodeGen/global-blocks-win32.c Thu Aug 9 01:02:42 2018
> @@ -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
> +
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list