From 324f918438715b4a0d024af5930628c1674f4fcd Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sat, 19 Jan 2019 08:50:56 +0000 Subject: Update the file headers across all of the LLVM projects in the monorepo to reflect the new license. We understand that people may be surprised that we're moving the header entirely to discuss the new license. We checked this carefully with the Foundation's lawyer and we believe this is the correct approach. Essentially, all code in the project is now made available by the LLVM project under our new license, so you will see that the license headers include that license only. Some of our contributors have contributed code under our old license, and accordingly, we have retained a copy of our old license notice in the top-level files in each project and repository. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@351636 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGBlocks.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'lib/CodeGen/CGBlocks.cpp') diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index fa3c3ee861..b7c8cbdc90 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -1,9 +1,8 @@ //===--- CGBlocks.cpp - Emit LLVM Code for declarations ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // -- cgit v1.2.3 From 80600084724ec0ae1c5422aef719f8a22aa92c46 Mon Sep 17 00:00:00 2001 From: James Y Knight Date: Wed, 30 Jan 2019 02:54:28 +0000 Subject: Cleanup: replace uses of CallSite with CallBase. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@352595 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGBlocks.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/CodeGen/CGBlocks.cpp') diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index b7c8cbdc90..4df46eb9b5 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -22,7 +22,6 @@ #include "clang/AST/DeclObjC.h" #include "clang/CodeGen/ConstantInitBuilder.h" #include "llvm/ADT/SmallSet.h" -#include "llvm/IR/CallSite.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Module.h" #include "llvm/Support/ScopedPrinter.h" -- cgit v1.2.3 From 679ab5f7119cceb67c0753e596292bd2192a9d1f Mon Sep 17 00:00:00 2001 From: James Y Knight Date: Tue, 5 Feb 2019 16:42:33 +0000 Subject: [opaque pointer types] Pass function types for runtime function calls. Emit{Nounwind,}RuntimeCall{,OrInvoke} have been modified to take a FunctionCallee as an argument, and CreateRuntimeFunction has been modified to return a FunctionCallee. All callers have been updated. Additionally, CreateBuiltinFunction is removed, as it was redundant with CreateRuntimeFunction after some previous changes. Differential Revision: https://reviews.llvm.org/D57668 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@353184 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGBlocks.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'lib/CodeGen/CGBlocks.cpp') diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 4df46eb9b5..983fb56ec3 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -2284,7 +2284,7 @@ public: unsigned flags = (Flags | BLOCK_BYREF_CALLER).getBitMask(); llvm::Value *flagsVal = llvm::ConstantInt::get(CGF.Int32Ty, flags); - llvm::Value *fn = CGF.CGM.getBlockObjectAssign(); + llvm::FunctionCallee fn = CGF.CGM.getBlockObjectAssign(); llvm::Value *args[] = { destField.getPointer(), srcValue, flagsVal }; CGF.EmitNounwindRuntimeCall(fn, args); @@ -2931,7 +2931,7 @@ void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) { void CodeGenFunction::BuildBlockRelease(llvm::Value *V, BlockFieldFlags flags, bool CanThrow) { - llvm::Value *F = CGM.getBlockObjectDispose(); + llvm::FunctionCallee F = CGM.getBlockObjectDispose(); llvm::Value *args[] = { Builder.CreateBitCast(V, Int8PtrTy), llvm::ConstantInt::get(Int32Ty, flags.getBitMask()) @@ -2987,7 +2987,7 @@ static void configureBlocksRuntimeObject(CodeGenModule &CGM, CGM.setDSOLocal(GV); } -llvm::Constant *CodeGenModule::getBlockObjectDispose() { +llvm::FunctionCallee CodeGenModule::getBlockObjectDispose() { if (BlockObjectDispose) return BlockObjectDispose; @@ -2995,11 +2995,12 @@ llvm::Constant *CodeGenModule::getBlockObjectDispose() { llvm::FunctionType *fty = llvm::FunctionType::get(VoidTy, args, false); BlockObjectDispose = CreateRuntimeFunction(fty, "_Block_object_dispose"); - configureBlocksRuntimeObject(*this, BlockObjectDispose); + configureBlocksRuntimeObject( + *this, cast(BlockObjectDispose.getCallee())); return BlockObjectDispose; } -llvm::Constant *CodeGenModule::getBlockObjectAssign() { +llvm::FunctionCallee CodeGenModule::getBlockObjectAssign() { if (BlockObjectAssign) return BlockObjectAssign; @@ -3007,7 +3008,8 @@ llvm::Constant *CodeGenModule::getBlockObjectAssign() { llvm::FunctionType *fty = llvm::FunctionType::get(VoidTy, args, false); BlockObjectAssign = CreateRuntimeFunction(fty, "_Block_object_assign"); - configureBlocksRuntimeObject(*this, BlockObjectAssign); + configureBlocksRuntimeObject( + *this, cast(BlockObjectAssign.getCallee())); return BlockObjectAssign; } -- cgit v1.2.3 From 937984b3a98c5c2a3eef78d0b1d6573287ae97a6 Mon Sep 17 00:00:00 2001 From: James Y Knight Date: Sat, 9 Feb 2019 22:22:28 +0000 Subject: [opaque pointer types] Cleanup CGBuilder's Create*GEP. The various EltSize, Offset, DataLayout, and StructLayout arguments are all computable from the Address's element type and the DataLayout which the CGBuilder already has access to. After having previously asserted that the computed values are the same as those passed in, now remove the redundant arguments from CGBuilder's Create*GEP functions. Differential Revision: https://reviews.llvm.org/D57767 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@353629 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGBlocks.cpp | 66 ++++++++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 39 deletions(-) (limited to 'lib/CodeGen/CGBlocks.cpp') diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 983fb56ec3..1d4ce27e92 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -836,9 +836,8 @@ static void enterBlockScope(CodeGenFunction &CGF, BlockDecl *block) { } // GEP down to the address. - Address addr = CGF.Builder.CreateStructGEP(blockInfo.LocalAddress, - capture.getIndex(), - capture.getOffset()); + Address addr = + CGF.Builder.CreateStructGEP(blockInfo.LocalAddress, capture.getIndex()); // We can use that GEP as the dominating IP. if (!blockInfo.DominatingIP) @@ -975,27 +974,24 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { flags |= BLOCK_IS_NOESCAPE | BLOCK_IS_GLOBAL; } - auto projectField = - [&](unsigned index, CharUnits offset, const Twine &name) -> Address { - return Builder.CreateStructGEP(blockAddr, index, offset, name); - }; - auto storeField = - [&](llvm::Value *value, unsigned index, CharUnits offset, - const Twine &name) { - Builder.CreateStore(value, projectField(index, offset, name)); - }; + auto projectField = [&](unsigned index, const Twine &name) -> Address { + return Builder.CreateStructGEP(blockAddr, index, name); + }; + auto storeField = [&](llvm::Value *value, unsigned index, const Twine &name) { + Builder.CreateStore(value, projectField(index, name)); + }; // Initialize the block header. { // We assume all the header fields are densely packed. unsigned index = 0; CharUnits offset; - auto addHeaderField = - [&](llvm::Value *value, CharUnits size, const Twine &name) { - storeField(value, index, offset, name); - offset += size; - index++; - }; + auto addHeaderField = [&](llvm::Value *value, CharUnits size, + const Twine &name) { + storeField(value, index, name); + offset += size; + index++; + }; if (!IsOpenCL) { addHeaderField(isa, getPointerSize(), "block.isa"); @@ -1031,8 +1027,8 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { // First, 'this'. if (blockDecl->capturesCXXThis()) { - Address addr = projectField(blockInfo.CXXThisIndex, blockInfo.CXXThisOffset, - "block.captured-this.addr"); + Address addr = + projectField(blockInfo.CXXThisIndex, "block.captured-this.addr"); Builder.CreateStore(LoadCXXThis(), addr); } @@ -1048,8 +1044,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { // This will be a [[type]]*, except that a byref entry will just be // an i8**. - Address blockField = - projectField(capture.getIndex(), capture.getOffset(), "block.captured"); + Address blockField = projectField(capture.getIndex(), "block.captured"); // Compute the address of the thing we're going to move into the // block literal. @@ -1068,7 +1063,6 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) { // This is a [[type]]*, except that a byref entry will just be an i8**. src = Builder.CreateStructGEP(LoadBlockStruct(), enclosingCapture.getIndex(), - enclosingCapture.getOffset(), "block.capture.addr"); } else { auto I = LocalDeclMap.find(variable); @@ -1330,9 +1324,8 @@ Address CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable) { // Handle constant captures. if (capture.isConstant()) return LocalDeclMap.find(variable)->second; - Address addr = - Builder.CreateStructGEP(LoadBlockStruct(), capture.getIndex(), - capture.getOffset(), "block.capture.addr"); + Address addr = Builder.CreateStructGEP(LoadBlockStruct(), capture.getIndex(), + "block.capture.addr"); if (variable->isEscapingByref()) { // addr should be a void** right now. Load, then cast the result @@ -1615,9 +1608,8 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD, // If we have a C++ 'this' reference, go ahead and force it into // existence now. if (blockDecl->capturesCXXThis()) { - Address addr = - Builder.CreateStructGEP(LoadBlockStruct(), blockInfo.CXXThisIndex, - blockInfo.CXXThisOffset, "block.captured-this"); + Address addr = Builder.CreateStructGEP( + LoadBlockStruct(), blockInfo.CXXThisIndex, "block.captured-this"); CXXThisValue = Builder.CreateLoad(addr, "this"); } @@ -2060,8 +2052,8 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { BlockFieldFlags flags = CopiedCapture.CopyFlags; unsigned index = capture.getIndex(); - Address srcField = Builder.CreateStructGEP(src, index, capture.getOffset()); - Address dstField = Builder.CreateStructGEP(dst, index, capture.getOffset()); + Address srcField = Builder.CreateStructGEP(src, index); + Address dstField = Builder.CreateStructGEP(dst, index); switch (CopiedCapture.CopyKind) { case BlockCaptureEntityKind::CXXRecord: @@ -2249,8 +2241,7 @@ CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) { const CGBlockInfo::Capture &capture = *DestroyedCapture.Capture; BlockFieldFlags flags = DestroyedCapture.DisposeFlags; - Address srcField = - Builder.CreateStructGEP(src, capture.getIndex(), capture.getOffset()); + Address srcField = Builder.CreateStructGEP(src, capture.getIndex()); pushCaptureCleanup(DestroyedCapture.DisposeKind, srcField, CI.getVariable()->getType(), flags, @@ -2710,13 +2701,11 @@ Address CodeGenFunction::emitBlockByrefAddress(Address baseAddr, const llvm::Twine &name) { // Chase the forwarding address if requested. if (followForward) { - Address forwardingAddr = - Builder.CreateStructGEP(baseAddr, 1, getPointerSize(), "forwarding"); + Address forwardingAddr = Builder.CreateStructGEP(baseAddr, 1, "forwarding"); baseAddr = Address(Builder.CreateLoad(forwardingAddr), info.ByrefAlignment); } - return Builder.CreateStructGEP(baseAddr, info.FieldIndex, - info.FieldOffset, name); + return Builder.CreateStructGEP(baseAddr, info.FieldIndex, name); } /// BuildByrefInfo - This routine changes a __block variable declared as T x @@ -2834,8 +2823,7 @@ void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) { CharUnits nextHeaderOffset; auto storeHeaderField = [&](llvm::Value *value, CharUnits fieldSize, const Twine &name) { - auto fieldAddr = Builder.CreateStructGEP(addr, nextHeaderIndex, - nextHeaderOffset, name); + auto fieldAddr = Builder.CreateStructGEP(addr, nextHeaderIndex, name); Builder.CreateStore(value, fieldAddr); nextHeaderIndex++; -- cgit v1.2.3 From eae71f8d05ce550c4e2595c9b7082cc2c7882c58 Mon Sep 17 00:00:00 2001 From: Andrew Savonichev Date: Thu, 21 Feb 2019 11:02:10 +0000 Subject: [OpenCL] Simplify LLVM IR generated for OpenCL blocks Summary: Emit direct call of block invoke functions when possible, i.e. in case the block is not passed as a function argument. Also doing some refactoring of `CodeGenFunction::EmitBlockCallExpr()` Reviewers: Anastasia, yaxunl, svenvh Reviewed By: Anastasia Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58388 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@354568 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGBlocks.cpp | 77 +++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 40 deletions(-) (limited to 'lib/CodeGen/CGBlocks.cpp') diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 1d4ce27e92..f4f5f6f8f4 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -1253,52 +1253,49 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue) { const BlockPointerType *BPT = E->getCallee()->getType()->getAs(); - llvm::Value *BlockPtr = EmitScalarExpr(E->getCallee()); - - // Get a pointer to the generic block literal. - // For OpenCL we generate generic AS void ptr to be able to reuse the same - // block definition for blocks with captures generated as private AS local - // variables and without captures generated as global AS program scope - // variables. - unsigned AddrSpace = 0; - if (getLangOpts().OpenCL) - AddrSpace = getContext().getTargetAddressSpace(LangAS::opencl_generic); - - llvm::Type *BlockLiteralTy = - llvm::PointerType::get(CGM.getGenericBlockLiteralType(), AddrSpace); - - // Bitcast the callee to a block literal. - BlockPtr = - Builder.CreatePointerCast(BlockPtr, BlockLiteralTy, "block.literal"); - - // Get the function pointer from the literal. - llvm::Value *FuncPtr = - Builder.CreateStructGEP(CGM.getGenericBlockLiteralType(), BlockPtr, - CGM.getLangOpts().OpenCL ? 2 : 3); - - // Add the block literal. + llvm::Type *GenBlockTy = CGM.getGenericBlockLiteralType(); + llvm::Value *Func = nullptr; + QualType FnType = BPT->getPointeeType(); + ASTContext &Ctx = getContext(); CallArgList Args; - QualType VoidPtrQualTy = getContext().VoidPtrTy; - llvm::Type *GenericVoidPtrTy = VoidPtrTy; if (getLangOpts().OpenCL) { - GenericVoidPtrTy = CGM.getOpenCLRuntime().getGenericVoidPointerType(); - VoidPtrQualTy = - getContext().getPointerType(getContext().getAddrSpaceQualType( - getContext().VoidTy, LangAS::opencl_generic)); - } - - BlockPtr = Builder.CreatePointerCast(BlockPtr, GenericVoidPtrTy); - Args.add(RValue::get(BlockPtr), VoidPtrQualTy); - - QualType FnType = BPT->getPointeeType(); + // For OpenCL, BlockPtr is already casted to generic block literal. + + // First argument of a block call is a generic block literal casted to + // generic void pointer, i.e. i8 addrspace(4)* + llvm::Value *BlockDescriptor = Builder.CreatePointerCast( + BlockPtr, CGM.getOpenCLRuntime().getGenericVoidPointerType()); + QualType VoidPtrQualTy = Ctx.getPointerType( + Ctx.getAddrSpaceQualType(Ctx.VoidTy, LangAS::opencl_generic)); + Args.add(RValue::get(BlockDescriptor), VoidPtrQualTy); + // And the rest of the arguments. + EmitCallArgs(Args, FnType->getAs(), E->arguments()); + + // We *can* call the block directly unless it is a function argument. + if (!isa(E->getCalleeDecl())) + Func = CGM.getOpenCLRuntime().getInvokeFunction(E->getCallee()); + else { + llvm::Value *FuncPtr = Builder.CreateStructGEP(GenBlockTy, BlockPtr, 2); + Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign()); + } + } else { + // Bitcast the block literal to a generic block literal. + BlockPtr = Builder.CreatePointerCast( + BlockPtr, llvm::PointerType::get(GenBlockTy, 0), "block.literal"); + // Get pointer to the block invoke function + llvm::Value *FuncPtr = Builder.CreateStructGEP(GenBlockTy, BlockPtr, 3); - // And the rest of the arguments. - EmitCallArgs(Args, FnType->getAs(), E->arguments()); + // First argument is a block literal casted to a void pointer + BlockPtr = Builder.CreatePointerCast(BlockPtr, VoidPtrTy); + Args.add(RValue::get(BlockPtr), Ctx.VoidPtrTy); + // And the rest of the arguments. + EmitCallArgs(Args, FnType->getAs(), E->arguments()); - // Load the function. - llvm::Value *Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign()); + // Load the function. + Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign()); + } const FunctionType *FuncTy = FnType->castAs(); const CGFunctionInfo &FnInfo = -- cgit v1.2.3 From 8f37e96206e47808d516401da00e100a960f66aa Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Fri, 22 Feb 2019 16:29:50 +0000 Subject: CodeGen: use COMDAT for block copy/destroy helpers SVN r339438 added support to deduplicate the helpers by using a consistent naming scheme and using LinkOnceODR semantics. This works on ELF by means of weak linking semantics, and entirely does not work on PE/COFF where you end up with multiply defined strong symbols, which is a strong error on PE/COFF. Assign the functions a COMDAT group so that they can be uniqued by the linker. This fixes the use of blocks in CoreFoundation on Windows. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@354678 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGBlocks.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/CodeGen/CGBlocks.cpp') diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index f4f5f6f8f4..1c10c46baa 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -2016,6 +2016,8 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) { llvm::Function *Fn = llvm::Function::Create(LTy, llvm::GlobalValue::LinkOnceODRLinkage, FuncName, &CGM.getModule()); + if (CGM.supportsCOMDAT()) + Fn->setComdat(CGM.getModule().getOrInsertComdat(FuncName)); IdentifierInfo *II = &C.Idents.get(FuncName); @@ -2207,6 +2209,8 @@ CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) { llvm::Function *Fn = llvm::Function::Create(LTy, llvm::GlobalValue::LinkOnceODRLinkage, FuncName, &CGM.getModule()); + if (CGM.supportsCOMDAT()) + Fn->setComdat(CGM.getModule().getOrInsertComdat(FuncName)); IdentifierInfo *II = &C.Idents.get(FuncName); -- cgit v1.2.3 From 94c9e98ba7184779aba9b994724be2a7b7335909 Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Sun, 31 Mar 2019 11:22:26 +0000 Subject: COMDAT-fold block descriptors. Without this change, linking multiple objects containing block descriptors together on Windows will generate duplicate symbol errors. Patch by Dustin Howett! Differential Revision: https://reviews.llvm.org/D58807 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@357363 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGBlocks.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/CodeGen/CGBlocks.cpp') diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 1c10c46baa..731735841e 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -274,6 +274,8 @@ static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM, /*constant*/ true, linkage, AddrSpace); if (linkage == llvm::GlobalValue::LinkOnceODRLinkage) { + if (CGM.supportsCOMDAT()) + global->setComdat(CGM.getModule().getOrInsertComdat(descName)); global->setVisibility(llvm::GlobalValue::HiddenVisibility); global->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); } -- cgit v1.2.3 From 329eb5c6baeca0a1bd6b1a5bd55e41de786f39fa Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 24 Apr 2019 14:43:05 +0000 Subject: Use llvm::stable_sort git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@359098 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGBlocks.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/CodeGen/CGBlocks.cpp') diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 731735841e..2a317fc956 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -671,7 +671,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, // Sort the layout by alignment. We have to use a stable sort here // to get reproducible results. There should probably be an // llvm::array_pod_stable_sort. - std::stable_sort(layout.begin(), layout.end()); + llvm::stable_sort(layout); // Needed for blocks layout info. info.BlockHeaderForcedGapOffset = info.BlockSize; -- cgit v1.2.3