2015-10-07 07:40:43 +08:00
|
|
|
//===--- CGBlocks.cpp - Emit LLVM Code for declarations ---------*- C++ -*-===//
|
2009-02-12 08:39:25 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This contains code to emit blocks.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "CGBlocks.h"
|
2009-09-30 10:43:10 +08:00
|
|
|
#include "CGDebugInfo.h"
|
2010-02-11 07:34:57 +08:00
|
|
|
#include "CGObjCRuntime.h"
|
2017-10-05 04:32:17 +08:00
|
|
|
#include "CGOpenCLRuntime.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "CodeGenFunction.h"
|
2009-02-12 08:39:25 +08:00
|
|
|
#include "CodeGenModule.h"
|
2017-08-16 05:42:52 +08:00
|
|
|
#include "ConstantEmitter.h"
|
2017-10-05 04:32:17 +08:00
|
|
|
#include "TargetInfo.h"
|
2009-03-21 05:53:12 +08:00
|
|
|
#include "clang/AST/DeclObjC.h"
|
2017-10-05 04:32:17 +08:00
|
|
|
#include "clang/CodeGen/ConstantInitBuilder.h"
|
2010-03-31 23:04:05 +08:00
|
|
|
#include "llvm/ADT/SmallSet.h"
|
2014-03-04 19:02:08 +08:00
|
|
|
#include "llvm/IR/CallSite.h"
|
2013-01-02 19:45:17 +08:00
|
|
|
#include "llvm/IR/DataLayout.h"
|
|
|
|
#include "llvm/IR/Module.h"
|
2009-02-12 08:39:25 +08:00
|
|
|
#include <algorithm>
|
2012-11-15 01:43:08 +08:00
|
|
|
#include <cstdio>
|
2009-08-24 21:25:12 +08:00
|
|
|
|
2009-02-12 08:39:25 +08:00
|
|
|
using namespace clang;
|
|
|
|
using namespace CodeGen;
|
|
|
|
|
2011-11-10 16:15:53 +08:00
|
|
|
CGBlockInfo::CGBlockInfo(const BlockDecl *block, StringRef name)
|
|
|
|
: Name(name), CXXThisIndex(0), CanBeGlobal(false), NeedsCopyDispose(false),
|
2012-11-02 02:32:55 +08:00
|
|
|
HasCXXObject(false), UsesStret(false), HasCapturedVariableLayout(false),
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
LocalAddress(Address::invalid()), StructureType(nullptr), Block(block),
|
2014-05-21 13:09:00 +08:00
|
|
|
DominatingIP(nullptr) {
|
|
|
|
|
2011-11-10 16:15:53 +08:00
|
|
|
// Skip asm prefix, if any. 'name' is usually taken directly from
|
|
|
|
// the mangled name of the enclosing function.
|
|
|
|
if (!name.empty() && name[0] == '\01')
|
|
|
|
name = name.substr(1);
|
2010-05-21 12:11:14 +08:00
|
|
|
}
|
|
|
|
|
2011-03-31 16:03:29 +08:00
|
|
|
// Anchor the vtable to this translation unit.
|
2015-10-20 21:23:58 +08:00
|
|
|
BlockByrefHelpers::~BlockByrefHelpers() {}
|
2011-03-31 16:03:29 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
/// Build the given block as a global block.
|
|
|
|
static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,
|
|
|
|
const CGBlockInfo &blockInfo,
|
|
|
|
llvm::Constant *blockFn);
|
2010-05-21 12:11:14 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
/// Build the helper function to copy a block.
|
|
|
|
static llvm::Constant *buildCopyHelper(CodeGenModule &CGM,
|
|
|
|
const CGBlockInfo &blockInfo) {
|
|
|
|
return CodeGenFunction(CGM).GenerateCopyHelperFunction(blockInfo);
|
|
|
|
}
|
|
|
|
|
2013-12-06 00:25:25 +08:00
|
|
|
/// Build the helper function to dispose of a block.
|
2011-02-07 18:33:21 +08:00
|
|
|
static llvm::Constant *buildDisposeHelper(CodeGenModule &CGM,
|
|
|
|
const CGBlockInfo &blockInfo) {
|
|
|
|
return CodeGenFunction(CGM).GenerateDestroyHelperFunction(blockInfo);
|
|
|
|
}
|
|
|
|
|
2012-10-26 02:06:53 +08:00
|
|
|
/// buildBlockDescriptor - Build the block descriptor meta-data for a block.
|
|
|
|
/// buildBlockDescriptor is accessed from 5th field of the Block_literal
|
|
|
|
/// meta-data and contains stationary information about the block literal.
|
|
|
|
/// Its definition will have 4 (or optinally 6) words.
|
2013-05-09 07:09:44 +08:00
|
|
|
/// \code
|
2012-10-26 02:06:53 +08:00
|
|
|
/// struct Block_descriptor {
|
|
|
|
/// unsigned long reserved;
|
|
|
|
/// unsigned long size; // size of Block_literal metadata in bytes.
|
|
|
|
/// void *copy_func_helper_decl; // optional copy helper.
|
|
|
|
/// void *destroy_func_decl; // optioanl destructor helper.
|
2013-05-09 07:09:44 +08:00
|
|
|
/// void *block_method_encoding_address; // @encode for block literal signature.
|
2012-10-26 02:06:53 +08:00
|
|
|
/// void *block_layout_info; // encoding of captured block variables.
|
|
|
|
/// };
|
2013-05-09 07:09:44 +08:00
|
|
|
/// \endcode
|
2011-02-07 18:33:21 +08:00
|
|
|
static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM,
|
|
|
|
const CGBlockInfo &blockInfo) {
|
|
|
|
ASTContext &C = CGM.getContext();
|
|
|
|
|
2016-11-19 16:17:24 +08:00
|
|
|
llvm::IntegerType *ulong =
|
|
|
|
cast<llvm::IntegerType>(CGM.getTypes().ConvertType(C.UnsignedLongTy));
|
|
|
|
llvm::PointerType *i8p = nullptr;
|
2014-08-14 17:37:50 +08:00
|
|
|
if (CGM.getLangOpts().OpenCL)
|
|
|
|
i8p =
|
|
|
|
llvm::Type::getInt8PtrTy(
|
|
|
|
CGM.getLLVMContext(), C.getTargetAddressSpace(LangAS::opencl_constant));
|
|
|
|
else
|
2016-11-19 16:17:24 +08:00
|
|
|
i8p = CGM.VoidPtrTy;
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2016-11-29 06:18:27 +08:00
|
|
|
ConstantInitBuilder builder(CGM);
|
2016-11-19 16:17:24 +08:00
|
|
|
auto elements = builder.beginStruct();
|
2009-02-14 00:19:19 +08:00
|
|
|
|
|
|
|
// reserved
|
2016-11-19 16:17:24 +08:00
|
|
|
elements.addInt(ulong, 0);
|
2009-02-14 00:19:19 +08:00
|
|
|
|
|
|
|
// Size
|
2009-02-22 04:07:44 +08:00
|
|
|
// FIXME: What is the right way to say this doesn't fit? We should give
|
|
|
|
// a user diagnostic in that case. Better fix would be to change the
|
|
|
|
// API to size_t.
|
2016-11-19 16:17:24 +08:00
|
|
|
elements.addInt(ulong, blockInfo.BlockSize.getQuantity());
|
2009-02-14 00:19:19 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// Optional copy/dispose helpers.
|
|
|
|
if (blockInfo.NeedsCopyDispose) {
|
2009-02-14 00:19:19 +08:00
|
|
|
// copy_func_helper_decl
|
2016-11-19 16:17:24 +08:00
|
|
|
elements.add(buildCopyHelper(CGM, blockInfo));
|
2009-02-14 00:19:19 +08:00
|
|
|
|
|
|
|
// destroy_func_decl
|
2016-11-19 16:17:24 +08:00
|
|
|
elements.add(buildDisposeHelper(CGM, blockInfo));
|
2009-02-14 00:19:19 +08:00
|
|
|
}
|
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// Signature. Mandatory ObjC-style method descriptor @encode sequence.
|
|
|
|
std::string typeAtEncoding =
|
|
|
|
CGM.getContext().getObjCEncodingForBlock(blockInfo.getBlockExpr());
|
2016-11-19 16:17:24 +08:00
|
|
|
elements.add(llvm::ConstantExpr::getBitCast(
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
CGM.GetAddrOfConstantCString(typeAtEncoding).getPointer(), i8p));
|
2010-02-24 05:51:17 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// GC layout.
|
2012-10-28 05:10:38 +08:00
|
|
|
if (C.getLangOpts().ObjC1) {
|
|
|
|
if (CGM.getLangOpts().getGC() != LangOptions::NonGC)
|
2016-11-19 16:17:24 +08:00
|
|
|
elements.add(CGM.getObjCRuntime().BuildGCBlockLayout(CGM, blockInfo));
|
2012-10-28 05:10:38 +08:00
|
|
|
else
|
2016-11-19 16:17:24 +08:00
|
|
|
elements.add(CGM.getObjCRuntime().BuildRCBlockLayout(CGM, blockInfo));
|
2012-10-28 05:10:38 +08:00
|
|
|
}
|
2011-02-07 18:33:21 +08:00
|
|
|
else
|
2016-11-19 16:17:24 +08:00
|
|
|
elements.addNullPointer(i8p);
|
2009-03-01 09:09:12 +08:00
|
|
|
|
2016-08-10 23:57:02 +08:00
|
|
|
unsigned AddrSpace = 0;
|
|
|
|
if (C.getLangOpts().OpenCL)
|
|
|
|
AddrSpace = C.getTargetAddressSpace(LangAS::opencl_constant);
|
2016-11-19 16:17:24 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
llvm::GlobalVariable *global =
|
2016-11-19 16:17:24 +08:00
|
|
|
elements.finishAndCreateGlobal("__block_descriptor_tmp",
|
|
|
|
CGM.getPointerAlign(),
|
|
|
|
/*constant*/ true,
|
|
|
|
llvm::GlobalValue::InternalLinkage,
|
|
|
|
AddrSpace);
|
2009-10-21 11:49:08 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
return llvm::ConstantExpr::getBitCast(global, CGM.getBlockDescriptorType());
|
2009-03-01 09:09:12 +08:00
|
|
|
}
|
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
/*
|
|
|
|
Purely notional variadic template describing the layout of a block.
|
|
|
|
|
|
|
|
template <class _ResultType, class... _ParamTypes, class... _CaptureTypes>
|
|
|
|
struct Block_literal {
|
|
|
|
/// Initialized to one of:
|
|
|
|
/// extern void *_NSConcreteStackBlock[];
|
|
|
|
/// extern void *_NSConcreteGlobalBlock[];
|
|
|
|
///
|
|
|
|
/// In theory, we could start one off malloc'ed by setting
|
|
|
|
/// BLOCK_NEEDS_FREE, giving it a refcount of 1, and using
|
|
|
|
/// this isa:
|
|
|
|
/// extern void *_NSConcreteMallocBlock[];
|
|
|
|
struct objc_class *isa;
|
|
|
|
|
|
|
|
/// These are the flags (with corresponding bit number) that the
|
|
|
|
/// compiler is actually supposed to know about.
|
|
|
|
/// 25. BLOCK_HAS_COPY_DISPOSE - indicates that the block
|
|
|
|
/// descriptor provides copy and dispose helper functions
|
|
|
|
/// 26. BLOCK_HAS_CXX_OBJ - indicates that there's a captured
|
|
|
|
/// object with a nontrivial destructor or copy constructor
|
|
|
|
/// 28. BLOCK_IS_GLOBAL - indicates that the block is allocated
|
|
|
|
/// as global memory
|
|
|
|
/// 29. BLOCK_USE_STRET - indicates that the block function
|
|
|
|
/// uses stret, which objc_msgSend needs to know about
|
|
|
|
/// 30. BLOCK_HAS_SIGNATURE - indicates that the block has an
|
|
|
|
/// @encoded signature string
|
|
|
|
/// And we're not supposed to manipulate these:
|
|
|
|
/// 24. BLOCK_NEEDS_FREE - indicates that the block has been moved
|
|
|
|
/// to malloc'ed memory
|
|
|
|
/// 27. BLOCK_IS_GC - indicates that the block has been moved to
|
|
|
|
/// to GC-allocated memory
|
|
|
|
/// Additionally, the bottom 16 bits are a reference count which
|
|
|
|
/// should be zero on the stack.
|
|
|
|
int flags;
|
|
|
|
|
|
|
|
/// Reserved; should be zero-initialized.
|
|
|
|
int reserved;
|
|
|
|
|
|
|
|
/// Function pointer generated from block literal.
|
|
|
|
_ResultType (*invoke)(Block_literal *, _ParamTypes...);
|
|
|
|
|
|
|
|
/// Block description metadata generated from block literal.
|
|
|
|
struct Block_descriptor *block_descriptor;
|
|
|
|
|
|
|
|
/// Captured values follow.
|
|
|
|
_CapturesTypes captures...;
|
|
|
|
};
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
/// A chunk of data that we actually have to capture in the block.
|
|
|
|
struct BlockLayoutChunk {
|
|
|
|
CharUnits Alignment;
|
|
|
|
CharUnits Size;
|
2013-01-17 08:25:06 +08:00
|
|
|
Qualifiers::ObjCLifetime Lifetime;
|
2011-02-07 18:33:21 +08:00
|
|
|
const BlockDecl::Capture *Capture; // null for 'this'
|
2011-07-11 17:56:20 +08:00
|
|
|
llvm::Type *Type;
|
2016-09-16 08:02:06 +08:00
|
|
|
QualType FieldType;
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
BlockLayoutChunk(CharUnits align, CharUnits size,
|
2013-01-17 08:25:06 +08:00
|
|
|
Qualifiers::ObjCLifetime lifetime,
|
2011-02-07 18:33:21 +08:00
|
|
|
const BlockDecl::Capture *capture,
|
2016-09-16 08:02:06 +08:00
|
|
|
llvm::Type *type, QualType fieldType)
|
2013-01-17 08:25:06 +08:00
|
|
|
: Alignment(align), Size(size), Lifetime(lifetime),
|
2016-09-16 08:02:06 +08:00
|
|
|
Capture(capture), Type(type), FieldType(fieldType) {}
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
/// Tell the block info that this chunk has the given field index.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
void setIndex(CGBlockInfo &info, unsigned index, CharUnits offset) {
|
|
|
|
if (!Capture) {
|
2011-02-07 18:33:21 +08:00
|
|
|
info.CXXThisIndex = index;
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
info.CXXThisOffset = offset;
|
|
|
|
} else {
|
2016-09-16 08:02:06 +08:00
|
|
|
auto C = CGBlockInfo::Capture::makeIndex(index, offset, FieldType);
|
|
|
|
info.Captures.insert({Capture->getVariable(), C});
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
}
|
2011-02-07 18:33:21 +08:00
|
|
|
}
|
|
|
|
};
|
2009-03-01 09:09:12 +08:00
|
|
|
|
2013-01-17 08:25:06 +08:00
|
|
|
/// Order by 1) all __strong together 2) next, all byfref together 3) next,
|
|
|
|
/// all __weak together. Preserve descending alignment in all situations.
|
2011-02-07 18:33:21 +08:00
|
|
|
bool operator<(const BlockLayoutChunk &left, const BlockLayoutChunk &right) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
if (left.Alignment != right.Alignment)
|
|
|
|
return left.Alignment > right.Alignment;
|
|
|
|
|
|
|
|
auto getPrefOrder = [](const BlockLayoutChunk &chunk) {
|
2015-09-12 06:00:51 +08:00
|
|
|
if (chunk.Capture && chunk.Capture->isByRef())
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
return 1;
|
|
|
|
if (chunk.Lifetime == Qualifiers::OCL_Strong)
|
|
|
|
return 0;
|
|
|
|
if (chunk.Lifetime == Qualifiers::OCL_Weak)
|
|
|
|
return 2;
|
|
|
|
return 3;
|
|
|
|
};
|
|
|
|
|
|
|
|
return getPrefOrder(left) < getPrefOrder(right);
|
2011-02-07 18:33:21 +08:00
|
|
|
}
|
2015-10-07 07:40:43 +08:00
|
|
|
} // end anonymous namespace
|
2009-03-05 16:32:30 +08:00
|
|
|
|
2011-02-08 11:07:00 +08:00
|
|
|
/// Determines if the given type is safe for constant capture in C++.
|
|
|
|
static bool isSafeForCXXConstantCapture(QualType type) {
|
|
|
|
const RecordType *recordType =
|
|
|
|
type->getBaseElementTypeUnsafe()->getAs<RecordType>();
|
|
|
|
|
|
|
|
// Only records can be unsafe.
|
|
|
|
if (!recordType) return true;
|
|
|
|
|
2014-05-09 08:08:36 +08:00
|
|
|
const auto *record = cast<CXXRecordDecl>(recordType->getDecl());
|
2011-02-08 11:07:00 +08:00
|
|
|
|
|
|
|
// Maintain semantics for classes with non-trivial dtors or copy ctors.
|
|
|
|
if (!record->hasTrivialDestructor()) return false;
|
2012-11-16 08:53:38 +08:00
|
|
|
if (record->hasNonTrivialCopyConstructor()) return false;
|
2011-02-08 11:07:00 +08:00
|
|
|
|
|
|
|
// Otherwise, we just have to make sure there aren't any mutable
|
|
|
|
// fields that might have changed since initialization.
|
2011-05-13 09:05:07 +08:00
|
|
|
return !record->hasMutableFields();
|
2011-02-08 11:07:00 +08:00
|
|
|
}
|
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
/// It is illegal to modify a const object after initialization.
|
|
|
|
/// Therefore, if a const object has a constant initializer, we don't
|
|
|
|
/// actually need to keep storage for it in the block; we'll just
|
|
|
|
/// rematerialize it at the start of the block function. This is
|
|
|
|
/// acceptable because we make no promises about address stability of
|
|
|
|
/// captured variables.
|
|
|
|
static llvm::Constant *tryCaptureAsConstant(CodeGenModule &CGM,
|
2012-01-14 12:30:29 +08:00
|
|
|
CodeGenFunction *CGF,
|
2011-02-07 18:33:21 +08:00
|
|
|
const VarDecl *var) {
|
2017-03-30 22:13:19 +08:00
|
|
|
// Return if this is a function parameter. We shouldn't try to
|
2016-05-03 06:29:40 +08:00
|
|
|
// rematerialize default arguments of function parameters.
|
|
|
|
if (isa<ParmVarDecl>(var))
|
|
|
|
return nullptr;
|
2016-05-03 05:52:57 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
QualType type = var->getType();
|
|
|
|
|
|
|
|
// We can only do this if the variable is const.
|
2014-05-21 13:09:00 +08:00
|
|
|
if (!type.isConstQualified()) return nullptr;
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2011-02-08 11:07:00 +08:00
|
|
|
// Furthermore, in C++ we have to worry about mutable fields:
|
|
|
|
// C++ [dcl.type.cv]p4:
|
|
|
|
// Except that any class member declared mutable can be
|
|
|
|
// modified, any attempt to modify a const object during its
|
|
|
|
// lifetime results in undefined behavior.
|
2012-03-11 15:00:24 +08:00
|
|
|
if (CGM.getLangOpts().CPlusPlus && !isSafeForCXXConstantCapture(type))
|
2014-05-21 13:09:00 +08:00
|
|
|
return nullptr;
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
// If the variable doesn't have any initializer (shouldn't this be
|
|
|
|
// invalid?), it's not clear what we should do. Maybe capture as
|
|
|
|
// zero?
|
|
|
|
const Expr *init = var->getInit();
|
2014-05-21 13:09:00 +08:00
|
|
|
if (!init) return nullptr;
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2017-08-16 05:42:52 +08:00
|
|
|
return ConstantEmitter(CGM, CGF).tryEmitAbstractForInitializer(*var);
|
2011-02-07 18:33:21 +08:00
|
|
|
}
|
2009-11-18 03:33:30 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
/// Get the low bit of a nonzero character count. This is the
|
|
|
|
/// alignment of the nth byte if the 0th byte is universally aligned.
|
|
|
|
static CharUnits getLowBit(CharUnits v) {
|
|
|
|
return CharUnits::fromQuantity(v.getQuantity() & (~v.getQuantity() + 1));
|
|
|
|
}
|
2009-11-18 03:33:30 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
static void initializeForBlockHeader(CodeGenModule &CGM, CGBlockInfo &info,
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<llvm::Type*> &elementTypes) {
|
2009-02-26 07:33:13 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
assert(elementTypes.empty());
|
2017-10-05 04:32:17 +08:00
|
|
|
if (CGM.getLangOpts().OpenCL) {
|
2018-03-08 03:32:58 +08:00
|
|
|
// The header is basically 'struct { int; int;
|
2017-10-05 04:32:17 +08:00
|
|
|
// custom_fields; }'. Assert that struct is packed.
|
|
|
|
elementTypes.push_back(CGM.IntTy); /* total size */
|
|
|
|
elementTypes.push_back(CGM.IntTy); /* align */
|
2018-03-08 03:32:58 +08:00
|
|
|
unsigned Offset = 2 * CGM.getIntSize().getQuantity();
|
|
|
|
unsigned BlockAlign = CGM.getIntAlign().getQuantity();
|
2017-10-05 04:32:17 +08:00
|
|
|
if (auto *Helper =
|
|
|
|
CGM.getTargetCodeGenInfo().getTargetOpenCLBlockHelper()) {
|
|
|
|
for (auto I : Helper->getCustomFieldTypes()) /* custom fields */ {
|
|
|
|
// TargetOpenCLBlockHelp needs to make sure the struct is packed.
|
|
|
|
// If necessary, add padding fields to the custom fields.
|
|
|
|
unsigned Align = CGM.getDataLayout().getABITypeAlignment(I);
|
|
|
|
if (BlockAlign < Align)
|
|
|
|
BlockAlign = Align;
|
|
|
|
assert(Offset % Align == 0);
|
|
|
|
Offset += CGM.getDataLayout().getTypeAllocSize(I);
|
|
|
|
elementTypes.push_back(I);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
info.BlockAlign = CharUnits::fromQuantity(BlockAlign);
|
|
|
|
info.BlockSize = CharUnits::fromQuantity(Offset);
|
|
|
|
} else {
|
|
|
|
// The header is basically 'struct { void *; int; int; void *; void *; }'.
|
|
|
|
// Assert that that struct is packed.
|
|
|
|
assert(CGM.getIntSize() <= CGM.getPointerSize());
|
|
|
|
assert(CGM.getIntAlign() <= CGM.getPointerAlign());
|
|
|
|
assert((2 * CGM.getIntSize()).isMultipleOf(CGM.getPointerAlign()));
|
|
|
|
info.BlockAlign = CGM.getPointerAlign();
|
|
|
|
info.BlockSize = 3 * CGM.getPointerSize() + 2 * CGM.getIntSize();
|
|
|
|
elementTypes.push_back(CGM.VoidPtrTy);
|
|
|
|
elementTypes.push_back(CGM.IntTy);
|
|
|
|
elementTypes.push_back(CGM.IntTy);
|
|
|
|
elementTypes.push_back(CGM.VoidPtrTy);
|
|
|
|
elementTypes.push_back(CGM.getBlockDescriptorType());
|
|
|
|
}
|
2011-02-07 18:33:21 +08:00
|
|
|
}
|
2009-02-26 07:33:13 +08:00
|
|
|
|
2017-02-14 14:46:55 +08:00
|
|
|
static QualType getCaptureFieldType(const CodeGenFunction &CGF,
|
|
|
|
const BlockDecl::Capture &CI) {
|
|
|
|
const VarDecl *VD = CI.getVariable();
|
|
|
|
|
|
|
|
// If the variable is captured by an enclosing block or lambda expression,
|
|
|
|
// use the type of the capture field.
|
|
|
|
if (CGF.BlockInfo && CI.isNested())
|
|
|
|
return CGF.BlockInfo->getCapture(VD).fieldType();
|
|
|
|
if (auto *FD = CGF.LambdaCaptureFields.lookup(VD))
|
|
|
|
return FD->getType();
|
|
|
|
return VD->getType();
|
|
|
|
}
|
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
/// Compute the layout of the given block. Attempts to lay the block
|
|
|
|
/// out with minimal space requirements.
|
2012-01-14 12:30:29 +08:00
|
|
|
static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
|
|
|
|
CGBlockInfo &info) {
|
2011-02-07 18:33:21 +08:00
|
|
|
ASTContext &C = CGM.getContext();
|
|
|
|
const BlockDecl *block = info.getBlockDecl();
|
2009-03-07 10:35:30 +08:00
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<llvm::Type*, 8> elementTypes;
|
2011-02-07 18:33:21 +08:00
|
|
|
initializeForBlockHeader(CGM, info, elementTypes);
|
2017-10-05 04:32:17 +08:00
|
|
|
bool hasNonConstantCustomFields = false;
|
|
|
|
if (auto *OpenCLHelper =
|
|
|
|
CGM.getTargetCodeGenInfo().getTargetOpenCLBlockHelper())
|
|
|
|
hasNonConstantCustomFields =
|
|
|
|
!OpenCLHelper->areAllCustomFieldValuesConstant(info);
|
|
|
|
if (!block->hasCaptures() && !hasNonConstantCustomFields) {
|
2011-02-07 18:33:21 +08:00
|
|
|
info.StructureType =
|
|
|
|
llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true);
|
|
|
|
info.CanBeGlobal = true;
|
|
|
|
return;
|
|
|
|
}
|
2012-11-02 02:32:55 +08:00
|
|
|
else if (C.getLangOpts().ObjC1 &&
|
|
|
|
CGM.getLangOpts().getGC() == LangOptions::NonGC)
|
|
|
|
info.HasCapturedVariableLayout = true;
|
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// Collect the layout chunks.
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<BlockLayoutChunk, 16> layout;
|
2011-02-07 18:33:21 +08:00
|
|
|
layout.reserve(block->capturesCXXThis() +
|
|
|
|
(block->capture_end() - block->capture_begin()));
|
2010-05-20 09:18:31 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
CharUnits maxFieldAlign;
|
2010-05-20 09:18:31 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// First, 'this'.
|
|
|
|
if (block->capturesCXXThis()) {
|
2013-07-13 06:05:26 +08:00
|
|
|
assert(CGF && CGF->CurFuncDecl && isa<CXXMethodDecl>(CGF->CurFuncDecl) &&
|
|
|
|
"Can't capture 'this' outside a method");
|
|
|
|
QualType thisType = cast<CXXMethodDecl>(CGF->CurFuncDecl)->getThisType(C);
|
2010-05-20 09:18:31 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
// Theoretically, this could be in a different address space, so
|
|
|
|
// don't assume standard pointer size/align.
|
2011-07-11 17:56:20 +08:00
|
|
|
llvm::Type *llvmType = CGM.getTypes().ConvertType(thisType);
|
2011-02-07 18:33:21 +08:00
|
|
|
std::pair<CharUnits,CharUnits> tinfo
|
|
|
|
= CGM.getContext().getTypeInfoInChars(thisType);
|
|
|
|
maxFieldAlign = std::max(maxFieldAlign, tinfo.second);
|
2010-05-20 09:18:31 +08:00
|
|
|
|
2013-01-17 08:25:06 +08:00
|
|
|
layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first,
|
|
|
|
Qualifiers::OCL_None,
|
2016-09-16 08:02:06 +08:00
|
|
|
nullptr, llvmType, thisType));
|
2011-02-07 18:33:21 +08:00
|
|
|
}
|
2010-05-20 09:18:31 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// Next, all the block captures.
|
2014-03-15 02:34:04 +08:00
|
|
|
for (const auto &CI : block->captures()) {
|
|
|
|
const VarDecl *variable = CI.getVariable();
|
2010-05-20 09:18:31 +08:00
|
|
|
|
2014-03-15 02:34:04 +08:00
|
|
|
if (CI.isByRef()) {
|
2011-02-07 18:33:21 +08:00
|
|
|
// We have to copy/dispose of the __block reference.
|
|
|
|
info.NeedsCopyDispose = true;
|
|
|
|
|
|
|
|
// Just use void* instead of a pointer to the byref type.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
CharUnits align = CGM.getPointerAlign();
|
|
|
|
maxFieldAlign = std::max(maxFieldAlign, align);
|
2011-02-07 18:33:21 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
layout.push_back(BlockLayoutChunk(align, CGM.getPointerSize(),
|
|
|
|
Qualifiers::OCL_None, &CI,
|
2016-09-16 08:02:06 +08:00
|
|
|
CGM.VoidPtrTy, variable->getType()));
|
2011-02-07 18:33:21 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, build a layout chunk with the size and alignment of
|
|
|
|
// the declaration.
|
2012-01-14 12:30:29 +08:00
|
|
|
if (llvm::Constant *constant = tryCaptureAsConstant(CGM, CGF, variable)) {
|
2011-02-07 18:33:21 +08:00
|
|
|
info.Captures[variable] = CGBlockInfo::Capture::makeConstant(constant);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
// If we have a lifetime qualifier, honor it for capture purposes.
|
|
|
|
// That includes *not* copying it if it's __unsafe_unretained.
|
2013-01-17 08:25:06 +08:00
|
|
|
Qualifiers::ObjCLifetime lifetime =
|
|
|
|
variable->getType().getObjCLifetime();
|
|
|
|
if (lifetime) {
|
2011-06-16 07:02:42 +08:00
|
|
|
switch (lifetime) {
|
|
|
|
case Qualifiers::OCL_None: llvm_unreachable("impossible");
|
|
|
|
case Qualifiers::OCL_ExplicitNone:
|
|
|
|
case Qualifiers::OCL_Autoreleasing:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Qualifiers::OCL_Strong:
|
|
|
|
case Qualifiers::OCL_Weak:
|
|
|
|
info.NeedsCopyDispose = true;
|
|
|
|
}
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
// Block pointers require copy/dispose. So do Objective-C pointers.
|
|
|
|
} else if (variable->getType()->isObjCRetainableType()) {
|
2015-11-19 10:28:03 +08:00
|
|
|
// But honor the inert __unsafe_unretained qualifier, which doesn't
|
|
|
|
// actually make it into the type system.
|
|
|
|
if (variable->getType()->isObjCInertUnsafeUnretainedType()) {
|
|
|
|
lifetime = Qualifiers::OCL_ExplicitNone;
|
|
|
|
} else {
|
|
|
|
info.NeedsCopyDispose = true;
|
|
|
|
// used for mrr below.
|
|
|
|
lifetime = Qualifiers::OCL_Strong;
|
|
|
|
}
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
// So do types that require non-trivial copy construction.
|
2014-03-15 02:34:04 +08:00
|
|
|
} else if (CI.hasCopyExpr()) {
|
2011-02-07 18:33:21 +08:00
|
|
|
info.NeedsCopyDispose = true;
|
|
|
|
info.HasCXXObject = true;
|
|
|
|
|
2018-02-28 15:15:55 +08:00
|
|
|
// So do C structs that require non-trivial copy construction or
|
|
|
|
// destruction.
|
|
|
|
} else if (variable->getType().isNonTrivialToPrimitiveCopy() ==
|
|
|
|
QualType::PCK_Struct ||
|
|
|
|
variable->getType().isDestructedType() ==
|
|
|
|
QualType::DK_nontrivial_c_struct) {
|
|
|
|
info.NeedsCopyDispose = true;
|
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// And so do types with destructors.
|
2012-03-11 15:00:24 +08:00
|
|
|
} else if (CGM.getLangOpts().CPlusPlus) {
|
2011-02-07 18:33:21 +08:00
|
|
|
if (const CXXRecordDecl *record =
|
|
|
|
variable->getType()->getAsCXXRecordDecl()) {
|
|
|
|
if (!record->hasTrivialDestructor()) {
|
|
|
|
info.HasCXXObject = true;
|
|
|
|
info.NeedsCopyDispose = true;
|
2010-05-20 09:18:31 +08:00
|
|
|
}
|
2010-11-18 14:31:45 +08:00
|
|
|
}
|
2011-02-07 18:33:21 +08:00
|
|
|
}
|
|
|
|
|
2017-02-14 14:46:55 +08:00
|
|
|
QualType VT = getCaptureFieldType(*CGF, CI);
|
2011-11-01 07:44:33 +08:00
|
|
|
CharUnits size = C.getTypeSizeInChars(VT);
|
2011-11-03 06:53:43 +08:00
|
|
|
CharUnits align = C.getDeclAlign(variable);
|
2011-11-01 07:44:33 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
maxFieldAlign = std::max(maxFieldAlign, align);
|
|
|
|
|
2011-07-11 17:56:20 +08:00
|
|
|
llvm::Type *llvmType =
|
2011-11-01 07:44:33 +08:00
|
|
|
CGM.getTypes().ConvertTypeForMem(VT);
|
|
|
|
|
2016-09-16 08:02:06 +08:00
|
|
|
layout.push_back(
|
|
|
|
BlockLayoutChunk(align, size, lifetime, &CI, llvmType, VT));
|
2011-02-07 18:33:21 +08:00
|
|
|
}
|
2010-05-20 09:18:31 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// If that was everything, we're done here.
|
|
|
|
if (layout.empty()) {
|
|
|
|
info.StructureType =
|
|
|
|
llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true);
|
|
|
|
info.CanBeGlobal = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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());
|
2012-12-05 01:20:57 +08:00
|
|
|
|
|
|
|
// Needed for blocks layout info.
|
|
|
|
info.BlockHeaderForcedGapOffset = info.BlockSize;
|
|
|
|
info.BlockHeaderForcedGapSize = CharUnits::Zero();
|
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
CharUnits &blockSize = info.BlockSize;
|
|
|
|
info.BlockAlign = std::max(maxFieldAlign, info.BlockAlign);
|
|
|
|
|
|
|
|
// Assuming that the first byte in the header is maximally aligned,
|
|
|
|
// get the alignment of the first byte following the header.
|
|
|
|
CharUnits endAlign = getLowBit(blockSize);
|
|
|
|
|
|
|
|
// If the end of the header isn't satisfactorily aligned for the
|
|
|
|
// maximum thing, look for things that are okay with the header-end
|
|
|
|
// alignment, and keep appending them until we get something that's
|
|
|
|
// aligned right. This algorithm is only guaranteed optimal if
|
|
|
|
// that condition is satisfied at some point; otherwise we can get
|
|
|
|
// things like:
|
|
|
|
// header // next byte has alignment 4
|
|
|
|
// something_with_size_5; // next byte has alignment 1
|
|
|
|
// something_with_alignment_8;
|
|
|
|
// which has 7 bytes of padding, as opposed to the naive solution
|
|
|
|
// which might have less (?).
|
|
|
|
if (endAlign < maxFieldAlign) {
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<BlockLayoutChunk>::iterator
|
2011-02-07 18:33:21 +08:00
|
|
|
li = layout.begin() + 1, le = layout.end();
|
|
|
|
|
|
|
|
// Look for something that the header end is already
|
|
|
|
// satisfactorily aligned for.
|
|
|
|
for (; li != le && endAlign < li->Alignment; ++li)
|
|
|
|
;
|
|
|
|
|
|
|
|
// If we found something that's naturally aligned for the end of
|
|
|
|
// the header, keep adding things...
|
|
|
|
if (li != le) {
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<BlockLayoutChunk>::iterator first = li;
|
2011-02-07 18:33:21 +08:00
|
|
|
for (; li != le; ++li) {
|
|
|
|
assert(endAlign >= li->Alignment);
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
li->setIndex(info, elementTypes.size(), blockSize);
|
2011-02-07 18:33:21 +08:00
|
|
|
elementTypes.push_back(li->Type);
|
|
|
|
blockSize += li->Size;
|
|
|
|
endAlign = getLowBit(blockSize);
|
|
|
|
|
|
|
|
// ...until we get to the alignment of the maximum field.
|
2012-12-05 01:20:57 +08:00
|
|
|
if (endAlign >= maxFieldAlign) {
|
2011-02-07 18:33:21 +08:00
|
|
|
break;
|
2012-12-05 01:20:57 +08:00
|
|
|
}
|
2009-02-26 07:33:13 +08:00
|
|
|
}
|
2011-02-07 18:33:21 +08:00
|
|
|
// Don't re-append everything we just appended.
|
|
|
|
layout.erase(first, li);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-27 05:14:42 +08:00
|
|
|
assert(endAlign == getLowBit(blockSize));
|
2012-12-05 01:20:57 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// At this point, we just have to add padding if the end align still
|
|
|
|
// isn't aligned right.
|
|
|
|
if (endAlign < maxFieldAlign) {
|
2016-01-15 05:00:27 +08:00
|
|
|
CharUnits newBlockSize = blockSize.alignTo(maxFieldAlign);
|
2012-04-27 05:14:42 +08:00
|
|
|
CharUnits padding = newBlockSize - blockSize;
|
2011-02-07 18:33:21 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
// If we haven't yet added any fields, remember that there was an
|
|
|
|
// initial gap; this need to go into the block layout bit map.
|
|
|
|
if (blockSize == info.BlockHeaderForcedGapOffset) {
|
|
|
|
info.BlockHeaderForcedGapSize = padding;
|
|
|
|
}
|
|
|
|
|
2011-02-15 17:22:45 +08:00
|
|
|
elementTypes.push_back(llvm::ArrayType::get(CGM.Int8Ty,
|
|
|
|
padding.getQuantity()));
|
2012-04-27 05:14:42 +08:00
|
|
|
blockSize = newBlockSize;
|
2012-05-02 04:28:00 +08:00
|
|
|
endAlign = getLowBit(blockSize); // might be > maxFieldAlign
|
2011-02-07 18:33:21 +08:00
|
|
|
}
|
|
|
|
|
2012-05-02 04:28:00 +08:00
|
|
|
assert(endAlign >= maxFieldAlign);
|
2012-04-27 05:14:42 +08:00
|
|
|
assert(endAlign == getLowBit(blockSize));
|
2011-02-07 18:33:21 +08:00
|
|
|
// Slam everything else on now. This works because they have
|
|
|
|
// strictly decreasing alignment and we expect that size is always a
|
|
|
|
// multiple of alignment.
|
2011-07-23 18:55:15 +08:00
|
|
|
for (SmallVectorImpl<BlockLayoutChunk>::iterator
|
2011-02-07 18:33:21 +08:00
|
|
|
li = layout.begin(), le = layout.end(); li != le; ++li) {
|
2014-08-12 23:51:49 +08:00
|
|
|
if (endAlign < li->Alignment) {
|
|
|
|
// size may not be multiple of alignment. This can only happen with
|
|
|
|
// an over-aligned variable. We will be adding a padding field to
|
|
|
|
// make the size be multiple of alignment.
|
|
|
|
CharUnits padding = li->Alignment - endAlign;
|
|
|
|
elementTypes.push_back(llvm::ArrayType::get(CGM.Int8Ty,
|
|
|
|
padding.getQuantity()));
|
|
|
|
blockSize += padding;
|
|
|
|
endAlign = getLowBit(blockSize);
|
|
|
|
}
|
2011-02-07 18:33:21 +08:00
|
|
|
assert(endAlign >= li->Alignment);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
li->setIndex(info, elementTypes.size(), blockSize);
|
2011-02-07 18:33:21 +08:00
|
|
|
elementTypes.push_back(li->Type);
|
|
|
|
blockSize += li->Size;
|
|
|
|
endAlign = getLowBit(blockSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
info.StructureType =
|
|
|
|
llvm::StructType::get(CGM.getLLVMContext(), elementTypes, true);
|
|
|
|
}
|
|
|
|
|
2011-11-10 16:15:53 +08:00
|
|
|
/// Enter the scope of a block. This should be run at the entrance to
|
|
|
|
/// a full-expression so that the block's cleanups are pushed at the
|
|
|
|
/// right place in the stack.
|
|
|
|
static void enterBlockScope(CodeGenFunction &CGF, BlockDecl *block) {
|
2012-04-14 02:44:05 +08:00
|
|
|
assert(CGF.HaveInsertPoint());
|
|
|
|
|
2011-11-10 16:15:53 +08:00
|
|
|
// Allocate the block info and place it at the head of the list.
|
|
|
|
CGBlockInfo &blockInfo =
|
|
|
|
*new CGBlockInfo(block, CGF.CurFn->getName());
|
|
|
|
blockInfo.NextBlockInfo = CGF.FirstBlockInfo;
|
|
|
|
CGF.FirstBlockInfo = &blockInfo;
|
|
|
|
|
|
|
|
// Compute information about the layout, etc., of this block,
|
|
|
|
// pushing cleanups as necessary.
|
2012-01-14 12:30:29 +08:00
|
|
|
computeBlockInfo(CGF.CGM, &CGF, blockInfo);
|
2011-11-10 16:15:53 +08:00
|
|
|
|
|
|
|
// Nothing else to do if it can be global.
|
|
|
|
if (blockInfo.CanBeGlobal) return;
|
|
|
|
|
|
|
|
// Make the allocation for the block.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
blockInfo.LocalAddress = CGF.CreateTempAlloca(blockInfo.StructureType,
|
|
|
|
blockInfo.BlockAlign, "block");
|
2011-11-10 16:15:53 +08:00
|
|
|
|
|
|
|
// If there are cleanups to emit, enter them (but inactive).
|
|
|
|
if (!blockInfo.NeedsCopyDispose) return;
|
|
|
|
|
|
|
|
// Walk through the captures (in order) and find the ones not
|
|
|
|
// captured by constant.
|
2014-03-15 02:34:04 +08:00
|
|
|
for (const auto &CI : block->captures()) {
|
2011-11-10 16:15:53 +08:00
|
|
|
// Ignore __block captures; there's nothing special in the
|
|
|
|
// on-stack block that we need to do for them.
|
2014-03-15 02:34:04 +08:00
|
|
|
if (CI.isByRef()) continue;
|
2011-11-10 16:15:53 +08:00
|
|
|
|
|
|
|
// Ignore variables that are constant-captured.
|
2014-03-15 02:34:04 +08:00
|
|
|
const VarDecl *variable = CI.getVariable();
|
2011-11-10 16:15:53 +08:00
|
|
|
CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
|
|
|
|
if (capture.isConstant()) continue;
|
|
|
|
|
|
|
|
// Ignore objects that aren't destructed.
|
2017-02-14 14:46:55 +08:00
|
|
|
QualType VT = getCaptureFieldType(CGF, CI);
|
|
|
|
QualType::DestructionKind dtorKind = VT.isDestructedType();
|
2011-11-10 16:15:53 +08:00
|
|
|
if (dtorKind == QualType::DK_none) continue;
|
|
|
|
|
|
|
|
CodeGenFunction::Destroyer *destroyer;
|
|
|
|
|
|
|
|
// Block captures count as local values and have imprecise semantics.
|
|
|
|
// They also can't be arrays, so need to worry about that.
|
2017-04-29 02:50:57 +08:00
|
|
|
//
|
|
|
|
// For const-qualified captures, emit clang.arc.use to ensure the captured
|
|
|
|
// object doesn't get released while we are still depending on its validity
|
|
|
|
// within the block.
|
2017-05-06 02:39:06 +08:00
|
|
|
if (VT.isConstQualified() &&
|
|
|
|
VT.getObjCLifetime() == Qualifiers::OCL_Strong &&
|
|
|
|
CGF.CGM.getCodeGenOpts().OptimizationLevel != 0) {
|
|
|
|
assert(CGF.CGM.getLangOpts().ObjCAutoRefCount &&
|
|
|
|
"expected ObjC ARC to be enabled");
|
2017-04-29 02:50:57 +08:00
|
|
|
destroyer = CodeGenFunction::emitARCIntrinsicUse;
|
2017-05-06 02:39:06 +08:00
|
|
|
} else if (dtorKind == QualType::DK_objc_strong_lifetime) {
|
2012-01-26 11:33:36 +08:00
|
|
|
destroyer = CodeGenFunction::destroyARCStrongImprecise;
|
2011-11-10 16:15:53 +08:00
|
|
|
} else {
|
2012-01-26 11:33:36 +08:00
|
|
|
destroyer = CGF.getDestroyer(dtorKind);
|
2011-11-10 16:15:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// GEP down to the address.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Address addr = CGF.Builder.CreateStructGEP(blockInfo.LocalAddress,
|
|
|
|
capture.getIndex(),
|
|
|
|
capture.getOffset());
|
2011-11-10 16:15:53 +08:00
|
|
|
|
2011-11-10 18:43:54 +08:00
|
|
|
// We can use that GEP as the dominating IP.
|
|
|
|
if (!blockInfo.DominatingIP)
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
blockInfo.DominatingIP = cast<llvm::Instruction>(addr.getPointer());
|
2011-11-10 18:43:54 +08:00
|
|
|
|
2011-11-10 16:15:53 +08:00
|
|
|
CleanupKind cleanupKind = InactiveNormalCleanup;
|
|
|
|
bool useArrayEHCleanup = CGF.needsEHCleanup(dtorKind);
|
|
|
|
if (useArrayEHCleanup)
|
|
|
|
cleanupKind = InactiveNormalAndEHCleanup;
|
|
|
|
|
2017-02-14 14:46:55 +08:00
|
|
|
CGF.pushDestroy(cleanupKind, addr, VT,
|
2012-01-26 11:33:36 +08:00
|
|
|
destroyer, useArrayEHCleanup);
|
2011-11-10 16:15:53 +08:00
|
|
|
|
|
|
|
// Remember where that cleanup was.
|
|
|
|
capture.setCleanup(CGF.EHStack.stable_begin());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Enter a full-expression with a non-trivial number of objects to
|
|
|
|
/// clean up. This is in this file because, at the moment, the only
|
|
|
|
/// kind of cleanup object is a BlockDecl*.
|
|
|
|
void CodeGenFunction::enterNonTrivialFullExpression(const ExprWithCleanups *E) {
|
|
|
|
assert(E->getNumObjects() != 0);
|
2018-03-03 04:10:38 +08:00
|
|
|
for (const ExprWithCleanups::CleanupObject &C : E->getObjects())
|
|
|
|
enterBlockScope(*this, C);
|
2011-11-10 16:15:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Find the layout for the given block in a linked list and remove it.
|
|
|
|
static CGBlockInfo *findAndRemoveBlockInfo(CGBlockInfo **head,
|
|
|
|
const BlockDecl *block) {
|
|
|
|
while (true) {
|
|
|
|
assert(head && *head);
|
|
|
|
CGBlockInfo *cur = *head;
|
|
|
|
|
|
|
|
// If this is the block we're looking for, splice it out of the list.
|
|
|
|
if (cur->getBlockDecl() == block) {
|
|
|
|
*head = cur->NextBlockInfo;
|
|
|
|
return cur;
|
|
|
|
}
|
|
|
|
|
|
|
|
head = &cur->NextBlockInfo;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Destroy a chain of block layouts.
|
|
|
|
void CodeGenFunction::destroyBlockInfos(CGBlockInfo *head) {
|
|
|
|
assert(head && "destroying an empty chain");
|
|
|
|
do {
|
|
|
|
CGBlockInfo *cur = head;
|
|
|
|
head = cur->NextBlockInfo;
|
|
|
|
delete cur;
|
2014-05-21 13:09:00 +08:00
|
|
|
} while (head != nullptr);
|
2011-11-10 16:15:53 +08:00
|
|
|
}
|
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
/// Emit a block literal expression in the current function.
|
2018-02-16 00:39:19 +08:00
|
|
|
llvm::Value *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) {
|
2011-11-10 16:15:53 +08:00
|
|
|
// If the block has no captures, we won't have a pre-computed
|
|
|
|
// layout for it.
|
|
|
|
if (!blockExpr->getBlockDecl()->hasCaptures()) {
|
2017-10-14 20:23:50 +08:00
|
|
|
// The block literal is emitted as a global variable, and the block invoke
|
|
|
|
// function has to be extracted from its initializer.
|
|
|
|
if (llvm::Constant *Block = CGM.getAddrOfGlobalBlockIfEmitted(blockExpr)) {
|
2016-12-22 10:50:20 +08:00
|
|
|
return Block;
|
2017-10-14 20:23:50 +08:00
|
|
|
}
|
2011-11-10 16:15:53 +08:00
|
|
|
CGBlockInfo blockInfo(blockExpr->getBlockDecl(), CurFn->getName());
|
2012-01-14 12:30:29 +08:00
|
|
|
computeBlockInfo(CGM, this, blockInfo);
|
2011-11-10 16:15:53 +08:00
|
|
|
blockInfo.BlockExpression = blockExpr;
|
2018-02-16 00:39:19 +08:00
|
|
|
return EmitBlockLiteral(blockInfo);
|
2011-11-10 16:15:53 +08:00
|
|
|
}
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2011-11-10 16:15:53 +08:00
|
|
|
// Find the block info for this block and take ownership of it.
|
2014-03-08 04:03:18 +08:00
|
|
|
std::unique_ptr<CGBlockInfo> blockInfo;
|
2011-11-10 16:15:53 +08:00
|
|
|
blockInfo.reset(findAndRemoveBlockInfo(&FirstBlockInfo,
|
|
|
|
blockExpr->getBlockDecl()));
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2011-11-10 16:15:53 +08:00
|
|
|
blockInfo->BlockExpression = blockExpr;
|
2018-02-16 00:39:19 +08:00
|
|
|
return EmitBlockLiteral(*blockInfo);
|
2011-11-10 16:15:53 +08:00
|
|
|
}
|
|
|
|
|
2018-02-16 00:39:19 +08:00
|
|
|
llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
|
2017-10-05 04:32:17 +08:00
|
|
|
bool IsOpenCL = CGM.getContext().getLangOpts().OpenCL;
|
2011-11-10 16:15:53 +08:00
|
|
|
// Using the computed layout, generate the actual block function.
|
2012-03-01 12:01:32 +08:00
|
|
|
bool isLambdaConv = blockInfo.getBlockDecl()->isConversionFromLambda();
|
2017-12-08 10:47:58 +08:00
|
|
|
CodeGenFunction BlockCGF{CGM, true};
|
|
|
|
BlockCGF.SanOpts = SanOpts;
|
|
|
|
auto *InvokeFn = BlockCGF.GenerateBlockFunction(
|
2017-10-05 04:32:17 +08:00
|
|
|
CurGD, blockInfo, LocalDeclMap, isLambdaConv, blockInfo.CanBeGlobal);
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
// If there is nothing to capture, we can emit this as a global block.
|
|
|
|
if (blockInfo.CanBeGlobal)
|
2017-09-23 05:32:06 +08:00
|
|
|
return CGM.getAddrOfGlobalBlockIfEmitted(blockInfo.BlockExpression);
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
// Otherwise, we have to emit this as a local block.
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Address blockAddr = blockInfo.LocalAddress;
|
|
|
|
assert(blockAddr.isValid() && "block has no address!");
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2017-10-05 04:32:17 +08:00
|
|
|
llvm::Constant *isa;
|
|
|
|
llvm::Constant *descriptor;
|
|
|
|
BlockFlags flags;
|
|
|
|
if (!IsOpenCL) {
|
|
|
|
isa = llvm::ConstantExpr::getBitCast(CGM.getNSConcreteStackBlock(),
|
|
|
|
VoidPtrTy);
|
|
|
|
|
|
|
|
// Build the block descriptor.
|
|
|
|
descriptor = buildBlockDescriptor(CGM, blockInfo);
|
|
|
|
|
|
|
|
// Compute the initial on-stack block flags.
|
|
|
|
flags = BLOCK_HAS_SIGNATURE;
|
|
|
|
if (blockInfo.HasCapturedVariableLayout)
|
|
|
|
flags |= BLOCK_HAS_EXTENDED_LAYOUT;
|
|
|
|
if (blockInfo.NeedsCopyDispose)
|
|
|
|
flags |= BLOCK_HAS_COPY_DISPOSE;
|
|
|
|
if (blockInfo.HasCXXObject)
|
|
|
|
flags |= BLOCK_HAS_CXX_OBJ;
|
|
|
|
if (blockInfo.UsesStret)
|
|
|
|
flags |= BLOCK_USE_STRET;
|
|
|
|
}
|
2011-02-07 18:33:21 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
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));
|
|
|
|
};
|
|
|
|
|
|
|
|
// 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++;
|
|
|
|
};
|
|
|
|
|
2017-10-05 04:32:17 +08:00
|
|
|
if (!IsOpenCL) {
|
|
|
|
addHeaderField(isa, getPointerSize(), "block.isa");
|
|
|
|
addHeaderField(llvm::ConstantInt::get(IntTy, flags.getBitMask()),
|
|
|
|
getIntSize(), "block.flags");
|
|
|
|
addHeaderField(llvm::ConstantInt::get(IntTy, 0), getIntSize(),
|
|
|
|
"block.reserved");
|
|
|
|
} else {
|
|
|
|
addHeaderField(
|
|
|
|
llvm::ConstantInt::get(IntTy, blockInfo.BlockSize.getQuantity()),
|
|
|
|
getIntSize(), "block.size");
|
|
|
|
addHeaderField(
|
|
|
|
llvm::ConstantInt::get(IntTy, blockInfo.BlockAlign.getQuantity()),
|
|
|
|
getIntSize(), "block.align");
|
|
|
|
}
|
2018-03-08 03:32:58 +08:00
|
|
|
if (!IsOpenCL) {
|
|
|
|
addHeaderField(llvm::ConstantExpr::getBitCast(InvokeFn, VoidPtrTy),
|
|
|
|
getPointerSize(), "block.invoke");
|
2017-10-05 04:32:17 +08:00
|
|
|
addHeaderField(descriptor, getPointerSize(), "block.descriptor");
|
2018-03-08 03:32:58 +08:00
|
|
|
} else if (auto *Helper =
|
|
|
|
CGM.getTargetCodeGenInfo().getTargetOpenCLBlockHelper()) {
|
2017-10-05 04:32:17 +08:00
|
|
|
for (auto I : Helper->getCustomFieldValues(*this, blockInfo)) {
|
|
|
|
addHeaderField(
|
|
|
|
I.first,
|
|
|
|
CharUnits::fromQuantity(
|
|
|
|
CGM.getDataLayout().getTypeAllocSize(I.first->getType())),
|
|
|
|
I.second);
|
|
|
|
}
|
|
|
|
}
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
}
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
// Finally, capture all the values into the block.
|
|
|
|
const BlockDecl *blockDecl = blockInfo.getBlockDecl();
|
|
|
|
|
|
|
|
// First, 'this'.
|
|
|
|
if (blockDecl->capturesCXXThis()) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Address addr = projectField(blockInfo.CXXThisIndex, blockInfo.CXXThisOffset,
|
|
|
|
"block.captured-this.addr");
|
2011-02-07 18:33:21 +08:00
|
|
|
Builder.CreateStore(LoadCXXThis(), addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Next, captured variables.
|
2014-03-15 02:34:04 +08:00
|
|
|
for (const auto &CI : blockDecl->captures()) {
|
|
|
|
const VarDecl *variable = CI.getVariable();
|
2011-02-07 18:33:21 +08:00
|
|
|
const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
|
|
|
|
|
|
|
|
// Ignore constant captures.
|
|
|
|
if (capture.isConstant()) continue;
|
|
|
|
|
2016-09-16 08:02:06 +08:00
|
|
|
QualType type = capture.fieldType();
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
// This will be a [[type]]*, except that a byref entry will just be
|
|
|
|
// an i8**.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Address blockField =
|
|
|
|
projectField(capture.getIndex(), capture.getOffset(), "block.captured");
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
// Compute the address of the thing we're going to move into the
|
|
|
|
// block literal.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Address src = Address::invalid();
|
2016-05-05 02:40:33 +08:00
|
|
|
|
|
|
|
if (blockDecl->isConversionFromLambda()) {
|
2012-02-25 10:48:22 +08:00
|
|
|
// The lambda capture in a lambda's conversion-to-block-pointer is
|
2012-03-01 12:01:32 +08:00
|
|
|
// special; we'll simply emit it directly.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
src = Address::invalid();
|
2016-05-05 02:40:33 +08:00
|
|
|
} else if (CI.isByRef()) {
|
|
|
|
if (BlockInfo && CI.isNested()) {
|
|
|
|
// We need to use the capture from the enclosing block.
|
|
|
|
const CGBlockInfo::Capture &enclosingCapture =
|
|
|
|
BlockInfo->getCapture(variable);
|
|
|
|
|
|
|
|
// This is a [[type]]*, except that a byref entry wil just be an i8**.
|
|
|
|
src = Builder.CreateStructGEP(LoadBlockStruct(),
|
|
|
|
enclosingCapture.getIndex(),
|
|
|
|
enclosingCapture.getOffset(),
|
|
|
|
"block.capture.addr");
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
} else {
|
2016-05-05 02:40:33 +08:00
|
|
|
auto I = LocalDeclMap.find(variable);
|
|
|
|
assert(I != LocalDeclMap.end());
|
|
|
|
src = I->second;
|
2013-03-04 14:32:36 +08:00
|
|
|
}
|
2016-05-05 02:40:33 +08:00
|
|
|
} else {
|
|
|
|
DeclRefExpr declRef(const_cast<VarDecl *>(variable),
|
|
|
|
/*RefersToEnclosingVariableOrCapture*/ CI.isNested(),
|
|
|
|
type.getNonReferenceType(), VK_LValue,
|
|
|
|
SourceLocation());
|
|
|
|
src = EmitDeclRefLValue(&declRef).getAddress();
|
|
|
|
};
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
// For byrefs, we just write the pointer to the byref struct into
|
|
|
|
// the block field. There's no need to chase the forwarding
|
|
|
|
// pointer at this point, since we're building something that will
|
|
|
|
// live a shorter life than the stack byref anyway.
|
2014-03-15 02:34:04 +08:00
|
|
|
if (CI.isByRef()) {
|
2011-02-15 17:22:45 +08:00
|
|
|
// Get a void* that points to the byref struct.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
llvm::Value *byrefPointer;
|
2014-03-15 02:34:04 +08:00
|
|
|
if (CI.isNested())
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
byrefPointer = Builder.CreateLoad(src, "byref.capture");
|
2010-05-20 09:18:31 +08:00
|
|
|
else
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
byrefPointer = Builder.CreateBitCast(src.getPointer(), VoidPtrTy);
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2011-02-15 17:22:45 +08:00
|
|
|
// Write that void* into the capture field.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Builder.CreateStore(byrefPointer, blockField);
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
// If we have a copy constructor, evaluate that into the block field.
|
2014-03-15 02:34:04 +08:00
|
|
|
} else if (const Expr *copyExpr = CI.getCopyExpr()) {
|
2012-03-01 12:01:32 +08:00
|
|
|
if (blockDecl->isConversionFromLambda()) {
|
|
|
|
// If we have a lambda conversion, emit the expression
|
|
|
|
// directly into the block instead.
|
|
|
|
AggValueSlot Slot =
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
AggValueSlot::forAddr(blockField, Qualifiers(),
|
2012-03-01 12:01:32 +08:00
|
|
|
AggValueSlot::IsDestructed,
|
|
|
|
AggValueSlot::DoesNotNeedGCBarriers,
|
2012-03-30 01:37:10 +08:00
|
|
|
AggValueSlot::IsNotAliased);
|
2012-03-01 12:01:32 +08:00
|
|
|
EmitAggExpr(copyExpr, Slot);
|
|
|
|
} else {
|
|
|
|
EmitSynthesizedCXXCopyCtor(blockField, src, copyExpr);
|
|
|
|
}
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
// If it's a reference variable, copy the reference into the block field.
|
2011-11-03 06:53:43 +08:00
|
|
|
} else if (type->isReferenceType()) {
|
2016-05-05 02:40:33 +08:00
|
|
|
Builder.CreateStore(src.getPointer(), blockField);
|
2013-04-09 07:27:49 +08:00
|
|
|
|
2017-04-29 02:50:57 +08:00
|
|
|
// If type is const-qualified, copy the value into the block field.
|
|
|
|
} else if (type.isConstQualified() &&
|
2017-05-09 09:20:05 +08:00
|
|
|
type.getObjCLifetime() == Qualifiers::OCL_Strong &&
|
|
|
|
CGM.getCodeGenOpts().OptimizationLevel != 0) {
|
2017-04-29 02:50:57 +08:00
|
|
|
llvm::Value *value = Builder.CreateLoad(src, "captured");
|
|
|
|
Builder.CreateStore(value, blockField);
|
|
|
|
|
2013-04-09 07:27:49 +08:00
|
|
|
// If this is an ARC __strong block-pointer variable, don't do a
|
|
|
|
// block copy.
|
|
|
|
//
|
|
|
|
// TODO: this can be generalized into the normal initialization logic:
|
|
|
|
// we should never need to do a block-copy when initializing a local
|
|
|
|
// variable, because the local variable's lifetime should be strictly
|
|
|
|
// contained within the stack block's.
|
|
|
|
} else if (type.getObjCLifetime() == Qualifiers::OCL_Strong &&
|
|
|
|
type->isBlockPointerType()) {
|
|
|
|
// Load the block and do a simple retain.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
llvm::Value *value = Builder.CreateLoad(src, "block.captured_block");
|
2013-04-09 07:27:49 +08:00
|
|
|
value = EmitARCRetainNonBlock(value);
|
|
|
|
|
|
|
|
// Do a primitive store to the block field.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Builder.CreateStore(value, blockField);
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
// Otherwise, fake up a POD copy into the block field.
|
|
|
|
} else {
|
2011-06-16 07:02:42 +08:00
|
|
|
// Fake up a new variable so that EmitScalarInit doesn't think
|
|
|
|
// we're referring to the variable in its own initializer.
|
2017-06-09 21:40:18 +08:00
|
|
|
ImplicitParamDecl BlockFieldPseudoVar(getContext(), type,
|
|
|
|
ImplicitParamDecl::Other);
|
2011-06-16 07:02:42 +08:00
|
|
|
|
2011-02-08 02:37:40 +08:00
|
|
|
// We use one of these or the other depending on whether the
|
|
|
|
// reference is nested.
|
2015-01-12 18:17:46 +08:00
|
|
|
DeclRefExpr declRef(const_cast<VarDecl *>(variable),
|
|
|
|
/*RefersToEnclosingVariableOrCapture*/ CI.isNested(),
|
|
|
|
type, VK_LValue, SourceLocation());
|
2011-02-08 02:37:40 +08:00
|
|
|
|
2011-11-03 06:53:43 +08:00
|
|
|
ImplicitCastExpr l2r(ImplicitCastExpr::OnStack, type, CK_LValueToRValue,
|
2012-03-10 17:33:50 +08:00
|
|
|
&declRef, VK_RValue);
|
2014-12-10 06:04:13 +08:00
|
|
|
// FIXME: Pass a specific location for the expr init so that the store is
|
|
|
|
// attributed to a reasonable location - otherwise it may be attributed to
|
|
|
|
// locations of subexpressions in the initialization.
|
2017-06-09 21:40:18 +08:00
|
|
|
EmitExprAsInit(&l2r, &BlockFieldPseudoVar,
|
2017-10-10 17:39:32 +08:00
|
|
|
MakeAddrLValue(blockField, type, AlignmentSource::Decl),
|
2015-01-14 15:38:27 +08:00
|
|
|
/*captured by init*/ false);
|
2010-05-20 09:18:31 +08:00
|
|
|
}
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2011-11-10 16:15:53 +08:00
|
|
|
// Activate the cleanup if layout pushed one.
|
2014-03-15 02:34:04 +08:00
|
|
|
if (!CI.isByRef()) {
|
2011-11-10 16:15:53 +08:00
|
|
|
EHScopeStack::stable_iterator cleanup = capture.getCleanup();
|
|
|
|
if (cleanup.isValid())
|
2011-11-10 18:43:54 +08:00
|
|
|
ActivateCleanupBlock(cleanup, blockInfo.DominatingIP);
|
2011-06-16 07:02:42 +08:00
|
|
|
}
|
2009-02-14 00:19:19 +08:00
|
|
|
}
|
2009-03-05 16:32:30 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// Cast to the converted block-pointer type, which happens (somewhat
|
|
|
|
// unfortunately) to be a pointer to function type.
|
2017-01-27 23:11:34 +08:00
|
|
|
llvm::Value *result = Builder.CreatePointerCast(
|
|
|
|
blockAddr.getPointer(), ConvertType(blockInfo.getBlockExpr()->getType()));
|
2011-01-05 20:14:39 +08:00
|
|
|
|
2018-02-16 00:39:19 +08:00
|
|
|
if (IsOpenCL) {
|
|
|
|
CGM.getOpenCLRuntime().recordBlockInfo(blockInfo.BlockExpression, InvokeFn,
|
|
|
|
result);
|
|
|
|
}
|
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
return result;
|
2009-02-14 00:19:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-07-10 01:41:47 +08:00
|
|
|
llvm::Type *CodeGenModule::getBlockDescriptorType() {
|
2009-02-13 23:16:56 +08:00
|
|
|
if (BlockDescriptorType)
|
|
|
|
return BlockDescriptorType;
|
|
|
|
|
2011-07-10 01:41:47 +08:00
|
|
|
llvm::Type *UnsignedLongTy =
|
2009-02-13 23:16:56 +08:00
|
|
|
getTypes().ConvertType(getContext().UnsignedLongTy);
|
2009-02-13 23:32:32 +08:00
|
|
|
|
2009-02-13 23:16:56 +08:00
|
|
|
// struct __block_descriptor {
|
|
|
|
// unsigned long reserved;
|
|
|
|
// unsigned long block_size;
|
2010-02-24 05:51:17 +08:00
|
|
|
//
|
|
|
|
// // later, the following will be added
|
|
|
|
//
|
|
|
|
// struct {
|
|
|
|
// void (*copyHelper)();
|
|
|
|
// void (*copyHelper)();
|
|
|
|
// } helpers; // !!! optional
|
|
|
|
//
|
|
|
|
// const char *signature; // the block signature
|
|
|
|
// const char *layout; // reserved
|
2009-02-13 23:16:56 +08:00
|
|
|
// };
|
2017-05-10 03:31:30 +08:00
|
|
|
BlockDescriptorType = llvm::StructType::create(
|
|
|
|
"struct.__block_descriptor", UnsignedLongTy, UnsignedLongTy);
|
2009-02-13 23:16:56 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// Now form a pointer to that.
|
2016-08-10 23:57:02 +08:00
|
|
|
unsigned AddrSpace = 0;
|
|
|
|
if (getLangOpts().OpenCL)
|
|
|
|
AddrSpace = getContext().getTargetAddressSpace(LangAS::opencl_constant);
|
|
|
|
BlockDescriptorType = llvm::PointerType::get(BlockDescriptorType, AddrSpace);
|
2009-02-13 23:16:56 +08:00
|
|
|
return BlockDescriptorType;
|
2009-02-12 08:39:25 +08:00
|
|
|
}
|
|
|
|
|
2011-07-10 01:41:47 +08:00
|
|
|
llvm::Type *CodeGenModule::getGenericBlockLiteralType() {
|
2018-03-08 03:32:58 +08:00
|
|
|
assert(!getLangOpts().OpenCL && "OpenCL does not need this");
|
|
|
|
|
2009-02-13 23:25:34 +08:00
|
|
|
if (GenericBlockLiteralType)
|
|
|
|
return GenericBlockLiteralType;
|
|
|
|
|
2011-07-10 01:41:47 +08:00
|
|
|
llvm::Type *BlockDescPtrTy = getBlockDescriptorType();
|
2009-02-13 23:32:32 +08:00
|
|
|
|
2018-03-08 03:32:58 +08:00
|
|
|
// struct __block_literal_generic {
|
|
|
|
// void *__isa;
|
|
|
|
// int __flags;
|
|
|
|
// int __reserved;
|
|
|
|
// void (*__invoke)(void *);
|
|
|
|
// struct __block_descriptor *__descriptor;
|
|
|
|
// };
|
|
|
|
GenericBlockLiteralType =
|
|
|
|
llvm::StructType::create("struct.__block_literal_generic", VoidPtrTy,
|
|
|
|
IntTy, IntTy, VoidPtrTy, BlockDescPtrTy);
|
2009-02-13 23:32:32 +08:00
|
|
|
|
2009-02-13 23:25:34 +08:00
|
|
|
return GenericBlockLiteralType;
|
2009-02-12 08:39:25 +08:00
|
|
|
}
|
|
|
|
|
2017-10-05 04:32:17 +08:00
|
|
|
RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
|
2009-12-25 05:13:40 +08:00
|
|
|
ReturnValueSlot ReturnValue) {
|
2009-02-13 23:32:32 +08:00
|
|
|
const BlockPointerType *BPT =
|
2009-07-30 05:53:49 +08:00
|
|
|
E->getCallee()->getType()->getAs<BlockPointerType>();
|
2009-02-13 23:32:32 +08:00
|
|
|
|
2016-10-27 07:46:34 +08:00
|
|
|
llvm::Value *BlockPtr = EmitScalarExpr(E->getCallee());
|
2018-03-08 03:32:58 +08:00
|
|
|
llvm::Value *FuncPtr;
|
2009-02-12 08:39:25 +08:00
|
|
|
|
2018-03-08 03:32:58 +08:00
|
|
|
if (!CGM.getLangOpts().OpenCL) {
|
|
|
|
// Get a pointer to the generic block literal.
|
|
|
|
llvm::Type *BlockLiteralTy =
|
|
|
|
llvm::PointerType::get(CGM.getGenericBlockLiteralType(), 0);
|
2017-01-27 23:11:34 +08:00
|
|
|
|
2018-03-08 03:32:58 +08:00
|
|
|
// Bitcast the callee to a block literal.
|
|
|
|
BlockPtr =
|
|
|
|
Builder.CreatePointerCast(BlockPtr, BlockLiteralTy, "block.literal");
|
2009-02-12 08:39:25 +08:00
|
|
|
|
2018-03-08 03:32:58 +08:00
|
|
|
// Get the function pointer from the literal.
|
|
|
|
FuncPtr =
|
|
|
|
Builder.CreateStructGEP(CGM.getGenericBlockLiteralType(), BlockPtr, 3);
|
|
|
|
}
|
2009-02-13 23:32:32 +08:00
|
|
|
|
2009-02-12 08:39:25 +08:00
|
|
|
// Add the block literal.
|
|
|
|
CallArgList Args;
|
2017-01-27 23:11:34 +08:00
|
|
|
|
|
|
|
QualType VoidPtrQualTy = getContext().VoidPtrTy;
|
|
|
|
llvm::Type *GenericVoidPtrTy = VoidPtrTy;
|
|
|
|
if (getLangOpts().OpenCL) {
|
2017-10-05 04:32:17 +08:00
|
|
|
GenericVoidPtrTy = CGM.getOpenCLRuntime().getGenericVoidPointerType();
|
2017-01-27 23:11:34 +08:00
|
|
|
VoidPtrQualTy =
|
|
|
|
getContext().getPointerType(getContext().getAddrSpaceQualType(
|
|
|
|
getContext().VoidTy, LangAS::opencl_generic));
|
|
|
|
}
|
|
|
|
|
|
|
|
BlockPtr = Builder.CreatePointerCast(BlockPtr, GenericVoidPtrTy);
|
|
|
|
Args.add(RValue::get(BlockPtr), VoidPtrQualTy);
|
2009-02-13 23:32:32 +08:00
|
|
|
|
2009-04-09 07:13:16 +08:00
|
|
|
QualType FnType = BPT->getPointeeType();
|
|
|
|
|
2009-02-12 08:39:25 +08:00
|
|
|
// And the rest of the arguments.
|
2015-07-22 02:37:18 +08:00
|
|
|
EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), E->arguments());
|
2009-02-13 23:32:32 +08:00
|
|
|
|
2009-04-08 06:10:22 +08:00
|
|
|
// Load the function.
|
2018-03-08 03:32:58 +08:00
|
|
|
llvm::Value *Func;
|
|
|
|
if (CGM.getLangOpts().OpenCL)
|
|
|
|
Func = CGM.getOpenCLRuntime().getInvokeFunction(E->getCallee());
|
|
|
|
else
|
|
|
|
Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign());
|
2009-04-08 06:10:22 +08:00
|
|
|
|
2011-03-09 16:39:33 +08:00
|
|
|
const FunctionType *FuncTy = FnType->castAs<FunctionType>();
|
2012-02-17 11:33:10 +08:00
|
|
|
const CGFunctionInfo &FnInfo =
|
Fix the required args count for variadic blocks.
We were emitting calls to blocks as if all arguments were
required --- i.e. with signature (A,B,C,D,...) rather than
(A,B,...). This patch fixes that and accounts for the
implicit block-context argument as a required argument.
In addition, this patch changes the function type under which
we call unprototyped functions on platforms like x86-64 that
guarantee compatibility of variadic functions with unprototyped
function types; previously we would always call such functions
under the LLVM type T (...)*, but now we will call them under
the type T (A,B,C,D,...)*. This last change should have no
material effect except for making the type conventions more
explicit; it was a side-effect of the most convenient implementation.
llvm-svn: 169588
2012-12-07 15:03:17 +08:00
|
|
|
CGM.getTypes().arrangeBlockFunctionCall(Args, FuncTy);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-04-08 06:10:22 +08:00
|
|
|
// Cast the function pointer to the right type.
|
2012-02-17 11:33:10 +08:00
|
|
|
llvm::Type *BlockFTy = CGM.getTypes().GetFunctionType(FnInfo);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2011-07-18 12:24:23 +08:00
|
|
|
llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);
|
2017-10-05 04:32:17 +08:00
|
|
|
Func = Builder.CreatePointerCast(Func, BlockFTyPtr);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2016-10-27 07:46:34 +08:00
|
|
|
// Prepare the callee.
|
|
|
|
CGCallee Callee(CGCalleeInfo(), Func);
|
|
|
|
|
2009-02-12 08:39:25 +08:00
|
|
|
// And call the block.
|
2016-10-27 07:46:34 +08:00
|
|
|
return EmitCall(FnInfo, Callee, ReturnValue, Args);
|
2009-02-12 08:39:25 +08:00
|
|
|
}
|
2009-02-13 01:55:02 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Address CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable,
|
|
|
|
bool isByRef) {
|
2011-02-07 18:33:21 +08:00
|
|
|
assert(BlockInfo && "evaluating block ref without block information?");
|
|
|
|
const CGBlockInfo::Capture &capture = BlockInfo->getCapture(variable);
|
2010-05-20 09:18:31 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// Handle constant captures.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
if (capture.isConstant()) return LocalDeclMap.find(variable)->second;
|
2010-05-20 09:18:31 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Address addr =
|
|
|
|
Builder.CreateStructGEP(LoadBlockStruct(), capture.getIndex(),
|
|
|
|
capture.getOffset(), "block.capture.addr");
|
2010-05-20 09:18:31 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
if (isByRef) {
|
|
|
|
// addr should be a void** right now. Load, then cast the result
|
|
|
|
// to byref*.
|
2009-03-04 11:23:46 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
auto &byrefInfo = getBlockByrefInfo(variable);
|
|
|
|
addr = Address(Builder.CreateLoad(addr), byrefInfo.ByrefAlignment);
|
|
|
|
|
|
|
|
auto byrefPointerType = llvm::PointerType::get(byrefInfo.Type, 0);
|
|
|
|
addr = Builder.CreateBitCast(addr, byrefPointerType, "byref.addr");
|
|
|
|
|
|
|
|
addr = emitBlockByrefAddress(addr, byrefInfo, /*follow*/ true,
|
|
|
|
variable->getName());
|
2010-05-20 09:18:31 +08:00
|
|
|
}
|
2009-10-21 11:49:08 +08:00
|
|
|
|
2017-10-30 19:49:31 +08:00
|
|
|
if (capture.fieldType()->isReferenceType())
|
|
|
|
addr = EmitLoadOfReference(MakeAddrLValue(addr, capture.fieldType()));
|
2009-10-21 11:49:08 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
return addr;
|
2009-03-04 11:23:46 +08:00
|
|
|
}
|
|
|
|
|
2016-12-22 10:50:20 +08:00
|
|
|
void CodeGenModule::setAddrOfGlobalBlock(const BlockExpr *BE,
|
|
|
|
llvm::Constant *Addr) {
|
|
|
|
bool Ok = EmittedGlobalBlocks.insert(std::make_pair(BE, Addr)).second;
|
|
|
|
(void)Ok;
|
|
|
|
assert(Ok && "Trying to replace an already-existing global block!");
|
|
|
|
}
|
|
|
|
|
2009-02-15 06:16:35 +08:00
|
|
|
llvm::Constant *
|
2016-11-03 10:21:43 +08:00
|
|
|
CodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *BE,
|
|
|
|
StringRef Name) {
|
2016-12-22 10:50:20 +08:00
|
|
|
if (llvm::Constant *Block = getAddrOfGlobalBlockIfEmitted(BE))
|
|
|
|
return Block;
|
|
|
|
|
2016-11-03 10:21:43 +08:00
|
|
|
CGBlockInfo blockInfo(BE->getBlockDecl(), Name);
|
|
|
|
blockInfo.BlockExpression = BE;
|
2009-02-13 23:32:32 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// Compute information about the layout, etc., of this block.
|
2014-05-21 13:09:00 +08:00
|
|
|
computeBlockInfo(*this, nullptr, blockInfo);
|
2010-02-24 05:51:17 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// Using that metadata, generate the actual block function.
|
|
|
|
{
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
CodeGenFunction::DeclMapTy LocalDeclMap;
|
2017-09-23 05:32:06 +08:00
|
|
|
CodeGenFunction(*this).GenerateBlockFunction(
|
|
|
|
GlobalDecl(), blockInfo, LocalDeclMap,
|
|
|
|
/*IsLambdaConversionToBlock*/ false, /*BuildGlobalBlock*/ true);
|
2011-02-07 18:33:21 +08:00
|
|
|
}
|
2009-02-13 23:32:32 +08:00
|
|
|
|
2017-09-23 05:32:06 +08:00
|
|
|
return getAddrOfGlobalBlockIfEmitted(BE);
|
2011-02-07 18:33:21 +08:00
|
|
|
}
|
2009-11-18 03:33:30 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,
|
|
|
|
const CGBlockInfo &blockInfo,
|
|
|
|
llvm::Constant *blockFn) {
|
|
|
|
assert(blockInfo.CanBeGlobal);
|
2016-12-22 10:50:20 +08:00
|
|
|
// Callers should detect this case on their own: calling this function
|
|
|
|
// generally requires computing layout information, which is a waste of time
|
|
|
|
// if we've already emitted this block.
|
|
|
|
assert(!CGM.getAddrOfGlobalBlockIfEmitted(blockInfo.BlockExpression) &&
|
|
|
|
"Refusing to re-emit a global block.");
|
2009-02-13 23:32:32 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// Generate the constants for the block literal initializer.
|
2016-11-29 06:18:27 +08:00
|
|
|
ConstantInitBuilder builder(CGM);
|
2016-11-19 16:17:24 +08:00
|
|
|
auto fields = builder.beginStruct();
|
2009-02-13 23:32:32 +08:00
|
|
|
|
2017-10-05 04:32:17 +08:00
|
|
|
bool IsOpenCL = CGM.getLangOpts().OpenCL;
|
|
|
|
if (!IsOpenCL) {
|
|
|
|
// isa
|
|
|
|
fields.add(CGM.getNSConcreteGlobalBlock());
|
|
|
|
|
|
|
|
// __flags
|
|
|
|
BlockFlags flags = BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE;
|
|
|
|
if (blockInfo.UsesStret)
|
|
|
|
flags |= BLOCK_USE_STRET;
|
2009-02-13 23:32:32 +08:00
|
|
|
|
2017-10-05 04:32:17 +08:00
|
|
|
fields.addInt(CGM.IntTy, flags.getBitMask());
|
2009-02-13 23:32:32 +08:00
|
|
|
|
2017-10-05 04:32:17 +08:00
|
|
|
// Reserved
|
|
|
|
fields.addInt(CGM.IntTy, 0);
|
2018-03-08 03:32:58 +08:00
|
|
|
|
|
|
|
// Function
|
|
|
|
fields.add(blockFn);
|
2017-10-05 04:32:17 +08:00
|
|
|
} else {
|
|
|
|
fields.addInt(CGM.IntTy, blockInfo.BlockSize.getQuantity());
|
|
|
|
fields.addInt(CGM.IntTy, blockInfo.BlockAlign.getQuantity());
|
|
|
|
}
|
2009-02-13 23:32:32 +08:00
|
|
|
|
2017-10-05 04:32:17 +08:00
|
|
|
if (!IsOpenCL) {
|
|
|
|
// Descriptor
|
|
|
|
fields.add(buildBlockDescriptor(CGM, blockInfo));
|
|
|
|
} else if (auto *Helper =
|
|
|
|
CGM.getTargetCodeGenInfo().getTargetOpenCLBlockHelper()) {
|
|
|
|
for (auto I : Helper->getCustomFieldValues(CGM, blockInfo)) {
|
|
|
|
fields.add(I);
|
|
|
|
}
|
|
|
|
}
|
2016-11-19 16:17:24 +08:00
|
|
|
|
2017-01-27 23:11:34 +08:00
|
|
|
unsigned AddrSpace = 0;
|
|
|
|
if (CGM.getContext().getLangOpts().OpenCL)
|
|
|
|
AddrSpace = CGM.getContext().getTargetAddressSpace(LangAS::opencl_global);
|
|
|
|
|
|
|
|
llvm::Constant *literal = fields.finishAndCreateGlobal(
|
|
|
|
"__block_literal_global", blockInfo.BlockAlign,
|
|
|
|
/*constant*/ true, llvm::GlobalVariable::InternalLinkage, AddrSpace);
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
// Return a constant of the appropriately-casted type.
|
2016-12-22 10:50:20 +08:00
|
|
|
llvm::Type *RequiredType =
|
2011-02-07 18:33:21 +08:00
|
|
|
CGM.getTypes().ConvertType(blockInfo.getBlockExpr()->getType());
|
2016-12-22 10:50:20 +08:00
|
|
|
llvm::Constant *Result =
|
2017-01-27 23:11:34 +08:00
|
|
|
llvm::ConstantExpr::getPointerCast(literal, RequiredType);
|
2016-12-22 10:50:20 +08:00
|
|
|
CGM.setAddrOfGlobalBlock(blockInfo.BlockExpression, Result);
|
2018-02-16 00:39:19 +08:00
|
|
|
if (CGM.getContext().getLangOpts().OpenCL)
|
|
|
|
CGM.getOpenCLRuntime().recordBlockInfo(
|
|
|
|
blockInfo.BlockExpression,
|
|
|
|
cast<llvm::Function>(blockFn->stripPointerCasts()), Result);
|
2016-12-22 10:50:20 +08:00
|
|
|
return Result;
|
2009-02-22 04:00:35 +08:00
|
|
|
}
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
void CodeGenFunction::setBlockContextParameter(const ImplicitParamDecl *D,
|
|
|
|
unsigned argNum,
|
|
|
|
llvm::Value *arg) {
|
|
|
|
assert(BlockInfo && "not emitting prologue of block invocation function?!");
|
|
|
|
|
2017-10-27 04:08:52 +08:00
|
|
|
// Allocate a stack slot like for any local variable to guarantee optimal
|
|
|
|
// debug info at -O0. The mem2reg pass will eliminate it when optimizing.
|
|
|
|
Address alloc = CreateMemTemp(D->getType(), D->getName() + ".addr");
|
|
|
|
Builder.CreateStore(arg, alloc);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
if (CGDebugInfo *DI = getDebugInfo()) {
|
2016-02-02 19:06:51 +08:00
|
|
|
if (CGM.getCodeGenOpts().getDebugInfo() >=
|
|
|
|
codegenoptions::LimitedDebugInfo) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
DI->setLocation(D->getLocation());
|
2017-10-27 04:08:52 +08:00
|
|
|
DI->EmitDeclareOfBlockLiteralArgVariable(
|
|
|
|
*BlockInfo, D->getName(), argNum,
|
|
|
|
cast<llvm::AllocaInst>(alloc.getPointer()), Builder);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SourceLocation StartLoc = BlockInfo->getBlockExpr()->getBody()->getLocStart();
|
|
|
|
ApplyDebugLocation Scope(*this, StartLoc);
|
|
|
|
|
|
|
|
// Instead of messing around with LocalDeclMap, just set the value
|
|
|
|
// directly as BlockPointer.
|
2017-01-27 23:11:34 +08:00
|
|
|
BlockPointer = Builder.CreatePointerCast(
|
|
|
|
arg,
|
|
|
|
BlockInfo->StructureType->getPointerTo(
|
|
|
|
getContext().getLangOpts().OpenCL
|
|
|
|
? getContext().getTargetAddressSpace(LangAS::opencl_generic)
|
|
|
|
: 0),
|
|
|
|
"block");
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Address CodeGenFunction::LoadBlockStruct() {
|
|
|
|
assert(BlockInfo && "not in a block invocation function!");
|
|
|
|
assert(BlockPointer && "no block pointer set!");
|
|
|
|
return Address(BlockPointer, BlockInfo->BlockAlign);
|
|
|
|
}
|
|
|
|
|
2009-03-05 16:32:30 +08:00
|
|
|
llvm::Function *
|
2011-02-07 18:33:21 +08:00
|
|
|
CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
|
|
|
|
const CGBlockInfo &blockInfo,
|
2012-02-25 10:48:22 +08:00
|
|
|
const DeclMapTy &ldm,
|
2017-09-23 05:32:06 +08:00
|
|
|
bool IsLambdaConversionToBlock,
|
|
|
|
bool BuildGlobalBlock) {
|
2011-02-07 18:33:21 +08:00
|
|
|
const BlockDecl *blockDecl = blockInfo.getBlockDecl();
|
2009-04-16 05:51:44 +08:00
|
|
|
|
2012-06-27 00:06:38 +08:00
|
|
|
CurGD = GD;
|
2015-01-14 07:06:27 +08:00
|
|
|
|
|
|
|
CurEHLocation = blockInfo.getBlockExpr()->getLocEnd();
|
2012-06-27 00:06:38 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
BlockInfo = &blockInfo;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-03-14 07:34:28 +08:00
|
|
|
// Arrange for local static and local extern declarations to appear
|
2011-02-07 18:33:21 +08:00
|
|
|
// to be local to this function as well, in case they're directly
|
|
|
|
// referenced in a block.
|
|
|
|
for (DeclMapTy::const_iterator i = ldm.begin(), e = ldm.end(); i != e; ++i) {
|
2014-05-09 08:08:36 +08:00
|
|
|
const auto *var = dyn_cast<VarDecl>(i->first);
|
2011-02-07 18:33:21 +08:00
|
|
|
if (var && !var->hasLocalStorage())
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
setAddrOfLocalVar(var, i->second);
|
2009-03-14 07:34:28 +08:00
|
|
|
}
|
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// Begin building the function declaration.
|
2009-02-13 23:32:32 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// Build the argument list.
|
|
|
|
FunctionArgList args;
|
2009-02-13 01:55:02 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// The first argument is the block pointer. Just take it as a void*
|
|
|
|
// and cast it later.
|
|
|
|
QualType selfTy = getContext().VoidPtrTy;
|
2017-01-27 23:11:34 +08:00
|
|
|
|
|
|
|
// For OpenCL passed block pointer can be private AS local variable or
|
|
|
|
// global AS program scope variable (for the case with and without captures).
|
2017-07-03 16:49:44 +08:00
|
|
|
// Generic AS is used therefore to be able to accommodate both private and
|
2017-01-27 23:11:34 +08:00
|
|
|
// generic AS in one implementation.
|
|
|
|
if (getLangOpts().OpenCL)
|
|
|
|
selfTy = getContext().getPointerType(getContext().getAddrSpaceQualType(
|
|
|
|
getContext().VoidTy, LangAS::opencl_generic));
|
|
|
|
|
2009-10-21 11:49:08 +08:00
|
|
|
IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor");
|
|
|
|
|
2017-06-09 21:40:18 +08:00
|
|
|
ImplicitParamDecl SelfDecl(getContext(), const_cast<BlockDecl *>(blockDecl),
|
|
|
|
SourceLocation(), II, selfTy,
|
|
|
|
ImplicitParamDecl::ObjCSelf);
|
|
|
|
args.push_back(&SelfDecl);
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
// Now add the rest of the parameters.
|
2015-02-18 00:48:30 +08:00
|
|
|
args.append(blockDecl->param_begin(), blockDecl->param_end());
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
// Create the function declaration.
|
2012-02-17 11:33:10 +08:00
|
|
|
const FunctionProtoType *fnType = blockInfo.getBlockExpr()->getFunctionType();
|
2016-03-11 12:30:31 +08:00
|
|
|
const CGFunctionInfo &fnInfo =
|
|
|
|
CGM.getTypes().arrangeBlockFunctionDeclaration(fnType, args);
|
2014-03-29 21:28:05 +08:00
|
|
|
if (CGM.ReturnSlotInterferesWithArgs(fnInfo))
|
2011-03-09 16:39:33 +08:00
|
|
|
blockInfo.UsesStret = true;
|
|
|
|
|
2012-02-17 11:33:10 +08:00
|
|
|
llvm::FunctionType *fnLLVMType = CGM.getTypes().GetFunctionType(fnInfo);
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2014-06-06 06:10:59 +08:00
|
|
|
StringRef name = CGM.getBlockMangledName(GD, blockDecl);
|
2014-06-03 10:13:57 +08:00
|
|
|
llvm::Function *fn = llvm::Function::Create(
|
|
|
|
fnLLVMType, llvm::GlobalValue::InternalLinkage, name, &CGM.getModule());
|
2011-02-07 18:33:21 +08:00
|
|
|
CGM.SetInternalFunctionAttributes(blockDecl, fn, fnInfo);
|
|
|
|
|
2017-10-05 04:32:17 +08:00
|
|
|
if (BuildGlobalBlock) {
|
|
|
|
auto GenVoidPtrTy = getContext().getLangOpts().OpenCL
|
|
|
|
? CGM.getOpenCLRuntime().getGenericVoidPointerType()
|
|
|
|
: VoidPtrTy;
|
2017-09-23 05:32:06 +08:00
|
|
|
buildGlobalBlock(CGM, blockInfo,
|
2017-10-05 04:32:17 +08:00
|
|
|
llvm::ConstantExpr::getPointerCast(fn, GenVoidPtrTy));
|
|
|
|
}
|
2017-09-23 05:32:06 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// Begin generating the function.
|
2014-01-26 00:55:45 +08:00
|
|
|
StartFunction(blockDecl, fnType->getReturnType(), fn, fnInfo, args,
|
2014-04-11 07:21:53 +08:00
|
|
|
blockDecl->getLocation(),
|
2011-03-26 05:26:13 +08:00
|
|
|
blockInfo.getBlockExpr()->getBody()->getLocStart());
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2011-02-23 06:38:33 +08:00
|
|
|
// Okay. Undo some of what StartFunction did.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
|
2013-03-30 03:20:35 +08:00
|
|
|
// At -O0 we generate an explicit alloca for the BlockPointer, so the RA
|
|
|
|
// won't delete the dbg.declare intrinsics for captured variables.
|
|
|
|
llvm::Value *BlockPointerDbgLoc = BlockPointer;
|
|
|
|
if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
|
|
|
|
// Allocate a stack slot for it, so we can point the debugger to it
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Address Alloca = CreateTempAlloca(BlockPointer->getType(),
|
|
|
|
getPointerAlign(),
|
|
|
|
"block.addr");
|
2013-04-02 09:00:48 +08:00
|
|
|
// Set the DebugLocation to empty, so the store is recognized as a
|
|
|
|
// frame setup instruction by llvm::DwarfDebug::beginFunction().
|
2015-02-04 04:00:54 +08:00
|
|
|
auto NL = ApplyDebugLocation::CreateEmpty(*this);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Builder.CreateStore(BlockPointer, Alloca);
|
|
|
|
BlockPointerDbgLoc = Alloca.getPointer();
|
2013-03-30 03:20:35 +08:00
|
|
|
}
|
2009-02-13 23:32:32 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// If we have a C++ 'this' reference, go ahead and force it into
|
|
|
|
// existence now.
|
|
|
|
if (blockDecl->capturesCXXThis()) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Address addr =
|
|
|
|
Builder.CreateStructGEP(LoadBlockStruct(), blockInfo.CXXThisIndex,
|
|
|
|
blockInfo.CXXThisOffset, "block.captured-this");
|
2011-02-07 18:33:21 +08:00
|
|
|
CXXThisValue = Builder.CreateLoad(addr, "this");
|
|
|
|
}
|
2009-02-13 23:32:32 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// Also force all the constant captures.
|
2014-03-15 02:34:04 +08:00
|
|
|
for (const auto &CI : blockDecl->captures()) {
|
|
|
|
const VarDecl *variable = CI.getVariable();
|
2011-02-07 18:33:21 +08:00
|
|
|
const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
|
|
|
|
if (!capture.isConstant()) continue;
|
2009-02-13 01:55:02 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
CharUnits align = getContext().getDeclAlign(variable);
|
|
|
|
Address alloca =
|
|
|
|
CreateMemTemp(variable->getType(), align, "block.captured-const");
|
2009-02-13 23:32:32 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Builder.CreateStore(capture.getConstant(), alloca);
|
2010-05-20 09:18:31 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
setAddrOfLocalVar(variable, alloca);
|
2010-05-21 12:11:14 +08:00
|
|
|
}
|
|
|
|
|
2012-03-10 17:33:50 +08:00
|
|
|
// Save a spot to insert the debug information for all the DeclRefExprs.
|
2009-09-30 10:43:10 +08:00
|
|
|
llvm::BasicBlock *entry = Builder.GetInsertBlock();
|
2009-10-02 06:29:41 +08:00
|
|
|
llvm::BasicBlock::iterator entry_ptr = Builder.GetInsertPoint();
|
|
|
|
--entry_ptr;
|
2009-09-30 10:43:10 +08:00
|
|
|
|
2012-02-25 10:48:22 +08:00
|
|
|
if (IsLambdaConversionToBlock)
|
|
|
|
EmitLambdaBlockInvokeBody();
|
2014-03-07 04:24:27 +08:00
|
|
|
else {
|
2015-12-06 22:32:39 +08:00
|
|
|
PGO.assignRegionCounters(GlobalDecl(blockDecl), fn);
|
2015-04-24 07:06:47 +08:00
|
|
|
incrementProfileCounter(blockDecl->getBody());
|
2012-02-25 10:48:22 +08:00
|
|
|
EmitStmt(blockDecl->getBody());
|
2014-03-07 04:24:27 +08:00
|
|
|
}
|
2009-10-02 06:29:41 +08:00
|
|
|
|
2009-10-01 08:27:30 +08:00
|
|
|
// Remember where we were...
|
|
|
|
llvm::BasicBlock *resume = Builder.GetInsertBlock();
|
2009-10-02 06:29:41 +08:00
|
|
|
|
2009-10-01 08:27:30 +08:00
|
|
|
// Go back to the entry.
|
2009-10-02 06:29:41 +08:00
|
|
|
++entry_ptr;
|
|
|
|
Builder.SetInsertPoint(entry, entry_ptr);
|
|
|
|
|
2012-03-10 17:33:50 +08:00
|
|
|
// Emit debug information for all the DeclRefExprs.
|
2011-02-07 18:33:21 +08:00
|
|
|
// FIXME: also for 'this'
|
2009-09-30 10:43:10 +08:00
|
|
|
if (CGDebugInfo *DI = getDebugInfo()) {
|
2014-03-15 02:34:04 +08:00
|
|
|
for (const auto &CI : blockDecl->captures()) {
|
|
|
|
const VarDecl *variable = CI.getVariable();
|
2011-10-14 05:45:18 +08:00
|
|
|
DI->EmitLocation(Builder, variable->getLocation());
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2016-02-02 19:06:51 +08:00
|
|
|
if (CGM.getCodeGenOpts().getDebugInfo() >=
|
|
|
|
codegenoptions::LimitedDebugInfo) {
|
2012-05-04 15:39:27 +08:00
|
|
|
const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
|
|
|
|
if (capture.isConstant()) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
auto addr = LocalDeclMap.find(variable)->second;
|
2018-02-03 21:55:59 +08:00
|
|
|
(void)DI->EmitDeclareOfAutoVariable(variable, addr.getPointer(),
|
|
|
|
Builder);
|
2012-05-04 15:39:27 +08:00
|
|
|
continue;
|
|
|
|
}
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2015-11-07 07:00:41 +08:00
|
|
|
DI->EmitDeclareOfBlockDeclRefVariable(
|
|
|
|
variable, BlockPointerDbgLoc, Builder, blockInfo,
|
|
|
|
entry_ptr == entry->end() ? nullptr : &*entry_ptr);
|
2012-05-04 15:39:27 +08:00
|
|
|
}
|
2009-09-30 10:43:10 +08:00
|
|
|
}
|
2013-01-05 02:51:35 +08:00
|
|
|
// Recover location if it was changed in the above loop.
|
|
|
|
DI->EmitLocation(Builder,
|
2013-04-09 04:52:12 +08:00
|
|
|
cast<CompoundStmt>(blockDecl->getBody())->getRBracLoc());
|
2009-09-30 10:43:10 +08:00
|
|
|
}
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2009-10-01 08:27:30 +08:00
|
|
|
// And resume where we left off.
|
2014-05-21 13:09:00 +08:00
|
|
|
if (resume == nullptr)
|
2009-10-01 08:27:30 +08:00
|
|
|
Builder.ClearInsertionPoint();
|
|
|
|
else
|
|
|
|
Builder.SetInsertPoint(resume);
|
2009-09-30 10:43:10 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
FinishFunction(cast<CompoundStmt>(blockDecl->getBody())->getRBracLoc());
|
2009-02-13 01:55:02 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
return fn;
|
2009-02-13 01:55:02 +08:00
|
|
|
}
|
2009-02-28 17:07:16 +08:00
|
|
|
|
2017-03-07 00:23:04 +08:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
/// Represents a type of copy/destroy operation that should be performed for an
|
|
|
|
/// entity that's captured by a block.
|
|
|
|
enum class BlockCaptureEntityKind {
|
|
|
|
CXXRecord, // Copy or destroy
|
|
|
|
ARCWeak,
|
|
|
|
ARCStrong,
|
2018-02-28 15:15:55 +08:00
|
|
|
NonTrivialCStruct,
|
2017-03-07 00:23:04 +08:00
|
|
|
BlockObject, // Assign or release
|
|
|
|
None
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Represents a captured entity that requires extra operations in order for
|
|
|
|
/// this entity to be copied or destroyed correctly.
|
|
|
|
struct BlockCaptureManagedEntity {
|
|
|
|
BlockCaptureEntityKind Kind;
|
|
|
|
BlockFieldFlags Flags;
|
|
|
|
const BlockDecl::Capture &CI;
|
|
|
|
const CGBlockInfo::Capture &Capture;
|
|
|
|
|
|
|
|
BlockCaptureManagedEntity(BlockCaptureEntityKind Type, BlockFieldFlags Flags,
|
|
|
|
const BlockDecl::Capture &CI,
|
|
|
|
const CGBlockInfo::Capture &Capture)
|
|
|
|
: Kind(Type), Flags(Flags), CI(CI), Capture(Capture) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
|
|
static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
|
|
|
|
computeCopyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,
|
|
|
|
const LangOptions &LangOpts) {
|
|
|
|
if (CI.getCopyExpr()) {
|
|
|
|
assert(!CI.isByRef());
|
|
|
|
// don't bother computing flags
|
|
|
|
return std::make_pair(BlockCaptureEntityKind::CXXRecord, BlockFieldFlags());
|
|
|
|
}
|
|
|
|
BlockFieldFlags Flags;
|
|
|
|
if (CI.isByRef()) {
|
|
|
|
Flags = BLOCK_FIELD_IS_BYREF;
|
|
|
|
if (T.isObjCGCWeak())
|
|
|
|
Flags |= BLOCK_FIELD_IS_WEAK;
|
|
|
|
return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
Flags = BLOCK_FIELD_IS_OBJECT;
|
|
|
|
bool isBlockPointer = T->isBlockPointerType();
|
|
|
|
if (isBlockPointer)
|
|
|
|
Flags = BLOCK_FIELD_IS_BLOCK;
|
|
|
|
|
2018-02-28 15:15:55 +08:00
|
|
|
switch (T.isNonTrivialToPrimitiveCopy()) {
|
|
|
|
case QualType::PCK_Struct:
|
|
|
|
return std::make_pair(BlockCaptureEntityKind::NonTrivialCStruct,
|
|
|
|
BlockFieldFlags());
|
|
|
|
case QualType::PCK_ARCStrong:
|
|
|
|
// We need to retain the copied value for __strong direct captures.
|
|
|
|
// If it's a block pointer, we have to copy the block and assign that to
|
|
|
|
// the destination pointer, so we might as well use _Block_object_assign.
|
|
|
|
// Otherwise we can avoid that.
|
2017-03-07 00:23:04 +08:00
|
|
|
return std::make_pair(!isBlockPointer ? BlockCaptureEntityKind::ARCStrong
|
|
|
|
: BlockCaptureEntityKind::BlockObject,
|
|
|
|
Flags);
|
2018-02-28 15:15:55 +08:00
|
|
|
case QualType::PCK_Trivial:
|
|
|
|
case QualType::PCK_VolatileTrivial: {
|
|
|
|
if (!T->isObjCRetainableType())
|
|
|
|
// For all other types, the memcpy is fine.
|
|
|
|
return std::make_pair(BlockCaptureEntityKind::None, BlockFieldFlags());
|
2017-03-07 00:23:04 +08:00
|
|
|
|
2018-02-28 15:15:55 +08:00
|
|
|
// Special rules for ARC captures:
|
|
|
|
Qualifiers QS = T.getQualifiers();
|
2017-03-07 00:23:04 +08:00
|
|
|
|
2018-03-13 01:05:06 +08:00
|
|
|
// We need to register __weak direct captures with the runtime.
|
|
|
|
if (QS.getObjCLifetime() == Qualifiers::OCL_Weak)
|
|
|
|
return std::make_pair(BlockCaptureEntityKind::ARCWeak, Flags);
|
|
|
|
|
2018-02-28 15:15:55 +08:00
|
|
|
// Non-ARC captures of retainable pointers are strong and
|
|
|
|
// therefore require a call to _Block_object_assign.
|
|
|
|
if (!QS.getObjCLifetime() && !LangOpts.ObjCAutoRefCount)
|
|
|
|
return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
|
|
|
|
|
|
|
|
// Otherwise the memcpy is fine.
|
|
|
|
return std::make_pair(BlockCaptureEntityKind::None, BlockFieldFlags());
|
|
|
|
}
|
|
|
|
}
|
2018-03-01 03:28:47 +08:00
|
|
|
llvm_unreachable("after exhaustive PrimitiveCopyKind switch");
|
2017-03-07 00:23:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Find the set of block captures that need to be explicitly copied or destroy.
|
|
|
|
static void findBlockCapturedManagedEntities(
|
|
|
|
const CGBlockInfo &BlockInfo, const LangOptions &LangOpts,
|
|
|
|
SmallVectorImpl<BlockCaptureManagedEntity> &ManagedCaptures,
|
|
|
|
llvm::function_ref<std::pair<BlockCaptureEntityKind, BlockFieldFlags>(
|
|
|
|
const BlockDecl::Capture &, QualType, const LangOptions &)>
|
|
|
|
Predicate) {
|
|
|
|
for (const auto &CI : BlockInfo.getBlockDecl()->captures()) {
|
|
|
|
const VarDecl *Variable = CI.getVariable();
|
|
|
|
const CGBlockInfo::Capture &Capture = BlockInfo.getCapture(Variable);
|
|
|
|
if (Capture.isConstant())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
auto Info = Predicate(CI, Variable->getType(), LangOpts);
|
|
|
|
if (Info.first != BlockCaptureEntityKind::None)
|
|
|
|
ManagedCaptures.emplace_back(Info.first, Info.second, CI, Capture);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-22 11:56:22 +08:00
|
|
|
/// Generate the copy-helper function for a block closure object:
|
|
|
|
/// static void block_copy_helper(block_t *dst, block_t *src);
|
|
|
|
/// The runtime will have previously initialized 'dst' by doing a
|
|
|
|
/// bit-copy of 'src'.
|
|
|
|
///
|
|
|
|
/// Note that this copies an entire block closure object to the heap;
|
|
|
|
/// it should not be confused with a 'byref copy helper', which moves
|
|
|
|
/// the contents of an individual __block variable to the heap.
|
2011-02-07 18:33:21 +08:00
|
|
|
llvm::Constant *
|
2011-02-08 16:22:06 +08:00
|
|
|
CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {
|
2011-02-07 18:33:21 +08:00
|
|
|
ASTContext &C = getContext();
|
|
|
|
|
|
|
|
FunctionArgList args;
|
2017-06-09 21:40:18 +08:00
|
|
|
ImplicitParamDecl DstDecl(getContext(), C.VoidPtrTy,
|
|
|
|
ImplicitParamDecl::Other);
|
|
|
|
args.push_back(&DstDecl);
|
|
|
|
ImplicitParamDecl SrcDecl(getContext(), C.VoidPtrTy,
|
|
|
|
ImplicitParamDecl::Other);
|
|
|
|
args.push_back(&SrcDecl);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2016-03-11 12:30:31 +08:00
|
|
|
const CGFunctionInfo &FI =
|
|
|
|
CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, args);
|
2009-03-06 09:33:24 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// FIXME: it would be nice if these were mergeable with things with
|
|
|
|
// identical semantics.
|
2012-02-17 11:33:10 +08:00
|
|
|
llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);
|
2009-03-06 09:33:24 +08:00
|
|
|
|
|
|
|
llvm::Function *Fn =
|
|
|
|
llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
|
2010-01-22 21:59:13 +08:00
|
|
|
"__copy_helper_block_", &CGM.getModule());
|
2009-03-06 09:33:24 +08:00
|
|
|
|
|
|
|
IdentifierInfo *II
|
|
|
|
= &CGM.getContext().Idents.get("__copy_helper_block_");
|
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
FunctionDecl *FD = FunctionDecl::Create(C,
|
|
|
|
C.getTranslationUnitDecl(),
|
2011-03-08 16:55:46 +08:00
|
|
|
SourceLocation(),
|
2014-05-21 13:09:00 +08:00
|
|
|
SourceLocation(), II, C.VoidTy,
|
|
|
|
nullptr, SC_Static,
|
2010-04-20 06:54:31 +08:00
|
|
|
false,
|
2012-04-12 08:35:04 +08:00
|
|
|
false);
|
2015-10-09 04:26:34 +08:00
|
|
|
|
2018-03-01 07:46:35 +08:00
|
|
|
CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);
|
2015-10-09 04:26:34 +08:00
|
|
|
|
2014-04-11 09:13:04 +08:00
|
|
|
StartFunction(FD, C.VoidTy, Fn, FI, args);
|
2017-10-27 05:27:24 +08:00
|
|
|
ApplyDebugLocation NL{*this, blockInfo.getBlockExpr()->getLocStart()};
|
2011-07-18 12:24:23 +08:00
|
|
|
llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo();
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2017-06-09 21:40:18 +08:00
|
|
|
Address src = GetAddrOfLocalVar(&SrcDecl);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
src = Address(Builder.CreateLoad(src), blockInfo.BlockAlign);
|
2011-02-08 16:22:06 +08:00
|
|
|
src = Builder.CreateBitCast(src, structPtrTy, "block.source");
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2017-06-09 21:40:18 +08:00
|
|
|
Address dst = GetAddrOfLocalVar(&DstDecl);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
dst = Address(Builder.CreateLoad(dst), blockInfo.BlockAlign);
|
2011-02-08 16:22:06 +08:00
|
|
|
dst = Builder.CreateBitCast(dst, structPtrTy, "block.dest");
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2017-03-07 00:23:04 +08:00
|
|
|
SmallVector<BlockCaptureManagedEntity, 4> CopiedCaptures;
|
|
|
|
findBlockCapturedManagedEntities(blockInfo, getLangOpts(), CopiedCaptures,
|
|
|
|
computeCopyInfoForBlockCapture);
|
Define weak and __weak to mean ARC-style weak references, even in MRC.
Previously, __weak was silently accepted and ignored in MRC mode.
That makes this a potentially source-breaking change that we have to
roll out cautiously. Accordingly, for the time being, actual support
for __weak references in MRC is experimental, and the compiler will
reject attempts to actually form such references. The intent is to
eventually enable the feature by default in all non-GC modes.
(It is, of course, incompatible with ObjC GC's interpretation of
__weak.)
If you like, you can enable this feature with
-Xclang -fobjc-weak
but like any -Xclang option, this option may be removed at any point,
e.g. if/when it is eventually enabled by default.
This patch also enables the use of the ARC __unsafe_unretained qualifier
in MRC. Unlike __weak, this is being enabled immediately. Since
variables are essentially __unsafe_unretained by default in MRC,
the only practical uses are (1) communication and (2) changing the
default behavior of by-value block capture.
As an implementation matter, this means that the ObjC ownership
qualifiers may appear in any ObjC language mode, and so this patch
removes a number of checks for getLangOpts().ObjCAutoRefCount
that were guarding the processing of these qualifiers. I don't
expect this to be a significant drain on performance; it may even
be faster to just check for these qualifiers directly on a type
(since it's probably in a register anyway) than to do N dependent
loads to grab the LangOptions.
rdar://9674298
llvm-svn: 251041
2015-10-23 02:38:17 +08:00
|
|
|
|
2017-03-07 00:23:04 +08:00
|
|
|
for (const auto &CopiedCapture : CopiedCaptures) {
|
|
|
|
const BlockDecl::Capture &CI = CopiedCapture.CI;
|
|
|
|
const CGBlockInfo::Capture &capture = CopiedCapture.Capture;
|
|
|
|
BlockFieldFlags flags = CopiedCapture.Flags;
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
unsigned index = capture.getIndex();
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Address srcField = Builder.CreateStructGEP(src, index, capture.getOffset());
|
|
|
|
Address dstField = Builder.CreateStructGEP(dst, index, capture.getOffset());
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
// If there's an explicit copy expression, we do that.
|
2017-03-07 00:23:04 +08:00
|
|
|
if (CI.getCopyExpr()) {
|
|
|
|
assert(CopiedCapture.Kind == BlockCaptureEntityKind::CXXRecord);
|
|
|
|
EmitSynthesizedCXXCopyCtor(dstField, srcField, CI.getCopyExpr());
|
|
|
|
} else if (CopiedCapture.Kind == BlockCaptureEntityKind::ARCWeak) {
|
2011-06-16 07:02:42 +08:00
|
|
|
EmitARCCopyWeak(dstField, srcField);
|
2018-02-28 15:15:55 +08:00
|
|
|
// If this is a C struct that requires non-trivial copy construction, emit a
|
|
|
|
// call to its copy constructor.
|
|
|
|
} else if (CopiedCapture.Kind ==
|
|
|
|
BlockCaptureEntityKind::NonTrivialCStruct) {
|
|
|
|
QualType varType = CI.getVariable()->getType();
|
|
|
|
callCStructCopyConstructor(MakeAddrLValue(dstField, varType),
|
|
|
|
MakeAddrLValue(srcField, varType));
|
2011-02-07 18:33:21 +08:00
|
|
|
} else {
|
|
|
|
llvm::Value *srcValue = Builder.CreateLoad(srcField, "blockcopy.src");
|
2017-03-07 00:23:04 +08:00
|
|
|
if (CopiedCapture.Kind == BlockCaptureEntityKind::ARCStrong) {
|
2012-10-17 10:28:37 +08:00
|
|
|
// At -O0, store null into the destination field (so that the
|
|
|
|
// storeStrong doesn't over-release) and then call storeStrong.
|
|
|
|
// This is a workaround to not having an initStrong call.
|
|
|
|
if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
|
2014-05-09 08:08:36 +08:00
|
|
|
auto *ty = cast<llvm::PointerType>(srcValue->getType());
|
2012-10-17 10:28:37 +08:00
|
|
|
llvm::Value *null = llvm::ConstantPointerNull::get(ty);
|
|
|
|
Builder.CreateStore(null, dstField);
|
|
|
|
EmitARCStoreStrongCall(dstField, srcValue, true);
|
|
|
|
|
|
|
|
// With optimization enabled, take advantage of the fact that
|
|
|
|
// the blocks runtime guarantees a memcpy of the block data, and
|
|
|
|
// just emit a retain of the src field.
|
|
|
|
} else {
|
|
|
|
EmitARCRetainNonBlock(srcValue);
|
|
|
|
|
|
|
|
// We don't need this anymore, so kill it. It's not quite
|
|
|
|
// worth the annoyance to avoid creating it in the first place.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
cast<llvm::Instruction>(dstField.getPointer())->eraseFromParent();
|
2012-10-17 10:28:37 +08:00
|
|
|
}
|
|
|
|
} else {
|
2017-03-07 00:23:04 +08:00
|
|
|
assert(CopiedCapture.Kind == BlockCaptureEntityKind::BlockObject);
|
2012-10-17 10:28:37 +08:00
|
|
|
srcValue = Builder.CreateBitCast(srcValue, VoidPtrTy);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
llvm::Value *dstAddr =
|
|
|
|
Builder.CreateBitCast(dstField.getPointer(), VoidPtrTy);
|
2013-03-01 03:01:20 +08:00
|
|
|
llvm::Value *args[] = {
|
|
|
|
dstAddr, srcValue, llvm::ConstantInt::get(Int32Ty, flags.getBitMask())
|
|
|
|
};
|
|
|
|
|
2017-03-07 00:23:04 +08:00
|
|
|
const VarDecl *variable = CI.getVariable();
|
2013-03-01 03:01:20 +08:00
|
|
|
bool copyCanThrow = false;
|
2014-03-15 02:34:04 +08:00
|
|
|
if (CI.isByRef() && variable->getType()->getAsCXXRecordDecl()) {
|
2013-03-01 03:01:20 +08:00
|
|
|
const Expr *copyExpr =
|
|
|
|
CGM.getContext().getBlockVarCopyInits(variable);
|
|
|
|
if (copyExpr) {
|
|
|
|
copyCanThrow = true; // FIXME: reuse the noexcept logic
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (copyCanThrow) {
|
|
|
|
EmitRuntimeCallOrInvoke(CGM.getBlockObjectAssign(), args);
|
|
|
|
} else {
|
|
|
|
EmitNounwindRuntimeCall(CGM.getBlockObjectAssign(), args);
|
|
|
|
}
|
2012-10-17 10:28:37 +08:00
|
|
|
}
|
2009-03-07 10:35:30 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-08 16:22:06 +08:00
|
|
|
FinishFunction();
|
2009-03-06 09:33:24 +08:00
|
|
|
|
2011-02-15 17:22:45 +08:00
|
|
|
return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
|
2009-03-04 11:23:46 +08:00
|
|
|
}
|
|
|
|
|
2018-02-28 15:15:55 +08:00
|
|
|
static BlockFieldFlags
|
|
|
|
getBlockFieldFlagsForObjCObjectPointer(const BlockDecl::Capture &CI,
|
|
|
|
QualType T) {
|
|
|
|
BlockFieldFlags Flags = BLOCK_FIELD_IS_OBJECT;
|
|
|
|
if (T->isBlockPointerType())
|
|
|
|
Flags = BLOCK_FIELD_IS_BLOCK;
|
|
|
|
return Flags;
|
|
|
|
}
|
|
|
|
|
2017-03-07 00:23:04 +08:00
|
|
|
static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
|
|
|
|
computeDestroyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,
|
|
|
|
const LangOptions &LangOpts) {
|
|
|
|
if (CI.isByRef()) {
|
2018-02-28 15:15:55 +08:00
|
|
|
BlockFieldFlags Flags = BLOCK_FIELD_IS_BYREF;
|
2017-03-07 00:23:04 +08:00
|
|
|
if (T.isObjCGCWeak())
|
|
|
|
Flags |= BLOCK_FIELD_IS_WEAK;
|
|
|
|
return std::make_pair(BlockCaptureEntityKind::BlockObject, Flags);
|
|
|
|
}
|
|
|
|
|
2018-02-28 15:15:55 +08:00
|
|
|
switch (T.isDestructedType()) {
|
|
|
|
case QualType::DK_cxx_destructor:
|
2017-03-07 00:23:04 +08:00
|
|
|
return std::make_pair(BlockCaptureEntityKind::CXXRecord, BlockFieldFlags());
|
2018-02-28 15:15:55 +08:00
|
|
|
case QualType::DK_objc_strong_lifetime:
|
|
|
|
// Use objc_storeStrong for __strong direct captures; the
|
|
|
|
// dynamic tools really like it when we do this.
|
|
|
|
return std::make_pair(BlockCaptureEntityKind::ARCStrong,
|
|
|
|
getBlockFieldFlagsForObjCObjectPointer(CI, T));
|
|
|
|
case QualType::DK_objc_weak_lifetime:
|
|
|
|
// Support __weak direct captures.
|
|
|
|
return std::make_pair(BlockCaptureEntityKind::ARCWeak,
|
|
|
|
getBlockFieldFlagsForObjCObjectPointer(CI, T));
|
|
|
|
case QualType::DK_nontrivial_c_struct:
|
|
|
|
return std::make_pair(BlockCaptureEntityKind::NonTrivialCStruct,
|
|
|
|
BlockFieldFlags());
|
|
|
|
case QualType::DK_none: {
|
|
|
|
// Non-ARC captures are strong, and we need to use _Block_object_dispose.
|
|
|
|
if (T->isObjCRetainableType() && !T.getQualifiers().hasObjCLifetime() &&
|
|
|
|
!LangOpts.ObjCAutoRefCount)
|
|
|
|
return std::make_pair(BlockCaptureEntityKind::BlockObject,
|
|
|
|
getBlockFieldFlagsForObjCObjectPointer(CI, T));
|
|
|
|
// Otherwise, we have nothing to do.
|
|
|
|
return std::make_pair(BlockCaptureEntityKind::None, BlockFieldFlags());
|
|
|
|
}
|
2017-03-07 00:23:04 +08:00
|
|
|
}
|
2018-03-01 03:28:47 +08:00
|
|
|
llvm_unreachable("after exhaustive DestructionKind switch");
|
2017-03-07 00:23:04 +08:00
|
|
|
}
|
|
|
|
|
2013-01-22 11:56:22 +08:00
|
|
|
/// Generate the destroy-helper function for a block closure object:
|
|
|
|
/// static void block_destroy_helper(block_t *theBlock);
|
|
|
|
///
|
|
|
|
/// Note that this destroys a heap-allocated block closure object;
|
|
|
|
/// it should not be confused with a 'byref destroy helper', which
|
|
|
|
/// destroys the heap-allocated contents of an individual __block
|
|
|
|
/// variable.
|
2011-02-07 18:33:21 +08:00
|
|
|
llvm::Constant *
|
2011-02-08 16:22:06 +08:00
|
|
|
CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) {
|
2011-02-07 18:33:21 +08:00
|
|
|
ASTContext &C = getContext();
|
2009-03-06 09:33:24 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
FunctionArgList args;
|
2017-06-09 21:40:18 +08:00
|
|
|
ImplicitParamDecl SrcDecl(getContext(), C.VoidPtrTy,
|
|
|
|
ImplicitParamDecl::Other);
|
|
|
|
args.push_back(&SrcDecl);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2016-03-11 12:30:31 +08:00
|
|
|
const CGFunctionInfo &FI =
|
|
|
|
CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, args);
|
2009-03-06 09:33:24 +08:00
|
|
|
|
2009-06-06 07:26:36 +08:00
|
|
|
// FIXME: We'd like to put these into a mergable by content, with
|
|
|
|
// internal linkage.
|
2012-02-17 11:33:10 +08:00
|
|
|
llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);
|
2009-03-06 09:33:24 +08:00
|
|
|
|
|
|
|
llvm::Function *Fn =
|
|
|
|
llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
|
2010-01-22 21:59:13 +08:00
|
|
|
"__destroy_helper_block_", &CGM.getModule());
|
2009-03-06 09:33:24 +08:00
|
|
|
|
|
|
|
IdentifierInfo *II
|
|
|
|
= &CGM.getContext().Idents.get("__destroy_helper_block_");
|
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
FunctionDecl *FD = FunctionDecl::Create(C, C.getTranslationUnitDecl(),
|
2011-03-08 16:55:46 +08:00
|
|
|
SourceLocation(),
|
2014-05-21 13:09:00 +08:00
|
|
|
SourceLocation(), II, C.VoidTy,
|
|
|
|
nullptr, SC_Static,
|
2012-04-12 08:35:04 +08:00
|
|
|
false, false);
|
2015-10-09 04:26:34 +08:00
|
|
|
|
2018-03-01 07:46:35 +08:00
|
|
|
CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);
|
2015-10-09 04:26:34 +08:00
|
|
|
|
2014-04-11 09:13:04 +08:00
|
|
|
StartFunction(FD, C.VoidTy, Fn, FI, args);
|
2017-10-27 05:27:24 +08:00
|
|
|
ApplyDebugLocation NL{*this, blockInfo.getBlockExpr()->getLocStart()};
|
2009-03-07 10:53:18 +08:00
|
|
|
|
2011-07-18 12:24:23 +08:00
|
|
|
llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo();
|
2009-04-11 02:52:28 +08:00
|
|
|
|
2017-06-09 21:40:18 +08:00
|
|
|
Address src = GetAddrOfLocalVar(&SrcDecl);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
src = Address(Builder.CreateLoad(src), blockInfo.BlockAlign);
|
2011-02-08 16:22:06 +08:00
|
|
|
src = Builder.CreateBitCast(src, structPtrTy, "block");
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2011-02-08 16:22:06 +08:00
|
|
|
CodeGenFunction::RunCleanupsScope cleanups(*this);
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2017-03-07 00:23:04 +08:00
|
|
|
SmallVector<BlockCaptureManagedEntity, 4> DestroyedCaptures;
|
|
|
|
findBlockCapturedManagedEntities(blockInfo, getLangOpts(), DestroyedCaptures,
|
|
|
|
computeDestroyInfoForBlockCapture);
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2017-03-07 00:23:04 +08:00
|
|
|
for (const auto &DestroyedCapture : DestroyedCaptures) {
|
|
|
|
const BlockDecl::Capture &CI = DestroyedCapture.CI;
|
|
|
|
const CGBlockInfo::Capture &capture = DestroyedCapture.Capture;
|
|
|
|
BlockFieldFlags flags = DestroyedCapture.Flags;
|
2011-02-07 18:33:21 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Address srcField =
|
|
|
|
Builder.CreateStructGEP(src, capture.getIndex(), capture.getOffset());
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2017-03-07 00:23:04 +08:00
|
|
|
// If the captured record has a destructor then call it.
|
|
|
|
if (DestroyedCapture.Kind == BlockCaptureEntityKind::CXXRecord) {
|
|
|
|
const auto *Dtor =
|
|
|
|
CI.getVariable()->getType()->getAsCXXRecordDecl()->getDestructor();
|
|
|
|
PushDestructorCleanup(Dtor, srcField);
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2017-03-07 00:23:04 +08:00
|
|
|
// If this is a __weak capture, emit the release directly.
|
|
|
|
} else if (DestroyedCapture.Kind == BlockCaptureEntityKind::ARCWeak) {
|
2011-06-16 07:02:42 +08:00
|
|
|
EmitARCDestroyWeak(srcField);
|
|
|
|
|
2012-10-17 10:28:37 +08:00
|
|
|
// Destroy strong objects with a call if requested.
|
2017-03-07 00:23:04 +08:00
|
|
|
} else if (DestroyedCapture.Kind == BlockCaptureEntityKind::ARCStrong) {
|
2013-03-13 11:10:54 +08:00
|
|
|
EmitARCDestroyStrong(srcField, ARCImpreciseLifetime);
|
2012-10-17 10:28:37 +08:00
|
|
|
|
2018-02-28 15:15:55 +08:00
|
|
|
// If this is a C struct that requires non-trivial destruction, emit a call
|
|
|
|
// to its destructor.
|
|
|
|
} else if (DestroyedCapture.Kind ==
|
|
|
|
BlockCaptureEntityKind::NonTrivialCStruct) {
|
|
|
|
QualType varType = CI.getVariable()->getType();
|
|
|
|
pushDestroy(varType.isDestructedType(), srcField, varType);
|
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// Otherwise we call _Block_object_dispose. It wouldn't be too
|
|
|
|
// hard to just emit this as a cleanup if we wanted to make sure
|
|
|
|
// that things were done in reverse.
|
|
|
|
} else {
|
2017-03-07 00:23:04 +08:00
|
|
|
assert(DestroyedCapture.Kind == BlockCaptureEntityKind::BlockObject);
|
2011-02-07 18:33:21 +08:00
|
|
|
llvm::Value *value = Builder.CreateLoad(srcField);
|
2011-02-15 17:22:45 +08:00
|
|
|
value = Builder.CreateBitCast(value, VoidPtrTy);
|
2011-02-07 18:33:21 +08:00
|
|
|
BuildBlockRelease(value, flags);
|
2009-03-07 10:53:18 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
cleanups.ForceCleanup();
|
|
|
|
|
2011-02-08 16:22:06 +08:00
|
|
|
FinishFunction();
|
2009-03-06 09:33:24 +08:00
|
|
|
|
2011-02-15 17:22:45 +08:00
|
|
|
return llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
|
2009-03-06 09:33:24 +08:00
|
|
|
}
|
|
|
|
|
2011-03-31 16:03:29 +08:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
/// Emits the copy/dispose helper functions for a __block object of id type.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
class ObjectByrefHelpers final : public BlockByrefHelpers {
|
2011-03-31 16:03:29 +08:00
|
|
|
BlockFieldFlags Flags;
|
|
|
|
|
|
|
|
public:
|
|
|
|
ObjectByrefHelpers(CharUnits alignment, BlockFieldFlags flags)
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
: BlockByrefHelpers(alignment), Flags(flags) {}
|
2011-03-31 16:03:29 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
void emitCopy(CodeGenFunction &CGF, Address destField,
|
|
|
|
Address srcField) override {
|
2011-03-31 16:03:29 +08:00
|
|
|
destField = CGF.Builder.CreateBitCast(destField, CGF.VoidPtrTy);
|
|
|
|
|
|
|
|
srcField = CGF.Builder.CreateBitCast(srcField, CGF.VoidPtrPtrTy);
|
|
|
|
llvm::Value *srcValue = CGF.Builder.CreateLoad(srcField);
|
|
|
|
|
|
|
|
unsigned flags = (Flags | BLOCK_BYREF_CALLER).getBitMask();
|
|
|
|
|
|
|
|
llvm::Value *flagsVal = llvm::ConstantInt::get(CGF.Int32Ty, flags);
|
|
|
|
llvm::Value *fn = CGF.CGM.getBlockObjectAssign();
|
2013-03-01 03:01:20 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
llvm::Value *args[] = { destField.getPointer(), srcValue, flagsVal };
|
2013-03-01 03:01:20 +08:00
|
|
|
CGF.EmitNounwindRuntimeCall(fn, args);
|
2011-03-31 16:03:29 +08:00
|
|
|
}
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
void emitDispose(CodeGenFunction &CGF, Address field) override {
|
2011-03-31 16:03:29 +08:00
|
|
|
field = CGF.Builder.CreateBitCast(field, CGF.Int8PtrTy->getPointerTo(0));
|
|
|
|
llvm::Value *value = CGF.Builder.CreateLoad(field);
|
|
|
|
|
|
|
|
CGF.BuildBlockRelease(value, Flags | BLOCK_BYREF_CALLER);
|
|
|
|
}
|
|
|
|
|
2014-03-12 14:41:41 +08:00
|
|
|
void profileImpl(llvm::FoldingSetNodeID &id) const override {
|
2011-03-31 16:03:29 +08:00
|
|
|
id.AddInteger(Flags.getBitMask());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
/// Emits the copy/dispose helpers for an ARC __block __weak variable.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
class ARCWeakByrefHelpers final : public BlockByrefHelpers {
|
2011-06-16 07:02:42 +08:00
|
|
|
public:
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
ARCWeakByrefHelpers(CharUnits alignment) : BlockByrefHelpers(alignment) {}
|
2011-06-16 07:02:42 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
void emitCopy(CodeGenFunction &CGF, Address destField,
|
|
|
|
Address srcField) override {
|
2011-06-16 07:02:42 +08:00
|
|
|
CGF.EmitARCMoveWeak(destField, srcField);
|
|
|
|
}
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
void emitDispose(CodeGenFunction &CGF, Address field) override {
|
2011-06-16 07:02:42 +08:00
|
|
|
CGF.EmitARCDestroyWeak(field);
|
|
|
|
}
|
|
|
|
|
2014-03-12 14:41:41 +08:00
|
|
|
void profileImpl(llvm::FoldingSetNodeID &id) const override {
|
2011-06-16 07:02:42 +08:00
|
|
|
// 0 is distinguishable from all pointers and byref flags
|
|
|
|
id.AddInteger(0);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Emits the copy/dispose helpers for an ARC __block __strong variable
|
|
|
|
/// that's not of block-pointer type.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
class ARCStrongByrefHelpers final : public BlockByrefHelpers {
|
2011-06-16 07:02:42 +08:00
|
|
|
public:
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
ARCStrongByrefHelpers(CharUnits alignment) : BlockByrefHelpers(alignment) {}
|
2011-06-16 07:02:42 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
void emitCopy(CodeGenFunction &CGF, Address destField,
|
|
|
|
Address srcField) override {
|
2011-06-16 07:02:42 +08:00
|
|
|
// Do a "move" by copying the value and then zeroing out the old
|
|
|
|
// variable.
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
llvm::Value *value = CGF.Builder.CreateLoad(srcField);
|
2011-11-09 11:17:26 +08:00
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
llvm::Value *null =
|
|
|
|
llvm::ConstantPointerNull::get(cast<llvm::PointerType>(value->getType()));
|
2011-11-09 11:17:26 +08:00
|
|
|
|
2013-01-05 07:32:24 +08:00
|
|
|
if (CGF.CGM.getCodeGenOpts().OptimizationLevel == 0) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
CGF.Builder.CreateStore(null, destField);
|
2013-01-05 07:32:24 +08:00
|
|
|
CGF.EmitARCStoreStrongCall(destField, value, /*ignored*/ true);
|
|
|
|
CGF.EmitARCStoreStrongCall(srcField, null, /*ignored*/ true);
|
|
|
|
return;
|
|
|
|
}
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
CGF.Builder.CreateStore(value, destField);
|
|
|
|
CGF.Builder.CreateStore(null, srcField);
|
2011-06-16 07:02:42 +08:00
|
|
|
}
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
void emitDispose(CodeGenFunction &CGF, Address field) override {
|
2013-03-13 11:10:54 +08:00
|
|
|
CGF.EmitARCDestroyStrong(field, ARCImpreciseLifetime);
|
2011-06-16 07:02:42 +08:00
|
|
|
}
|
|
|
|
|
2014-03-12 14:41:41 +08:00
|
|
|
void profileImpl(llvm::FoldingSetNodeID &id) const override {
|
2011-06-16 07:02:42 +08:00
|
|
|
// 1 is distinguishable from all pointers and byref flags
|
|
|
|
id.AddInteger(1);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-11-09 11:17:26 +08:00
|
|
|
/// Emits the copy/dispose helpers for an ARC __block __strong
|
|
|
|
/// variable that's of block-pointer type.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
class ARCStrongBlockByrefHelpers final : public BlockByrefHelpers {
|
2011-11-09 11:17:26 +08:00
|
|
|
public:
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
ARCStrongBlockByrefHelpers(CharUnits alignment)
|
|
|
|
: BlockByrefHelpers(alignment) {}
|
2011-11-09 11:17:26 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
void emitCopy(CodeGenFunction &CGF, Address destField,
|
|
|
|
Address srcField) override {
|
2011-11-09 11:17:26 +08:00
|
|
|
// Do the copy with objc_retainBlock; that's all that
|
|
|
|
// _Block_object_assign would do anyway, and we'd have to pass the
|
|
|
|
// right arguments to make sure it doesn't get no-op'ed.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
llvm::Value *oldValue = CGF.Builder.CreateLoad(srcField);
|
2011-11-09 11:17:26 +08:00
|
|
|
llvm::Value *copy = CGF.EmitARCRetainBlock(oldValue, /*mandatory*/ true);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
CGF.Builder.CreateStore(copy, destField);
|
2011-11-09 11:17:26 +08:00
|
|
|
}
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
void emitDispose(CodeGenFunction &CGF, Address field) override {
|
2013-03-13 11:10:54 +08:00
|
|
|
CGF.EmitARCDestroyStrong(field, ARCImpreciseLifetime);
|
2011-11-09 11:17:26 +08:00
|
|
|
}
|
|
|
|
|
2014-03-12 14:41:41 +08:00
|
|
|
void profileImpl(llvm::FoldingSetNodeID &id) const override {
|
2011-11-09 11:17:26 +08:00
|
|
|
// 2 is distinguishable from all pointers and byref flags
|
|
|
|
id.AddInteger(2);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-03-31 16:03:29 +08:00
|
|
|
/// Emits the copy/dispose helpers for a __block variable with a
|
|
|
|
/// nontrivial copy constructor or destructor.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
class CXXByrefHelpers final : public BlockByrefHelpers {
|
2011-03-31 16:03:29 +08:00
|
|
|
QualType VarType;
|
|
|
|
const Expr *CopyExpr;
|
|
|
|
|
|
|
|
public:
|
|
|
|
CXXByrefHelpers(CharUnits alignment, QualType type,
|
|
|
|
const Expr *copyExpr)
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
: BlockByrefHelpers(alignment), VarType(type), CopyExpr(copyExpr) {}
|
2011-03-31 16:03:29 +08:00
|
|
|
|
2014-05-21 13:09:00 +08:00
|
|
|
bool needsCopy() const override { return CopyExpr != nullptr; }
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
void emitCopy(CodeGenFunction &CGF, Address destField,
|
|
|
|
Address srcField) override {
|
2011-03-31 16:03:29 +08:00
|
|
|
if (!CopyExpr) return;
|
|
|
|
CGF.EmitSynthesizedCXXCopyCtor(destField, srcField, CopyExpr);
|
|
|
|
}
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
void emitDispose(CodeGenFunction &CGF, Address field) override {
|
2011-03-31 16:03:29 +08:00
|
|
|
EHScopeStack::stable_iterator cleanupDepth = CGF.EHStack.stable_begin();
|
|
|
|
CGF.PushDestructorCleanup(VarType, field);
|
|
|
|
CGF.PopCleanupBlocks(cleanupDepth);
|
|
|
|
}
|
|
|
|
|
2014-03-12 14:41:41 +08:00
|
|
|
void profileImpl(llvm::FoldingSetNodeID &id) const override {
|
2011-03-31 16:03:29 +08:00
|
|
|
id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr());
|
|
|
|
}
|
|
|
|
};
|
2018-02-28 15:15:55 +08:00
|
|
|
|
|
|
|
/// Emits the copy/dispose helpers for a __block variable that is a non-trivial
|
|
|
|
/// C struct.
|
|
|
|
class NonTrivialCStructByrefHelpers final : public BlockByrefHelpers {
|
|
|
|
QualType VarType;
|
|
|
|
|
|
|
|
public:
|
|
|
|
NonTrivialCStructByrefHelpers(CharUnits alignment, QualType type)
|
|
|
|
: BlockByrefHelpers(alignment), VarType(type) {}
|
|
|
|
|
|
|
|
void emitCopy(CodeGenFunction &CGF, Address destField,
|
|
|
|
Address srcField) override {
|
|
|
|
CGF.callCStructMoveConstructor(CGF.MakeAddrLValue(destField, VarType),
|
|
|
|
CGF.MakeAddrLValue(srcField, VarType));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool needsDispose() const override {
|
|
|
|
return VarType.isDestructedType();
|
|
|
|
}
|
|
|
|
|
|
|
|
void emitDispose(CodeGenFunction &CGF, Address field) override {
|
|
|
|
EHScopeStack::stable_iterator cleanupDepth = CGF.EHStack.stable_begin();
|
|
|
|
CGF.pushDestroy(VarType.isDestructedType(), field, VarType);
|
|
|
|
CGF.PopCleanupBlocks(cleanupDepth);
|
|
|
|
}
|
|
|
|
|
|
|
|
void profileImpl(llvm::FoldingSetNodeID &id) const override {
|
|
|
|
id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr());
|
|
|
|
}
|
|
|
|
};
|
2011-03-31 16:03:29 +08:00
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
|
|
static llvm::Constant *
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
generateByrefCopyHelper(CodeGenFunction &CGF, const BlockByrefInfo &byrefInfo,
|
|
|
|
BlockByrefHelpers &generator) {
|
2011-03-31 16:03:29 +08:00
|
|
|
ASTContext &Context = CGF.getContext();
|
|
|
|
|
|
|
|
QualType R = Context.VoidTy;
|
2009-03-06 10:29:21 +08:00
|
|
|
|
2011-03-09 12:27:21 +08:00
|
|
|
FunctionArgList args;
|
2017-06-09 21:40:18 +08:00
|
|
|
ImplicitParamDecl Dst(CGF.getContext(), Context.VoidPtrTy,
|
|
|
|
ImplicitParamDecl::Other);
|
|
|
|
args.push_back(&Dst);
|
2011-03-09 12:27:21 +08:00
|
|
|
|
2017-06-09 21:40:18 +08:00
|
|
|
ImplicitParamDecl Src(CGF.getContext(), Context.VoidPtrTy,
|
|
|
|
ImplicitParamDecl::Other);
|
|
|
|
args.push_back(&Src);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2016-03-11 12:30:31 +08:00
|
|
|
const CGFunctionInfo &FI =
|
|
|
|
CGF.CGM.getTypes().arrangeBuiltinFunctionDeclaration(R, args);
|
2009-03-06 10:29:21 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
llvm::FunctionType *LTy = CGF.CGM.getTypes().GetFunctionType(FI);
|
2009-03-06 10:29:21 +08:00
|
|
|
|
2009-06-06 07:26:36 +08:00
|
|
|
// FIXME: We'd like to put these into a mergable by content, with
|
|
|
|
// internal linkage.
|
2009-03-06 10:29:21 +08:00
|
|
|
llvm::Function *Fn =
|
|
|
|
llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
|
2011-03-31 16:03:29 +08:00
|
|
|
"__Block_byref_object_copy_", &CGF.CGM.getModule());
|
2009-03-06 10:29:21 +08:00
|
|
|
|
|
|
|
IdentifierInfo *II
|
2011-03-31 16:03:29 +08:00
|
|
|
= &Context.Idents.get("__Block_byref_object_copy_");
|
2009-03-06 10:29:21 +08:00
|
|
|
|
2011-03-31 16:03:29 +08:00
|
|
|
FunctionDecl *FD = FunctionDecl::Create(Context,
|
|
|
|
Context.getTranslationUnitDecl(),
|
2011-03-08 16:55:46 +08:00
|
|
|
SourceLocation(),
|
2014-05-21 13:09:00 +08:00
|
|
|
SourceLocation(), II, R, nullptr,
|
2010-08-26 11:08:43 +08:00
|
|
|
SC_Static,
|
2012-04-12 10:16:49 +08:00
|
|
|
false, false);
|
2011-06-16 07:02:42 +08:00
|
|
|
|
2018-03-01 07:46:35 +08:00
|
|
|
CGF.CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);
|
2015-10-09 04:26:34 +08:00
|
|
|
|
2014-04-11 09:13:04 +08:00
|
|
|
CGF.StartFunction(FD, R, Fn, FI, args);
|
2009-03-06 10:29:21 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
if (generator.needsCopy()) {
|
|
|
|
llvm::Type *byrefPtrType = byrefInfo.Type->getPointerTo(0);
|
2011-03-31 16:03:29 +08:00
|
|
|
|
|
|
|
// dst->x
|
2017-06-09 21:40:18 +08:00
|
|
|
Address destField = CGF.GetAddrOfLocalVar(&Dst);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
destField = Address(CGF.Builder.CreateLoad(destField),
|
|
|
|
byrefInfo.ByrefAlignment);
|
2011-03-31 16:03:29 +08:00
|
|
|
destField = CGF.Builder.CreateBitCast(destField, byrefPtrType);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
destField = CGF.emitBlockByrefAddress(destField, byrefInfo, false,
|
|
|
|
"dest-object");
|
2011-03-31 16:03:29 +08:00
|
|
|
|
|
|
|
// src->x
|
2017-06-09 21:40:18 +08:00
|
|
|
Address srcField = CGF.GetAddrOfLocalVar(&Src);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
srcField = Address(CGF.Builder.CreateLoad(srcField),
|
|
|
|
byrefInfo.ByrefAlignment);
|
2011-03-31 16:03:29 +08:00
|
|
|
srcField = CGF.Builder.CreateBitCast(srcField, byrefPtrType);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
srcField = CGF.emitBlockByrefAddress(srcField, byrefInfo, false,
|
|
|
|
"src-object");
|
2011-03-31 16:03:29 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
generator.emitCopy(CGF, destField, srcField);
|
2011-03-31 16:03:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
CGF.FinishFunction();
|
|
|
|
|
|
|
|
return llvm::ConstantExpr::getBitCast(Fn, CGF.Int8PtrTy);
|
2009-03-06 10:29:21 +08:00
|
|
|
}
|
|
|
|
|
2011-03-31 16:03:29 +08:00
|
|
|
/// Build the copy helper for a __block variable.
|
|
|
|
static llvm::Constant *buildByrefCopyHelper(CodeGenModule &CGM,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
const BlockByrefInfo &byrefInfo,
|
|
|
|
BlockByrefHelpers &generator) {
|
2011-03-31 16:03:29 +08:00
|
|
|
CodeGenFunction CGF(CGM);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
return generateByrefCopyHelper(CGF, byrefInfo, generator);
|
2011-03-31 16:03:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Generate code for a __block variable's dispose helper.
|
|
|
|
static llvm::Constant *
|
|
|
|
generateByrefDisposeHelper(CodeGenFunction &CGF,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
const BlockByrefInfo &byrefInfo,
|
|
|
|
BlockByrefHelpers &generator) {
|
2011-03-31 16:03:29 +08:00
|
|
|
ASTContext &Context = CGF.getContext();
|
|
|
|
QualType R = Context.VoidTy;
|
2009-03-06 10:29:21 +08:00
|
|
|
|
2011-03-09 12:27:21 +08:00
|
|
|
FunctionArgList args;
|
2017-06-09 21:40:18 +08:00
|
|
|
ImplicitParamDecl Src(CGF.getContext(), Context.VoidPtrTy,
|
|
|
|
ImplicitParamDecl::Other);
|
|
|
|
args.push_back(&Src);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2016-03-11 12:30:31 +08:00
|
|
|
const CGFunctionInfo &FI =
|
|
|
|
CGF.CGM.getTypes().arrangeBuiltinFunctionDeclaration(R, args);
|
2009-03-06 10:29:21 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
llvm::FunctionType *LTy = CGF.CGM.getTypes().GetFunctionType(FI);
|
2009-03-06 10:29:21 +08:00
|
|
|
|
2009-06-06 07:26:36 +08:00
|
|
|
// FIXME: We'd like to put these into a mergable by content, with
|
|
|
|
// internal linkage.
|
2009-03-06 10:29:21 +08:00
|
|
|
llvm::Function *Fn =
|
|
|
|
llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
|
2010-12-03 01:02:11 +08:00
|
|
|
"__Block_byref_object_dispose_",
|
2011-03-31 16:03:29 +08:00
|
|
|
&CGF.CGM.getModule());
|
2009-03-06 10:29:21 +08:00
|
|
|
|
|
|
|
IdentifierInfo *II
|
2011-03-31 16:03:29 +08:00
|
|
|
= &Context.Idents.get("__Block_byref_object_dispose_");
|
2009-03-06 10:29:21 +08:00
|
|
|
|
2011-03-31 16:03:29 +08:00
|
|
|
FunctionDecl *FD = FunctionDecl::Create(Context,
|
|
|
|
Context.getTranslationUnitDecl(),
|
2011-03-08 16:55:46 +08:00
|
|
|
SourceLocation(),
|
2014-05-21 13:09:00 +08:00
|
|
|
SourceLocation(), II, R, nullptr,
|
2010-08-26 11:08:43 +08:00
|
|
|
SC_Static,
|
2012-04-12 10:16:49 +08:00
|
|
|
false, false);
|
2015-10-09 04:26:34 +08:00
|
|
|
|
2018-03-01 07:46:35 +08:00
|
|
|
CGF.CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);
|
2015-10-09 04:26:34 +08:00
|
|
|
|
2014-04-11 09:13:04 +08:00
|
|
|
CGF.StartFunction(FD, R, Fn, FI, args);
|
2009-03-06 12:53:30 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
if (generator.needsDispose()) {
|
2017-06-09 21:40:18 +08:00
|
|
|
Address addr = CGF.GetAddrOfLocalVar(&Src);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
addr = Address(CGF.Builder.CreateLoad(addr), byrefInfo.ByrefAlignment);
|
|
|
|
auto byrefPtrType = byrefInfo.Type->getPointerTo(0);
|
|
|
|
addr = CGF.Builder.CreateBitCast(addr, byrefPtrType);
|
|
|
|
addr = CGF.emitBlockByrefAddress(addr, byrefInfo, false, "object");
|
2011-02-08 16:22:06 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
generator.emitDispose(CGF, addr);
|
2010-12-03 01:02:11 +08:00
|
|
|
}
|
2009-03-06 10:29:21 +08:00
|
|
|
|
2011-03-31 16:03:29 +08:00
|
|
|
CGF.FinishFunction();
|
2011-02-08 16:22:06 +08:00
|
|
|
|
2011-03-31 16:03:29 +08:00
|
|
|
return llvm::ConstantExpr::getBitCast(Fn, CGF.Int8PtrTy);
|
2009-03-06 10:29:21 +08:00
|
|
|
}
|
|
|
|
|
2011-03-31 16:03:29 +08:00
|
|
|
/// Build the dispose helper for a __block variable.
|
|
|
|
static llvm::Constant *buildByrefDisposeHelper(CodeGenModule &CGM,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
const BlockByrefInfo &byrefInfo,
|
|
|
|
BlockByrefHelpers &generator) {
|
2011-03-31 16:03:29 +08:00
|
|
|
CodeGenFunction CGF(CGM);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
return generateByrefDisposeHelper(CGF, byrefInfo, generator);
|
2009-03-06 10:29:21 +08:00
|
|
|
}
|
|
|
|
|
2013-01-22 11:56:22 +08:00
|
|
|
/// Lazily build the copy and dispose helpers for a __block variable
|
|
|
|
/// with the given information.
|
2015-08-14 07:53:09 +08:00
|
|
|
template <class T>
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
static T *buildByrefHelpers(CodeGenModule &CGM, const BlockByrefInfo &byrefInfo,
|
|
|
|
T &&generator) {
|
2011-03-31 16:03:29 +08:00
|
|
|
llvm::FoldingSetNodeID id;
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
generator.Profile(id);
|
2011-03-31 16:03:29 +08:00
|
|
|
|
|
|
|
void *insertPos;
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
BlockByrefHelpers *node
|
2011-03-31 16:03:29 +08:00
|
|
|
= CGM.ByrefHelpersCache.FindNodeOrInsertPos(id, insertPos);
|
|
|
|
if (node) return static_cast<T*>(node);
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
generator.CopyHelper = buildByrefCopyHelper(CGM, byrefInfo, generator);
|
|
|
|
generator.DisposeHelper = buildByrefDisposeHelper(CGM, byrefInfo, generator);
|
2011-03-31 16:03:29 +08:00
|
|
|
|
2016-12-06 22:49:18 +08:00
|
|
|
T *copy = new (CGM.getContext()) T(std::forward<T>(generator));
|
2011-03-31 16:03:29 +08:00
|
|
|
CGM.ByrefHelpersCache.InsertNode(copy, insertPos);
|
|
|
|
return copy;
|
|
|
|
}
|
|
|
|
|
2013-01-22 11:56:22 +08:00
|
|
|
/// Build the copy and dispose helpers for the given __block variable
|
|
|
|
/// emission. Places the helpers in the global cache. Returns null
|
|
|
|
/// if no helpers are required.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
BlockByrefHelpers *
|
2011-07-18 12:24:23 +08:00
|
|
|
CodeGenFunction::buildByrefHelpers(llvm::StructType &byrefType,
|
2011-03-31 16:03:29 +08:00
|
|
|
const AutoVarEmission &emission) {
|
|
|
|
const VarDecl &var = *emission.Variable;
|
|
|
|
QualType type = var.getType();
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
auto &byrefInfo = getBlockByrefInfo(&var);
|
|
|
|
|
|
|
|
// The alignment we care about for the purposes of uniquing byref
|
|
|
|
// helpers is the alignment of the actual byref value field.
|
|
|
|
CharUnits valueAlignment =
|
|
|
|
byrefInfo.ByrefAlignment.alignmentAtOffset(byrefInfo.FieldOffset);
|
2013-01-22 11:56:22 +08:00
|
|
|
|
2011-03-31 16:03:29 +08:00
|
|
|
if (const CXXRecordDecl *record = type->getAsCXXRecordDecl()) {
|
|
|
|
const Expr *copyExpr = CGM.getContext().getBlockVarCopyInits(&var);
|
2014-05-21 13:09:00 +08:00
|
|
|
if (!copyExpr && record->hasTrivialDestructor()) return nullptr;
|
2011-03-31 16:03:29 +08:00
|
|
|
|
2015-08-14 07:53:09 +08:00
|
|
|
return ::buildByrefHelpers(
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
CGM, byrefInfo, CXXByrefHelpers(valueAlignment, type, copyExpr));
|
2011-03-31 16:03:29 +08:00
|
|
|
}
|
|
|
|
|
2018-02-28 15:15:55 +08:00
|
|
|
// If type is a non-trivial C struct type that is non-trivial to
|
|
|
|
// destructly move or destroy, build the copy and dispose helpers.
|
|
|
|
if (type.isNonTrivialToPrimitiveDestructiveMove() == QualType::PCK_Struct ||
|
|
|
|
type.isDestructedType() == QualType::DK_nontrivial_c_struct)
|
|
|
|
return ::buildByrefHelpers(
|
|
|
|
CGM, byrefInfo, NonTrivialCStructByrefHelpers(valueAlignment, type));
|
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
// Otherwise, if we don't have a retainable type, there's nothing to do.
|
|
|
|
// that the runtime does extra copies.
|
2014-05-21 13:09:00 +08:00
|
|
|
if (!type->isObjCRetainableType()) return nullptr;
|
2011-06-16 07:02:42 +08:00
|
|
|
|
|
|
|
Qualifiers qs = type.getQualifiers();
|
|
|
|
|
|
|
|
// If we have lifetime, that dominates.
|
|
|
|
if (Qualifiers::ObjCLifetime lifetime = qs.getObjCLifetime()) {
|
|
|
|
switch (lifetime) {
|
|
|
|
case Qualifiers::OCL_None: llvm_unreachable("impossible");
|
|
|
|
|
|
|
|
// These are just bits as far as the runtime is concerned.
|
|
|
|
case Qualifiers::OCL_ExplicitNone:
|
|
|
|
case Qualifiers::OCL_Autoreleasing:
|
2014-05-21 13:09:00 +08:00
|
|
|
return nullptr;
|
2011-06-16 07:02:42 +08:00
|
|
|
|
|
|
|
// Tell the runtime that this is ARC __weak, called by the
|
|
|
|
// byref routines.
|
2015-08-14 07:53:09 +08:00
|
|
|
case Qualifiers::OCL_Weak:
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
return ::buildByrefHelpers(CGM, byrefInfo,
|
|
|
|
ARCWeakByrefHelpers(valueAlignment));
|
2011-06-16 07:02:42 +08:00
|
|
|
|
|
|
|
// ARC __strong __block variables need to be retained.
|
|
|
|
case Qualifiers::OCL_Strong:
|
2011-11-09 11:17:26 +08:00
|
|
|
// Block pointers need to be copied, and there's no direct
|
|
|
|
// transfer possible.
|
2011-06-16 07:02:42 +08:00
|
|
|
if (type->isBlockPointerType()) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
return ::buildByrefHelpers(CGM, byrefInfo,
|
|
|
|
ARCStrongBlockByrefHelpers(valueAlignment));
|
2011-06-16 07:02:42 +08:00
|
|
|
|
|
|
|
// Otherwise, we transfer ownership of the retain from the stack
|
|
|
|
// to the heap.
|
|
|
|
} else {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
return ::buildByrefHelpers(CGM, byrefInfo,
|
|
|
|
ARCStrongByrefHelpers(valueAlignment));
|
2011-06-16 07:02:42 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
llvm_unreachable("fell out of lifetime switch!");
|
|
|
|
}
|
|
|
|
|
2011-03-31 16:03:29 +08:00
|
|
|
BlockFieldFlags flags;
|
|
|
|
if (type->isBlockPointerType()) {
|
|
|
|
flags |= BLOCK_FIELD_IS_BLOCK;
|
|
|
|
} else if (CGM.getContext().isObjCNSObjectType(type) ||
|
|
|
|
type->isObjCObjectPointerType()) {
|
|
|
|
flags |= BLOCK_FIELD_IS_OBJECT;
|
|
|
|
} else {
|
2014-05-21 13:09:00 +08:00
|
|
|
return nullptr;
|
2011-03-31 16:03:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (type.isObjCGCWeak())
|
|
|
|
flags |= BLOCK_FIELD_IS_WEAK;
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
return ::buildByrefHelpers(CGM, byrefInfo,
|
|
|
|
ObjectByrefHelpers(valueAlignment, flags));
|
2009-03-06 10:29:21 +08:00
|
|
|
}
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Address CodeGenFunction::emitBlockByrefAddress(Address baseAddr,
|
|
|
|
const VarDecl *var,
|
|
|
|
bool followForward) {
|
|
|
|
auto &info = getBlockByrefInfo(var);
|
|
|
|
return emitBlockByrefAddress(baseAddr, info, followForward, var->getName());
|
2011-03-31 09:59:53 +08:00
|
|
|
}
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Address CodeGenFunction::emitBlockByrefAddress(Address baseAddr,
|
|
|
|
const BlockByrefInfo &info,
|
|
|
|
bool followForward,
|
|
|
|
const llvm::Twine &name) {
|
|
|
|
// Chase the forwarding address if requested.
|
|
|
|
if (followForward) {
|
|
|
|
Address forwardingAddr =
|
|
|
|
Builder.CreateStructGEP(baseAddr, 1, getPointerSize(), "forwarding");
|
|
|
|
baseAddr = Address(Builder.CreateLoad(forwardingAddr), info.ByrefAlignment);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Builder.CreateStructGEP(baseAddr, info.FieldIndex,
|
|
|
|
info.FieldOffset, name);
|
2011-03-31 09:59:53 +08:00
|
|
|
}
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
/// BuildByrefInfo - This routine changes a __block variable declared as T x
|
2011-03-31 09:59:53 +08:00
|
|
|
/// into:
|
|
|
|
///
|
|
|
|
/// struct {
|
|
|
|
/// void *__isa;
|
|
|
|
/// void *__forwarding;
|
|
|
|
/// int32_t __flags;
|
|
|
|
/// int32_t __size;
|
|
|
|
/// void *__copy_helper; // only if needed
|
|
|
|
/// void *__destroy_helper; // only if needed
|
2012-11-15 01:15:51 +08:00
|
|
|
/// void *__byref_variable_layout;// only if needed
|
2011-03-31 09:59:53 +08:00
|
|
|
/// char padding[X]; // only if needed
|
|
|
|
/// T x;
|
|
|
|
/// } x
|
|
|
|
///
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
const BlockByrefInfo &CodeGenFunction::getBlockByrefInfo(const VarDecl *D) {
|
|
|
|
auto it = BlockByrefInfos.find(D);
|
|
|
|
if (it != BlockByrefInfos.end())
|
|
|
|
return it->second;
|
|
|
|
|
|
|
|
llvm::StructType *byrefType =
|
|
|
|
llvm::StructType::create(getLLVMContext(),
|
|
|
|
"struct.__block_byref_" + D->getNameAsString());
|
2011-03-31 09:59:53 +08:00
|
|
|
|
|
|
|
QualType Ty = D->getType();
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
CharUnits size;
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<llvm::Type *, 8> types;
|
2011-03-31 09:59:53 +08:00
|
|
|
|
|
|
|
// void *__isa;
|
2011-05-15 09:53:33 +08:00
|
|
|
types.push_back(Int8PtrTy);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
size += getPointerSize();
|
2011-03-31 09:59:53 +08:00
|
|
|
|
|
|
|
// void *__forwarding;
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
types.push_back(llvm::PointerType::getUnqual(byrefType));
|
|
|
|
size += getPointerSize();
|
2011-03-31 09:59:53 +08:00
|
|
|
|
|
|
|
// int32_t __flags;
|
2011-05-15 09:53:33 +08:00
|
|
|
types.push_back(Int32Ty);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
size += CharUnits::fromQuantity(4);
|
2011-03-31 09:59:53 +08:00
|
|
|
|
|
|
|
// int32_t __size;
|
2011-05-15 09:53:33 +08:00
|
|
|
types.push_back(Int32Ty);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
size += CharUnits::fromQuantity(4);
|
|
|
|
|
2012-11-29 07:12:17 +08:00
|
|
|
// Note that this must match *exactly* the logic in buildByrefHelpers.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
bool hasCopyAndDispose = getContext().BlockRequiresCopying(Ty, D);
|
|
|
|
if (hasCopyAndDispose) {
|
2011-03-31 09:59:53 +08:00
|
|
|
/// void *__copy_helper;
|
2011-05-15 09:53:33 +08:00
|
|
|
types.push_back(Int8PtrTy);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
size += getPointerSize();
|
2011-03-31 09:59:53 +08:00
|
|
|
|
|
|
|
/// void *__destroy_helper;
|
2011-05-15 09:53:33 +08:00
|
|
|
types.push_back(Int8PtrTy);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
size += getPointerSize();
|
2011-03-31 09:59:53 +08:00
|
|
|
}
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
|
2012-11-15 01:15:51 +08:00
|
|
|
bool HasByrefExtendedLayout = false;
|
|
|
|
Qualifiers::ObjCLifetime Lifetime;
|
|
|
|
if (getContext().getByrefLifetime(Ty, Lifetime, HasByrefExtendedLayout) &&
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
HasByrefExtendedLayout) {
|
2012-11-15 01:15:51 +08:00
|
|
|
/// void *__byref_variable_layout;
|
|
|
|
types.push_back(Int8PtrTy);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
size += CharUnits::fromQuantity(PointerSizeInBytes);
|
|
|
|
}
|
2011-03-31 09:59:53 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
// T x;
|
|
|
|
llvm::Type *varTy = ConvertTypeForMem(Ty);
|
2011-03-31 09:59:53 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
bool packed = false;
|
|
|
|
CharUnits varAlign = getContext().getDeclAlign(D);
|
2016-01-15 05:00:27 +08:00
|
|
|
CharUnits varOffset = size.alignTo(varAlign);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
|
|
|
|
// We may have to insert padding.
|
|
|
|
if (varOffset != size) {
|
|
|
|
llvm::Type *paddingTy =
|
|
|
|
llvm::ArrayType::get(Int8Ty, (varOffset - size).getQuantity());
|
|
|
|
|
|
|
|
types.push_back(paddingTy);
|
|
|
|
size = varOffset;
|
|
|
|
|
|
|
|
// Conversely, we might have to prevent LLVM from inserting padding.
|
|
|
|
} else if (CGM.getDataLayout().getABITypeAlignment(varTy)
|
|
|
|
> varAlign.getQuantity()) {
|
|
|
|
packed = true;
|
2011-03-31 09:59:53 +08:00
|
|
|
}
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
types.push_back(varTy);
|
2011-03-31 09:59:53 +08:00
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
byrefType->setBody(types, packed);
|
|
|
|
|
|
|
|
BlockByrefInfo info;
|
|
|
|
info.Type = byrefType;
|
|
|
|
info.FieldIndex = types.size() - 1;
|
|
|
|
info.FieldOffset = varOffset;
|
|
|
|
info.ByrefAlignment = std::max(varAlign, getPointerAlign());
|
|
|
|
|
|
|
|
auto pair = BlockByrefInfos.insert({D, info});
|
|
|
|
assert(pair.second && "info was inserted recursively?");
|
|
|
|
return pair.first->second;
|
2011-03-31 09:59:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Initialize the structural components of a __block variable, i.e.
|
|
|
|
/// everything but the actual object.
|
|
|
|
void CodeGenFunction::emitByrefStructureInit(const AutoVarEmission &emission) {
|
2011-03-31 16:03:29 +08:00
|
|
|
// Find the address of the local.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Address addr = emission.Addr;
|
2011-03-31 16:03:29 +08:00
|
|
|
|
|
|
|
// That's an alloca of the byref structure type.
|
2011-07-18 12:24:23 +08:00
|
|
|
llvm::StructType *byrefType = cast<llvm::StructType>(
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
cast<llvm::PointerType>(addr.getPointer()->getType())->getElementType());
|
|
|
|
|
|
|
|
unsigned nextHeaderIndex = 0;
|
|
|
|
CharUnits nextHeaderOffset;
|
|
|
|
auto storeHeaderField = [&](llvm::Value *value, CharUnits fieldSize,
|
|
|
|
const Twine &name) {
|
|
|
|
auto fieldAddr = Builder.CreateStructGEP(addr, nextHeaderIndex,
|
|
|
|
nextHeaderOffset, name);
|
|
|
|
Builder.CreateStore(value, fieldAddr);
|
|
|
|
|
|
|
|
nextHeaderIndex++;
|
|
|
|
nextHeaderOffset += fieldSize;
|
|
|
|
};
|
2011-03-31 09:59:53 +08:00
|
|
|
|
2011-03-31 16:03:29 +08:00
|
|
|
// Build the byref helpers if necessary. This is null if we don't need any.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
BlockByrefHelpers *helpers = buildByrefHelpers(*byrefType, emission);
|
2011-03-31 09:59:53 +08:00
|
|
|
|
|
|
|
const VarDecl &D = *emission.Variable;
|
|
|
|
QualType type = D.getType();
|
|
|
|
|
2012-11-15 01:15:51 +08:00
|
|
|
bool HasByrefExtendedLayout;
|
|
|
|
Qualifiers::ObjCLifetime ByrefLifetime;
|
|
|
|
bool ByRefHasLifetime =
|
|
|
|
getContext().getByrefLifetime(type, ByrefLifetime, HasByrefExtendedLayout);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
|
2011-03-31 16:03:29 +08:00
|
|
|
llvm::Value *V;
|
2011-03-31 09:59:53 +08:00
|
|
|
|
|
|
|
// Initialize the 'isa', which is just 0 or 1.
|
|
|
|
int isa = 0;
|
2011-03-31 16:03:29 +08:00
|
|
|
if (type.isObjCGCWeak())
|
2011-03-31 09:59:53 +08:00
|
|
|
isa = 1;
|
|
|
|
V = Builder.CreateIntToPtr(Builder.getInt32(isa), Int8PtrTy, "isa");
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
storeHeaderField(V, getPointerSize(), "byref.isa");
|
2011-03-31 09:59:53 +08:00
|
|
|
|
|
|
|
// Store the address of the variable into its own forwarding pointer.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
storeHeaderField(addr.getPointer(), getPointerSize(), "byref.forwarding");
|
2011-03-31 09:59:53 +08:00
|
|
|
|
|
|
|
// Blocks ABI:
|
|
|
|
// c) the flags field is set to either 0 if no helper functions are
|
2012-11-15 01:15:51 +08:00
|
|
|
// needed or BLOCK_BYREF_HAS_COPY_DISPOSE if they are,
|
2011-03-31 09:59:53 +08:00
|
|
|
BlockFlags flags;
|
2012-11-15 01:15:51 +08:00
|
|
|
if (helpers) flags |= BLOCK_BYREF_HAS_COPY_DISPOSE;
|
|
|
|
if (ByRefHasLifetime) {
|
|
|
|
if (HasByrefExtendedLayout) flags |= BLOCK_BYREF_LAYOUT_EXTENDED;
|
|
|
|
else switch (ByrefLifetime) {
|
|
|
|
case Qualifiers::OCL_Strong:
|
|
|
|
flags |= BLOCK_BYREF_LAYOUT_STRONG;
|
|
|
|
break;
|
|
|
|
case Qualifiers::OCL_Weak:
|
|
|
|
flags |= BLOCK_BYREF_LAYOUT_WEAK;
|
|
|
|
break;
|
|
|
|
case Qualifiers::OCL_ExplicitNone:
|
|
|
|
flags |= BLOCK_BYREF_LAYOUT_UNRETAINED;
|
|
|
|
break;
|
|
|
|
case Qualifiers::OCL_None:
|
|
|
|
if (!type->isObjCObjectPointerType() && !type->isBlockPointerType())
|
|
|
|
flags |= BLOCK_BYREF_LAYOUT_NON_OBJECT;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (CGM.getLangOpts().ObjCGCBitmapPrint) {
|
|
|
|
printf("\n Inline flag for BYREF variable layout (%d):", flags.getBitMask());
|
|
|
|
if (flags & BLOCK_BYREF_HAS_COPY_DISPOSE)
|
|
|
|
printf(" BLOCK_BYREF_HAS_COPY_DISPOSE");
|
|
|
|
if (flags & BLOCK_BYREF_LAYOUT_MASK) {
|
|
|
|
BlockFlags ThisFlag(flags.getBitMask() & BLOCK_BYREF_LAYOUT_MASK);
|
|
|
|
if (ThisFlag == BLOCK_BYREF_LAYOUT_EXTENDED)
|
|
|
|
printf(" BLOCK_BYREF_LAYOUT_EXTENDED");
|
|
|
|
if (ThisFlag == BLOCK_BYREF_LAYOUT_STRONG)
|
|
|
|
printf(" BLOCK_BYREF_LAYOUT_STRONG");
|
|
|
|
if (ThisFlag == BLOCK_BYREF_LAYOUT_WEAK)
|
|
|
|
printf(" BLOCK_BYREF_LAYOUT_WEAK");
|
|
|
|
if (ThisFlag == BLOCK_BYREF_LAYOUT_UNRETAINED)
|
|
|
|
printf(" BLOCK_BYREF_LAYOUT_UNRETAINED");
|
|
|
|
if (ThisFlag == BLOCK_BYREF_LAYOUT_NON_OBJECT)
|
|
|
|
printf(" BLOCK_BYREF_LAYOUT_NON_OBJECT");
|
|
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
}
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
storeHeaderField(llvm::ConstantInt::get(IntTy, flags.getBitMask()),
|
|
|
|
getIntSize(), "byref.flags");
|
2011-03-31 09:59:53 +08:00
|
|
|
|
2011-03-31 16:03:29 +08:00
|
|
|
CharUnits byrefSize = CGM.GetTargetTypeStoreSize(byrefType);
|
|
|
|
V = llvm::ConstantInt::get(IntTy, byrefSize.getQuantity());
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
storeHeaderField(V, getIntSize(), "byref.size");
|
2011-03-31 09:59:53 +08:00
|
|
|
|
2011-03-31 16:03:29 +08:00
|
|
|
if (helpers) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
storeHeaderField(helpers->CopyHelper, getPointerSize(),
|
|
|
|
"byref.copyHelper");
|
|
|
|
storeHeaderField(helpers->DisposeHelper, getPointerSize(),
|
|
|
|
"byref.disposeHelper");
|
2011-03-31 09:59:53 +08:00
|
|
|
}
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
|
2012-11-15 01:15:51 +08:00
|
|
|
if (ByRefHasLifetime && HasByrefExtendedLayout) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
auto layoutInfo = CGM.getObjCRuntime().BuildByrefLayout(CGM, type);
|
|
|
|
storeHeaderField(layoutInfo, getPointerSize(), "byref.layout");
|
2012-11-15 01:15:51 +08:00
|
|
|
}
|
2011-03-31 09:59:53 +08:00
|
|
|
}
|
|
|
|
|
2011-02-08 16:22:06 +08:00
|
|
|
void CodeGenFunction::BuildBlockRelease(llvm::Value *V, BlockFieldFlags flags) {
|
2010-07-16 08:00:15 +08:00
|
|
|
llvm::Value *F = CGM.getBlockObjectDispose();
|
2013-03-01 03:01:20 +08:00
|
|
|
llvm::Value *args[] = {
|
|
|
|
Builder.CreateBitCast(V, Int8PtrTy),
|
|
|
|
llvm::ConstantInt::get(Int32Ty, flags.getBitMask())
|
|
|
|
};
|
|
|
|
EmitNounwindRuntimeCall(F, args); // FIXME: throwing destructors?
|
2009-03-05 09:23:13 +08:00
|
|
|
}
|
2011-03-31 09:59:53 +08:00
|
|
|
|
|
|
|
namespace {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
/// Release a __block variable.
|
2015-08-19 06:40:54 +08:00
|
|
|
struct CallBlockRelease final : EHScopeStack::Cleanup {
|
2011-03-31 09:59:53 +08:00
|
|
|
llvm::Value *Addr;
|
|
|
|
CallBlockRelease(llvm::Value *Addr) : Addr(Addr) {}
|
|
|
|
|
2014-03-12 14:41:41 +08:00
|
|
|
void Emit(CodeGenFunction &CGF, Flags flags) override {
|
2011-06-16 07:02:42 +08:00
|
|
|
// Should we be passing FIELD_IS_WEAK here?
|
2011-03-31 09:59:53 +08:00
|
|
|
CGF.BuildBlockRelease(Addr, BLOCK_FIELD_IS_BYREF);
|
|
|
|
}
|
|
|
|
};
|
2015-10-07 07:40:43 +08:00
|
|
|
} // end anonymous namespace
|
2011-03-31 09:59:53 +08:00
|
|
|
|
|
|
|
/// Enter a cleanup to destroy a __block variable. Note that this
|
|
|
|
/// cleanup should be a no-op if the variable hasn't left the stack
|
|
|
|
/// yet; if a cleanup is required for the variable itself, that needs
|
|
|
|
/// to be done externally.
|
|
|
|
void CodeGenFunction::enterByrefCleanup(const AutoVarEmission &emission) {
|
|
|
|
// We don't enter this cleanup if we're in pure-GC mode.
|
2012-03-11 15:00:24 +08:00
|
|
|
if (CGM.getLangOpts().getGC() == LangOptions::GCOnly)
|
2011-03-31 09:59:53 +08:00
|
|
|
return;
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
EHStack.pushCleanup<CallBlockRelease>(NormalAndEHCleanup,
|
|
|
|
emission.Addr.getPointer());
|
2011-03-31 09:59:53 +08:00
|
|
|
}
|
2011-09-10 04:41:01 +08:00
|
|
|
|
|
|
|
/// Adjust the declaration of something from the blocks API.
|
|
|
|
static void configureBlocksRuntimeObject(CodeGenModule &CGM,
|
|
|
|
llvm::Constant *C) {
|
2014-05-09 08:08:36 +08:00
|
|
|
auto *GV = cast<llvm::GlobalValue>(C->stripPointerCasts());
|
2016-05-29 03:41:35 +08:00
|
|
|
|
|
|
|
if (CGM.getTarget().getTriple().isOSBinFormatCOFF()) {
|
|
|
|
IdentifierInfo &II = CGM.getContext().Idents.get(C->getName());
|
|
|
|
TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();
|
|
|
|
DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
|
|
|
|
|
2016-06-04 07:26:30 +08:00
|
|
|
assert((isa<llvm::Function>(C->stripPointerCasts()) ||
|
|
|
|
isa<llvm::GlobalVariable>(C->stripPointerCasts())) &&
|
|
|
|
"expected Function or GlobalVariable");
|
2016-05-29 03:41:35 +08:00
|
|
|
|
|
|
|
const NamedDecl *ND = nullptr;
|
|
|
|
for (const auto &Result : DC->lookup(&II))
|
|
|
|
if ((ND = dyn_cast<FunctionDecl>(Result)) ||
|
|
|
|
(ND = dyn_cast<VarDecl>(Result)))
|
|
|
|
break;
|
|
|
|
|
|
|
|
// TODO: support static blocks runtime
|
|
|
|
if (GV->isDeclaration() && (!ND || !ND->hasAttr<DLLExportAttr>())) {
|
|
|
|
GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
|
|
|
|
GV->setLinkage(llvm::GlobalValue::ExternalLinkage);
|
|
|
|
} else {
|
|
|
|
GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
|
|
|
|
GV->setLinkage(llvm::GlobalValue::ExternalLinkage);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-15 02:19:26 +08:00
|
|
|
if (CGM.getLangOpts().BlocksRuntimeOptional && GV->isDeclaration() &&
|
|
|
|
GV->hasExternalLinkage())
|
2011-09-10 04:41:01 +08:00
|
|
|
GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
|
2018-03-15 02:19:26 +08:00
|
|
|
|
|
|
|
CGM.setDSOLocal(GV);
|
2011-09-10 04:41:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
llvm::Constant *CodeGenModule::getBlockObjectDispose() {
|
|
|
|
if (BlockObjectDispose)
|
|
|
|
return BlockObjectDispose;
|
|
|
|
|
|
|
|
llvm::Type *args[] = { Int8PtrTy, Int32Ty };
|
|
|
|
llvm::FunctionType *fty
|
|
|
|
= llvm::FunctionType::get(VoidTy, args, false);
|
|
|
|
BlockObjectDispose = CreateRuntimeFunction(fty, "_Block_object_dispose");
|
|
|
|
configureBlocksRuntimeObject(*this, BlockObjectDispose);
|
|
|
|
return BlockObjectDispose;
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm::Constant *CodeGenModule::getBlockObjectAssign() {
|
|
|
|
if (BlockObjectAssign)
|
|
|
|
return BlockObjectAssign;
|
|
|
|
|
|
|
|
llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, Int32Ty };
|
|
|
|
llvm::FunctionType *fty
|
|
|
|
= llvm::FunctionType::get(VoidTy, args, false);
|
|
|
|
BlockObjectAssign = CreateRuntimeFunction(fty, "_Block_object_assign");
|
|
|
|
configureBlocksRuntimeObject(*this, BlockObjectAssign);
|
|
|
|
return BlockObjectAssign;
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm::Constant *CodeGenModule::getNSConcreteGlobalBlock() {
|
|
|
|
if (NSConcreteGlobalBlock)
|
|
|
|
return NSConcreteGlobalBlock;
|
|
|
|
|
|
|
|
NSConcreteGlobalBlock = GetOrCreateLLVMGlobal("_NSConcreteGlobalBlock",
|
2014-05-21 13:09:00 +08:00
|
|
|
Int8PtrTy->getPointerTo(),
|
|
|
|
nullptr);
|
2011-09-10 04:41:01 +08:00
|
|
|
configureBlocksRuntimeObject(*this, NSConcreteGlobalBlock);
|
|
|
|
return NSConcreteGlobalBlock;
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm::Constant *CodeGenModule::getNSConcreteStackBlock() {
|
|
|
|
if (NSConcreteStackBlock)
|
|
|
|
return NSConcreteStackBlock;
|
|
|
|
|
|
|
|
NSConcreteStackBlock = GetOrCreateLLVMGlobal("_NSConcreteStackBlock",
|
2014-05-21 13:09:00 +08:00
|
|
|
Int8PtrTy->getPointerTo(),
|
|
|
|
nullptr);
|
2011-09-10 04:41:01 +08:00
|
|
|
configureBlocksRuntimeObject(*this, NSConcreteStackBlock);
|
2016-05-29 03:41:35 +08:00
|
|
|
return NSConcreteStackBlock;
|
2011-09-10 04:41:01 +08:00
|
|
|
}
|