2015-10-07 07:40:43 +08:00
|
|
|
//===--- CGBlocks.cpp - Emit LLVM Code for declarations ---------*- C++ -*-===//
|
2009-02-12 08:39:25 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2009-02-12 08:39:25 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This contains code to emit blocks.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "CGBlocks.h"
|
2018-08-10 23:09:24 +08:00
|
|
|
#include "CGCXXABI.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"
|
2019-12-10 08:11:56 +08:00
|
|
|
#include "clang/AST/Attr.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"
|
2013-01-02 19:45:17 +08:00
|
|
|
#include "llvm/IR/DataLayout.h"
|
|
|
|
#include "llvm/IR/Module.h"
|
2018-08-10 23:09:24 +08:00
|
|
|
#include "llvm/Support/ScopedPrinter.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),
|
2018-08-10 23:09:24 +08:00
|
|
|
CapturesNonExternalType(false), LocalAddress(Address::invalid()),
|
2020-06-04 07:41:50 +08:00
|
|
|
StructureType(nullptr), Block(block) {
|
2014-05-21 13:09:00 +08:00
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2018-08-17 23:46:07 +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,
|
|
|
|
NonTrivialCStruct,
|
|
|
|
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 CopyKind, DisposeKind;
|
|
|
|
BlockFieldFlags CopyFlags, DisposeFlags;
|
|
|
|
const BlockDecl::Capture *CI;
|
|
|
|
const CGBlockInfo::Capture *Capture;
|
|
|
|
|
|
|
|
BlockCaptureManagedEntity(BlockCaptureEntityKind CopyType,
|
|
|
|
BlockCaptureEntityKind DisposeType,
|
|
|
|
BlockFieldFlags CopyFlags,
|
|
|
|
BlockFieldFlags DisposeFlags,
|
|
|
|
const BlockDecl::Capture &CI,
|
|
|
|
const CGBlockInfo::Capture &Capture)
|
|
|
|
: CopyKind(CopyType), DisposeKind(DisposeType), CopyFlags(CopyFlags),
|
|
|
|
DisposeFlags(DisposeFlags), CI(&CI), Capture(&Capture) {}
|
|
|
|
|
|
|
|
bool operator<(const BlockCaptureManagedEntity &Other) const {
|
|
|
|
return Capture->getOffset() < Other.Capture->getOffset();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class CaptureStrKind {
|
|
|
|
// String for the copy helper.
|
|
|
|
CopyHelper,
|
|
|
|
// String for the dispose helper.
|
|
|
|
DisposeHelper,
|
|
|
|
// Merge the strings for the copy helper and dispose helper.
|
|
|
|
Merged
|
|
|
|
};
|
|
|
|
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
|
|
static void findBlockCapturedManagedEntities(
|
|
|
|
const CGBlockInfo &BlockInfo, const LangOptions &LangOpts,
|
|
|
|
SmallVectorImpl<BlockCaptureManagedEntity> &ManagedCaptures);
|
|
|
|
|
|
|
|
static std::string getBlockCaptureStr(const BlockCaptureManagedEntity &E,
|
|
|
|
CaptureStrKind StrKind,
|
|
|
|
CharUnits BlockAlignment,
|
|
|
|
CodeGenModule &CGM);
|
|
|
|
|
|
|
|
static std::string getBlockDescriptorName(const CGBlockInfo &BlockInfo,
|
|
|
|
CodeGenModule &CGM) {
|
|
|
|
std::string Name = "__block_descriptor_";
|
|
|
|
Name += llvm::to_string(BlockInfo.BlockSize.getQuantity()) + "_";
|
|
|
|
|
|
|
|
if (BlockInfo.needsCopyDisposeHelpers()) {
|
|
|
|
if (CGM.getLangOpts().Exceptions)
|
|
|
|
Name += "e";
|
|
|
|
if (CGM.getCodeGenOpts().ObjCAutoRefCountExceptions)
|
|
|
|
Name += "a";
|
|
|
|
Name += llvm::to_string(BlockInfo.BlockAlign.getQuantity()) + "_";
|
|
|
|
|
|
|
|
SmallVector<BlockCaptureManagedEntity, 4> ManagedCaptures;
|
|
|
|
findBlockCapturedManagedEntities(BlockInfo, CGM.getContext().getLangOpts(),
|
|
|
|
ManagedCaptures);
|
|
|
|
|
|
|
|
for (const BlockCaptureManagedEntity &E : ManagedCaptures) {
|
|
|
|
Name += llvm::to_string(E.Capture->getOffset().getQuantity());
|
|
|
|
|
|
|
|
if (E.CopyKind == E.DisposeKind) {
|
|
|
|
// If CopyKind and DisposeKind are the same, merge the capture
|
|
|
|
// information.
|
|
|
|
assert(E.CopyKind != BlockCaptureEntityKind::None &&
|
|
|
|
"shouldn't see BlockCaptureManagedEntity that is None");
|
|
|
|
Name += getBlockCaptureStr(E, CaptureStrKind::Merged,
|
|
|
|
BlockInfo.BlockAlign, CGM);
|
|
|
|
} else {
|
|
|
|
// If CopyKind and DisposeKind are not the same, which can happen when
|
|
|
|
// either Kind is None or the captured object is a __strong block,
|
|
|
|
// concatenate the copy and dispose strings.
|
|
|
|
Name += getBlockCaptureStr(E, CaptureStrKind::CopyHelper,
|
|
|
|
BlockInfo.BlockAlign, CGM);
|
|
|
|
Name += getBlockCaptureStr(E, CaptureStrKind::DisposeHelper,
|
|
|
|
BlockInfo.BlockAlign, CGM);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Name += "_";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string TypeAtEncoding =
|
|
|
|
CGM.getContext().getObjCEncodingForBlock(BlockInfo.getBlockExpr());
|
2018-12-30 01:28:30 +08:00
|
|
|
/// Replace occurrences of '@' with '\1'. '@' is reserved on ELF platforms as
|
|
|
|
/// a separator between symbol name and symbol version.
|
|
|
|
std::replace(TypeAtEncoding.begin(), TypeAtEncoding.end(), '@', '\1');
|
2018-08-17 23:46:07 +08:00
|
|
|
Name += "e" + llvm::to_string(TypeAtEncoding.size()) + "_" + TypeAtEncoding;
|
|
|
|
Name += "l" + CGM.getObjCRuntime().getRCBlockLayoutStr(CGM, BlockInfo);
|
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
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.
|
2018-04-06 23:14:32 +08:00
|
|
|
/// Its definition will have 4 (or optionally 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.
|
Misc typos fixes in ./lib folder
Summary: Found via `codespell -q 3 -I ../clang-whitelist.txt -L uint,importd,crasher,gonna,cant,ue,ons,orign,ned`
Reviewers: teemperor
Reviewed By: teemperor
Subscribers: teemperor, jholewinski, jvesely, nhaehnle, whisperity, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D55475
llvm-svn: 348755
2018-12-10 20:37:46 +08:00
|
|
|
/// void *destroy_func_decl; // optional 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)
|
2018-07-31 03:24:48 +08:00
|
|
|
i8p =
|
2014-08-14 17:37:50 +08:00
|
|
|
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
|
|
|
|
2018-08-17 23:46:07 +08:00
|
|
|
std::string descName;
|
|
|
|
|
|
|
|
// If an equivalent block descriptor global variable exists, return it.
|
2018-10-31 04:31:30 +08:00
|
|
|
if (C.getLangOpts().ObjC &&
|
2018-08-17 23:46:07 +08:00
|
|
|
CGM.getLangOpts().getGC() == LangOptions::NonGC) {
|
|
|
|
descName = getBlockDescriptorName(blockInfo, CGM);
|
|
|
|
if (llvm::GlobalValue *desc = CGM.getModule().getNamedValue(descName))
|
|
|
|
return llvm::ConstantExpr::getBitCast(desc,
|
|
|
|
CGM.getBlockDescriptorType());
|
|
|
|
}
|
|
|
|
|
|
|
|
// If there isn't an equivalent block descriptor global variable, create a new
|
|
|
|
// one.
|
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.
|
2018-08-17 23:46:07 +08:00
|
|
|
bool hasInternalHelper = false;
|
2018-07-21 01:10:32 +08:00
|
|
|
if (blockInfo.needsCopyDisposeHelpers()) {
|
2009-02-14 00:19:19 +08:00
|
|
|
// copy_func_helper_decl
|
2018-08-17 23:46:07 +08:00
|
|
|
llvm::Constant *copyHelper = buildCopyHelper(CGM, blockInfo);
|
|
|
|
elements.add(copyHelper);
|
2009-02-14 00:19:19 +08:00
|
|
|
|
|
|
|
// destroy_func_decl
|
2018-08-17 23:46:07 +08:00
|
|
|
llvm::Constant *disposeHelper = buildDisposeHelper(CGM, blockInfo);
|
|
|
|
elements.add(disposeHelper);
|
|
|
|
|
|
|
|
if (cast<llvm::Function>(copyHelper->getOperand(0))->hasInternalLinkage() ||
|
|
|
|
cast<llvm::Function>(disposeHelper->getOperand(0))
|
|
|
|
->hasInternalLinkage())
|
|
|
|
hasInternalHelper = true;
|
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));
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
// GC layout.
|
2018-10-31 04:31:30 +08:00
|
|
|
if (C.getLangOpts().ObjC) {
|
2012-10-28 05:10:38 +08:00
|
|
|
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
|
|
|
|
2018-08-17 23:46:07 +08:00
|
|
|
llvm::GlobalValue::LinkageTypes linkage;
|
|
|
|
if (descName.empty()) {
|
|
|
|
linkage = llvm::GlobalValue::InternalLinkage;
|
|
|
|
descName = "__block_descriptor_tmp";
|
|
|
|
} else if (hasInternalHelper) {
|
|
|
|
// If either the copy helper or the dispose helper has internal linkage,
|
|
|
|
// the block descriptor must have internal linkage too.
|
|
|
|
linkage = llvm::GlobalValue::InternalLinkage;
|
|
|
|
} else {
|
|
|
|
linkage = llvm::GlobalValue::LinkOnceODRLinkage;
|
|
|
|
}
|
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
llvm::GlobalVariable *global =
|
2018-08-17 23:46:07 +08:00
|
|
|
elements.finishAndCreateGlobal(descName, CGM.getPointerAlign(),
|
|
|
|
/*constant*/ true, linkage, AddrSpace);
|
|
|
|
|
|
|
|
if (linkage == llvm::GlobalValue::LinkOnceODRLinkage) {
|
2019-03-31 19:22:26 +08:00
|
|
|
if (CGM.supportsCOMDAT())
|
|
|
|
global->setComdat(CGM.getModule().getOrInsertComdat(descName));
|
2018-08-17 23:46:07 +08:00
|
|
|
global->setVisibility(llvm::GlobalValue::HiddenVisibility);
|
|
|
|
global->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
|
|
|
|
}
|
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.
|
2018-07-21 01:10:32 +08:00
|
|
|
/// 23. BLOCK_IS_NOESCAPE - indicates that the block is non-escaping
|
2011-02-07 18:33:21 +08:00
|
|
|
/// 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-10-02 21:02:24 +08:00
|
|
|
// The header is basically 'struct { int; int; generic void *;
|
2017-10-05 04:32:17 +08:00
|
|
|
// custom_fields; }'. Assert that struct is packed.
|
2018-10-02 21:02:24 +08:00
|
|
|
auto GenericAS =
|
|
|
|
CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic);
|
|
|
|
auto GenPtrAlign =
|
|
|
|
CharUnits::fromQuantity(CGM.getTarget().getPointerAlign(GenericAS) / 8);
|
|
|
|
auto GenPtrSize =
|
|
|
|
CharUnits::fromQuantity(CGM.getTarget().getPointerWidth(GenericAS) / 8);
|
|
|
|
assert(CGM.getIntSize() <= GenPtrSize);
|
|
|
|
assert(CGM.getIntAlign() <= GenPtrAlign);
|
|
|
|
assert((2 * CGM.getIntSize()).isMultipleOf(GenPtrAlign));
|
2017-10-05 04:32:17 +08:00
|
|
|
elementTypes.push_back(CGM.IntTy); /* total size */
|
|
|
|
elementTypes.push_back(CGM.IntTy); /* align */
|
2018-10-02 21:02:24 +08:00
|
|
|
elementTypes.push_back(
|
|
|
|
CGM.getOpenCLRuntime()
|
|
|
|
.getGenericVoidPointerType()); /* invoke function */
|
|
|
|
unsigned Offset =
|
|
|
|
2 * CGM.getIntSize().getQuantity() + GenPtrSize.getQuantity();
|
|
|
|
unsigned BlockAlign = GenPtrAlign.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 *; }'.
|
2018-04-06 23:14:32 +08:00
|
|
|
// Assert that the struct is packed.
|
2017-10-05 04:32:17 +08:00
|
|
|
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();
|
2018-10-02 05:51:28 +08:00
|
|
|
// If the captured variable is a non-escaping __block variable, the field
|
|
|
|
// type is the reference type. If the variable is a __block variable that
|
|
|
|
// already has a reference type, the field type is the variable's type.
|
|
|
|
return VD->isNonEscapingByref() ?
|
|
|
|
CGF.getContext().getLValueReferenceType(VD->getType()) : VD->getType();
|
2017-02-14 14:46:55 +08:00
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
2018-10-31 04:31:30 +08:00
|
|
|
else if (C.getLangOpts().ObjC &&
|
2012-11-02 02:32:55 +08:00
|
|
|
CGM.getLangOpts().getGC() == LangOptions::NonGC)
|
|
|
|
info.HasCapturedVariableLayout = true;
|
2018-07-31 03:24:48 +08:00
|
|
|
|
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");
|
2019-01-11 09:54:53 +08:00
|
|
|
QualType thisType = cast<CXXMethodDecl>(CGF->CurFuncDecl)->getThisType();
|
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);
|
2020-08-24 16:19:29 +08:00
|
|
|
auto TInfo = CGM.getContext().getTypeInfoInChars(thisType);
|
|
|
|
maxFieldAlign = std::max(maxFieldAlign, TInfo.Align);
|
2010-05-20 09:18:31 +08:00
|
|
|
|
2020-08-24 16:19:29 +08:00
|
|
|
layout.push_back(BlockLayoutChunk(TInfo.Align, TInfo.Width,
|
2013-01-17 08:25:06 +08:00
|
|
|
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
|
|
|
|
2018-10-02 05:51:28 +08:00
|
|
|
if (CI.isEscapingByref()) {
|
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
|
|
|
|
2018-08-22 21:41:19 +08:00
|
|
|
// Since a __block variable cannot be captured by lambdas, its type and
|
|
|
|
// the capture field type should always match.
|
2020-09-16 19:11:29 +08:00
|
|
|
assert(CGF && getCaptureFieldType(*CGF, CI) == variable->getType() &&
|
2018-08-22 21:41:19 +08:00
|
|
|
"capture type differs from the variable 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
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-08-22 21:41:19 +08:00
|
|
|
QualType VT = getCaptureFieldType(*CGF, CI);
|
|
|
|
|
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.
|
2018-08-22 21:41:19 +08:00
|
|
|
Qualifiers::ObjCLifetime lifetime = VT.getObjCLifetime();
|
2013-01-17 08:25:06 +08:00
|
|
|
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.
|
2018-08-22 21:41:19 +08:00
|
|
|
} else if (VT->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.
|
2018-08-22 21:41:19 +08:00
|
|
|
if (VT->isObjCInertUnsafeUnretainedType()) {
|
2015-11-19 10:28:03 +08:00
|
|
|
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-08-22 21:41:19 +08:00
|
|
|
if (!VT->getAsCXXRecordDecl()->isExternallyVisible())
|
2018-08-10 23:09:24 +08:00
|
|
|
info.CapturesNonExternalType = true;
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2018-02-28 15:15:55 +08:00
|
|
|
// So do C structs that require non-trivial copy construction or
|
|
|
|
// destruction.
|
2018-08-22 21:41:19 +08:00
|
|
|
} else if (VT.isNonTrivialToPrimitiveCopy() == QualType::PCK_Struct ||
|
|
|
|
VT.isDestructedType() == QualType::DK_nontrivial_c_struct) {
|
2018-02-28 15:15:55 +08:00
|
|
|
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) {
|
2018-08-22 21:41:19 +08:00
|
|
|
if (const CXXRecordDecl *record = VT->getAsCXXRecordDecl()) {
|
2011-02-07 18:33:21 +08:00
|
|
|
if (!record->hasTrivialDestructor()) {
|
|
|
|
info.HasCXXObject = true;
|
|
|
|
info.NeedsCopyDispose = true;
|
2018-08-10 23:09:24 +08:00
|
|
|
if (!record->isExternallyVisible())
|
|
|
|
info.CapturesNonExternalType = 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
|
|
|
}
|
|
|
|
|
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);
|
2018-07-31 03:24:48 +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);
|
2018-07-31 03:24:48 +08:00
|
|
|
|
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.
|
2019-04-24 22:43:05 +08:00
|
|
|
llvm::stable_sort(layout);
|
2018-07-31 03:24:48 +08:00
|
|
|
|
2012-12-05 01:20:57 +08:00
|
|
|
// Needed for blocks layout info.
|
|
|
|
info.BlockHeaderForcedGapOffset = info.BlockSize;
|
|
|
|
info.BlockHeaderForcedGapSize = CharUnits::Zero();
|
2018-07-31 03:24:48 +08:00
|
|
|
|
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));
|
2018-07-31 03:24:48 +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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 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.
|
2020-06-04 07:41:50 +08:00
|
|
|
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.
|
2020-06-04 07:41:50 +08:00
|
|
|
if (llvm::Constant *Block = CGM.getAddrOfGlobalBlockIfEmitted(blockExpr))
|
2016-12-22 10:50:20 +08:00
|
|
|
return Block;
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2020-06-04 07:41:50 +08:00
|
|
|
CGBlockInfo blockInfo(blockExpr->getBlockDecl(), CurFn->getName());
|
|
|
|
computeBlockInfo(CGM, this, blockInfo);
|
|
|
|
blockInfo.BlockExpression = blockExpr;
|
|
|
|
if (!blockInfo.CanBeGlobal)
|
|
|
|
blockInfo.LocalAddress = CreateTempAlloca(blockInfo.StructureType,
|
|
|
|
blockInfo.BlockAlign, "block");
|
|
|
|
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;
|
2018-10-02 21:02:24 +08:00
|
|
|
auto GenVoidPtrTy =
|
|
|
|
IsOpenCL ? CGM.getOpenCLRuntime().getGenericVoidPointerType() : VoidPtrTy;
|
|
|
|
LangAS GenVoidPtrAddr = IsOpenCL ? LangAS::opencl_generic : LangAS::Default;
|
|
|
|
auto GenVoidPtrSize = CharUnits::fromQuantity(
|
|
|
|
CGM.getTarget().getPointerWidth(
|
|
|
|
CGM.getContext().getTargetAddressSpace(GenVoidPtrAddr)) /
|
|
|
|
8);
|
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);
|
2018-10-02 21:02:24 +08:00
|
|
|
auto *blockFn = llvm::ConstantExpr::getPointerCast(InvokeFn, GenVoidPtrTy);
|
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) {
|
2018-07-21 01:10:32 +08:00
|
|
|
// If the block is non-escaping, set field 'isa 'to NSConcreteGlobalBlock
|
|
|
|
// and set the BLOCK_IS_GLOBAL bit of field 'flags'. Copying a non-escaping
|
|
|
|
// block just returns the original block and releasing it is a no-op.
|
|
|
|
llvm::Constant *blockISA = blockInfo.getBlockDecl()->doesNotEscape()
|
|
|
|
? CGM.getNSConcreteGlobalBlock()
|
|
|
|
: CGM.getNSConcreteStackBlock();
|
|
|
|
isa = llvm::ConstantExpr::getBitCast(blockISA, VoidPtrTy);
|
2017-10-05 04:32:17 +08:00
|
|
|
|
|
|
|
// 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;
|
2018-07-21 01:10:32 +08:00
|
|
|
if (blockInfo.needsCopyDisposeHelpers())
|
2017-10-05 04:32:17 +08:00
|
|
|
flags |= BLOCK_HAS_COPY_DISPOSE;
|
|
|
|
if (blockInfo.HasCXXObject)
|
|
|
|
flags |= BLOCK_HAS_CXX_OBJ;
|
|
|
|
if (blockInfo.UsesStret)
|
|
|
|
flags |= BLOCK_USE_STRET;
|
2018-07-21 01:10:32 +08:00
|
|
|
if (blockInfo.getBlockDecl()->doesNotEscape())
|
|
|
|
flags |= BLOCK_IS_NOESCAPE | BLOCK_IS_GLOBAL;
|
2017-10-05 04:32:17 +08:00
|
|
|
}
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2019-02-10 06:22:28 +08:00
|
|
|
auto projectField = [&](unsigned index, const Twine &name) -> Address {
|
|
|
|
return Builder.CreateStructGEP(blockAddr, index, name);
|
|
|
|
};
|
|
|
|
auto storeField = [&](llvm::Value *value, unsigned index, const Twine &name) {
|
|
|
|
Builder.CreateStore(value, projectField(index, name));
|
|
|
|
};
|
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
|
|
|
|
|
|
|
// Initialize the block header.
|
|
|
|
{
|
|
|
|
// We assume all the header fields are densely packed.
|
|
|
|
unsigned index = 0;
|
|
|
|
CharUnits offset;
|
2019-02-10 06:22:28 +08:00
|
|
|
auto addHeaderField = [&](llvm::Value *value, CharUnits size,
|
|
|
|
const Twine &name) {
|
|
|
|
storeField(value, index, name);
|
|
|
|
offset += size;
|
|
|
|
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
|
|
|
|
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-10-02 21:02:24 +08:00
|
|
|
addHeaderField(blockFn, GenVoidPtrSize, "block.invoke");
|
|
|
|
if (!IsOpenCL)
|
2017-10-05 04:32:17 +08:00
|
|
|
addHeaderField(descriptor, getPointerSize(), "block.descriptor");
|
2018-10-02 21:02:24 +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()) {
|
2019-02-10 06:22:28 +08:00
|
|
|
Address addr =
|
|
|
|
projectField(blockInfo.CXXThisIndex, "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**.
|
2019-02-10 06:22:28 +08:00
|
|
|
Address blockField = projectField(capture.getIndex(), "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();
|
2018-10-02 05:51:28 +08:00
|
|
|
} else if (CI.isEscapingByref()) {
|
2016-05-05 02:40:33 +08:00
|
|
|
if (BlockInfo && CI.isNested()) {
|
|
|
|
// We need to use the capture from the enclosing block.
|
|
|
|
const CGBlockInfo::Capture &enclosingCapture =
|
|
|
|
BlockInfo->getCapture(variable);
|
|
|
|
|
2018-04-06 23:14:32 +08:00
|
|
|
// This is a [[type]]*, except that a byref entry will just be an i8**.
|
2016-05-05 02:40:33 +08:00
|
|
|
src = Builder.CreateStructGEP(LoadBlockStruct(),
|
|
|
|
enclosingCapture.getIndex(),
|
|
|
|
"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 {
|
2018-12-21 22:10:18 +08:00
|
|
|
DeclRefExpr declRef(getContext(), const_cast<VarDecl *>(variable),
|
2016-05-05 02:40:33 +08:00
|
|
|
/*RefersToEnclosingVariableOrCapture*/ CI.isNested(),
|
|
|
|
type.getNonReferenceType(), VK_LValue,
|
|
|
|
SourceLocation());
|
2019-12-04 07:17:01 +08:00
|
|
|
src = EmitDeclRefLValue(&declRef).getAddress(*this);
|
2016-05-05 02:40:33 +08:00
|
|
|
};
|
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.
|
2018-10-02 05:51:28 +08:00
|
|
|
if (CI.isEscapingByref()) {
|
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,
|
2018-04-06 04:52:58 +08:00
|
|
|
AggValueSlot::IsNotAliased,
|
|
|
|
AggValueSlot::DoesNotOverlap);
|
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.
|
2018-12-21 22:10:18 +08:00
|
|
|
DeclRefExpr declRef(getContext(), const_cast<VarDecl *>(variable),
|
2015-01-12 18:17:46 +08:00
|
|
|
/*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,
|
2020-09-12 22:54:14 +08:00
|
|
|
&declRef, VK_RValue, FPOptionsOverride());
|
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
|
|
|
|
2020-06-04 07:41:50 +08:00
|
|
|
// Push a cleanup for the capture if necessary.
|
|
|
|
if (!blockInfo.NeedsCopyDispose)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Ignore __block captures; there's nothing special in the on-stack block
|
|
|
|
// that we need to do for them.
|
|
|
|
if (CI.isByRef())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Ignore objects that aren't destructed.
|
|
|
|
QualType::DestructionKind dtorKind = type.isDestructedType();
|
|
|
|
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.
|
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
if (type.isConstQualified() &&
|
|
|
|
type.getObjCLifetime() == Qualifiers::OCL_Strong &&
|
|
|
|
CGM.getCodeGenOpts().OptimizationLevel != 0) {
|
|
|
|
assert(CGM.getLangOpts().ObjCAutoRefCount &&
|
|
|
|
"expected ObjC ARC to be enabled");
|
|
|
|
destroyer = emitARCIntrinsicUse;
|
|
|
|
} else if (dtorKind == QualType::DK_objc_strong_lifetime) {
|
|
|
|
destroyer = destroyARCStrongImprecise;
|
|
|
|
} else {
|
|
|
|
destroyer = getDestroyer(dtorKind);
|
2011-06-16 07:02:42 +08:00
|
|
|
}
|
2020-06-04 07:41:50 +08:00
|
|
|
|
|
|
|
CleanupKind cleanupKind = NormalCleanup;
|
|
|
|
bool useArrayEHCleanup = needsEHCleanup(dtorKind);
|
|
|
|
if (useArrayEHCleanup)
|
|
|
|
cleanupKind = NormalAndEHCleanup;
|
|
|
|
|
|
|
|
// Extend the lifetime of the capture to the end of the scope enclosing the
|
|
|
|
// block expression except when the block decl is in the list of RetExpr's
|
|
|
|
// cleanup objects, in which case its lifetime ends after the full
|
|
|
|
// expression.
|
|
|
|
auto IsBlockDeclInRetExpr = [&]() {
|
|
|
|
auto *EWC = llvm::dyn_cast_or_null<ExprWithCleanups>(RetExpr);
|
|
|
|
if (EWC)
|
|
|
|
for (auto &C : EWC->getObjects())
|
|
|
|
if (auto *BD = C.dyn_cast<BlockDecl *>())
|
|
|
|
if (BD == blockDecl)
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
|
|
|
if (IsBlockDeclInRetExpr())
|
|
|
|
pushDestroy(cleanupKind, blockField, type, destroyer, useArrayEHCleanup);
|
|
|
|
else
|
|
|
|
pushLifetimeExtendedDestroy(cleanupKind, blockField, type, destroyer,
|
|
|
|
useArrayEHCleanup);
|
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() {
|
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-10-02 21:02:24 +08:00
|
|
|
if (getLangOpts().OpenCL) {
|
|
|
|
// struct __opencl_block_literal_generic {
|
|
|
|
// int __size;
|
|
|
|
// int __align;
|
|
|
|
// __generic void *__invoke;
|
|
|
|
// /* custom fields */
|
|
|
|
// };
|
|
|
|
SmallVector<llvm::Type *, 8> StructFields(
|
|
|
|
{IntTy, IntTy, getOpenCLRuntime().getGenericVoidPointerType()});
|
|
|
|
if (auto *Helper = getTargetCodeGenInfo().getTargetOpenCLBlockHelper()) {
|
|
|
|
for (auto I : Helper->getCustomFieldTypes())
|
|
|
|
StructFields.push_back(I);
|
|
|
|
}
|
|
|
|
GenericBlockLiteralType = llvm::StructType::create(
|
|
|
|
StructFields, "struct.__opencl_block_literal_generic");
|
|
|
|
} else {
|
|
|
|
// 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) {
|
2019-10-04 23:01:54 +08:00
|
|
|
const auto *BPT = E->getCallee()->getType()->castAs<BlockPointerType>();
|
2016-10-27 07:46:34 +08:00
|
|
|
llvm::Value *BlockPtr = EmitScalarExpr(E->getCallee());
|
2019-02-21 19:02:10 +08:00
|
|
|
llvm::Type *GenBlockTy = CGM.getGenericBlockLiteralType();
|
|
|
|
llvm::Value *Func = nullptr;
|
|
|
|
QualType FnType = BPT->getPointeeType();
|
|
|
|
ASTContext &Ctx = getContext();
|
2009-02-12 08:39:25 +08:00
|
|
|
CallArgList Args;
|
2017-01-27 23:11:34 +08:00
|
|
|
|
|
|
|
if (getLangOpts().OpenCL) {
|
2019-02-21 19:02:10 +08:00
|
|
|
// For OpenCL, BlockPtr is already casted to generic block literal.
|
|
|
|
|
|
|
|
// First argument of a block call is a generic block literal casted to
|
|
|
|
// generic void pointer, i.e. i8 addrspace(4)*
|
|
|
|
llvm::Value *BlockDescriptor = Builder.CreatePointerCast(
|
|
|
|
BlockPtr, CGM.getOpenCLRuntime().getGenericVoidPointerType());
|
|
|
|
QualType VoidPtrQualTy = Ctx.getPointerType(
|
|
|
|
Ctx.getAddrSpaceQualType(Ctx.VoidTy, LangAS::opencl_generic));
|
|
|
|
Args.add(RValue::get(BlockDescriptor), VoidPtrQualTy);
|
|
|
|
// And the rest of the arguments.
|
|
|
|
EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), E->arguments());
|
|
|
|
|
|
|
|
// We *can* call the block directly unless it is a function argument.
|
|
|
|
if (!isa<ParmVarDecl>(E->getCalleeDecl()))
|
|
|
|
Func = CGM.getOpenCLRuntime().getInvokeFunction(E->getCallee());
|
|
|
|
else {
|
|
|
|
llvm::Value *FuncPtr = Builder.CreateStructGEP(GenBlockTy, BlockPtr, 2);
|
|
|
|
Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign());
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Bitcast the block literal to a generic block literal.
|
|
|
|
BlockPtr = Builder.CreatePointerCast(
|
|
|
|
BlockPtr, llvm::PointerType::get(GenBlockTy, 0), "block.literal");
|
|
|
|
// Get pointer to the block invoke function
|
|
|
|
llvm::Value *FuncPtr = Builder.CreateStructGEP(GenBlockTy, BlockPtr, 3);
|
|
|
|
|
|
|
|
// First argument is a block literal casted to a void pointer
|
|
|
|
BlockPtr = Builder.CreatePointerCast(BlockPtr, VoidPtrTy);
|
|
|
|
Args.add(RValue::get(BlockPtr), Ctx.VoidPtrTy);
|
|
|
|
// And the rest of the arguments.
|
|
|
|
EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), E->arguments());
|
|
|
|
|
|
|
|
// Load the function.
|
|
|
|
Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign());
|
2017-01-27 23:11:34 +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
|
|
|
|
2018-10-02 05:51:28 +08:00
|
|
|
Address CodeGenFunction::GetAddrOfBlockDecl(const VarDecl *variable) {
|
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
|
|
|
|
2019-02-10 06:22:28 +08:00
|
|
|
Address addr = Builder.CreateStructGEP(LoadBlockStruct(), capture.getIndex(),
|
|
|
|
"block.capture.addr");
|
2010-05-20 09:18:31 +08:00
|
|
|
|
2018-10-02 05:51:28 +08:00
|
|
|
if (variable->isEscapingByref()) {
|
2011-02-07 18:33:21 +08:00
|
|
|
// 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
|
|
|
|
2018-10-02 05:51:28 +08:00
|
|
|
assert((!variable->isNonEscapingByref() ||
|
|
|
|
capture.fieldType()->isReferenceType()) &&
|
|
|
|
"the capture field of a non-escaping variable should have a "
|
|
|
|
"reference type");
|
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;
|
2018-08-09 16:02:42 +08:00
|
|
|
bool IsWindows = CGM.getTarget().getTriple().isOSWindows();
|
2017-10-05 04:32:17 +08:00
|
|
|
if (!IsOpenCL) {
|
|
|
|
// isa
|
2018-08-09 16:02:42 +08:00
|
|
|
if (IsWindows)
|
|
|
|
fields.addNullPointer(CGM.Int8PtrPtrTy);
|
|
|
|
else
|
|
|
|
fields.add(CGM.getNSConcreteGlobalBlock());
|
2017-10-05 04:32:17 +08:00
|
|
|
|
|
|
|
// __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);
|
|
|
|
} else {
|
|
|
|
fields.addInt(CGM.IntTy, blockInfo.BlockSize.getQuantity());
|
|
|
|
fields.addInt(CGM.IntTy, blockInfo.BlockAlign.getQuantity());
|
|
|
|
}
|
2009-02-13 23:32:32 +08:00
|
|
|
|
2018-10-02 21:02:24 +08:00
|
|
|
// Function
|
|
|
|
fields.add(blockFn);
|
|
|
|
|
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);
|
|
|
|
|
2019-06-15 06:06:28 +08:00
|
|
|
llvm::GlobalVariable *literal = fields.finishAndCreateGlobal(
|
2017-01-27 23:11:34 +08:00
|
|
|
"__block_literal_global", blockInfo.BlockAlign,
|
2018-08-09 16:02:42 +08:00
|
|
|
/*constant*/ !IsWindows, llvm::GlobalVariable::InternalLinkage, AddrSpace);
|
|
|
|
|
2019-06-15 06:06:28 +08:00
|
|
|
literal->addAttribute("objc_arc_inert");
|
|
|
|
|
2018-08-09 16:02:42 +08:00
|
|
|
// Windows does not allow globals to be initialised to point to globals in
|
|
|
|
// different DLLs. Any such variables must run code to initialise them.
|
|
|
|
if (IsWindows) {
|
|
|
|
auto *Init = llvm::Function::Create(llvm::FunctionType::get(CGM.VoidTy,
|
|
|
|
{}), llvm::GlobalValue::InternalLinkage, ".block_isa_init",
|
|
|
|
&CGM.getModule());
|
|
|
|
llvm::IRBuilder<> b(llvm::BasicBlock::Create(CGM.getLLVMContext(), "entry",
|
|
|
|
Init));
|
|
|
|
b.CreateAlignedStore(CGM.getNSConcreteGlobalBlock(),
|
2020-01-23 23:18:34 +08:00
|
|
|
b.CreateStructGEP(literal, 0),
|
|
|
|
CGM.getPointerAlign().getAsAlign());
|
2018-08-09 16:02:42 +08:00
|
|
|
b.CreateRetVoid();
|
|
|
|
// We can't use the normal LLVM global initialisation array, because we
|
|
|
|
// need to specify that this runs early in library initialisation.
|
|
|
|
auto *InitVar = new llvm::GlobalVariable(CGM.getModule(), Init->getType(),
|
|
|
|
/*isConstant*/true, llvm::GlobalValue::InternalLinkage,
|
|
|
|
Init, ".block_isa_init_ptr");
|
|
|
|
InitVar->setSection(".CRT$XCLa");
|
|
|
|
CGM.addUsedGlobal(InitVar);
|
|
|
|
}
|
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()) {
|
2020-01-14 07:54:54 +08:00
|
|
|
if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-10 05:08:08 +08:00
|
|
|
SourceLocation StartLoc = BlockInfo->getBlockExpr()->getBody()->getBeginLoc();
|
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
|
|
|
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
|
|
|
|
2018-08-10 05:09:38 +08:00
|
|
|
CurEHLocation = blockInfo.getBlockExpr()->getEndLoc();
|
2018-07-31 03:24:48 +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(),
|
2018-08-10 05:08:08 +08:00
|
|
|
blockInfo.getBlockExpr()->getBody()->getBeginLoc());
|
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()) {
|
2019-02-10 06:22:28 +08:00
|
|
|
Address addr = Builder.CreateStructGEP(
|
|
|
|
LoadBlockStruct(), blockInfo.CXXThisIndex, "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
|
|
|
|
2020-01-14 07:54:54 +08:00
|
|
|
if (CGM.getCodeGenOpts().hasReducedDebugInfo()) {
|
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
|
|
|
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;
|
2018-10-02 05:51:28 +08:00
|
|
|
if (CI.isEscapingByref()) {
|
2017-03-07 00:23:04 +08:00
|
|
|
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());
|
2018-03-20 01:38:40 +08:00
|
|
|
case QualType::PCK_ARCWeak:
|
|
|
|
// We need to register __weak direct captures with the runtime.
|
|
|
|
return std::make_pair(BlockCaptureEntityKind::ARCWeak, Flags);
|
2018-02-28 15:15:55 +08:00
|
|
|
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-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
|
|
|
}
|
|
|
|
|
2018-08-17 23:46:07 +08:00
|
|
|
static std::pair<BlockCaptureEntityKind, BlockFieldFlags>
|
|
|
|
computeDestroyInfoForBlockCapture(const BlockDecl::Capture &CI, QualType T,
|
|
|
|
const LangOptions &LangOpts);
|
|
|
|
|
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,
|
2018-08-17 23:46:07 +08:00
|
|
|
SmallVectorImpl<BlockCaptureManagedEntity> &ManagedCaptures) {
|
2017-03-07 00:23:04 +08:00
|
|
|
for (const auto &CI : BlockInfo.getBlockDecl()->captures()) {
|
|
|
|
const VarDecl *Variable = CI.getVariable();
|
|
|
|
const CGBlockInfo::Capture &Capture = BlockInfo.getCapture(Variable);
|
|
|
|
if (Capture.isConstant())
|
|
|
|
continue;
|
|
|
|
|
2018-08-22 21:41:19 +08:00
|
|
|
QualType VT = Capture.fieldType();
|
|
|
|
auto CopyInfo = computeCopyInfoForBlockCapture(CI, VT, LangOpts);
|
|
|
|
auto DisposeInfo = computeDestroyInfoForBlockCapture(CI, VT, LangOpts);
|
2018-08-17 23:46:07 +08:00
|
|
|
if (CopyInfo.first != BlockCaptureEntityKind::None ||
|
|
|
|
DisposeInfo.first != BlockCaptureEntityKind::None)
|
|
|
|
ManagedCaptures.emplace_back(CopyInfo.first, DisposeInfo.first,
|
|
|
|
CopyInfo.second, DisposeInfo.second, CI,
|
|
|
|
Capture);
|
2017-03-07 00:23:04 +08:00
|
|
|
}
|
2018-08-10 23:09:24 +08:00
|
|
|
|
|
|
|
// Sort the captures by offset.
|
2018-09-27 06:16:28 +08:00
|
|
|
llvm::sort(ManagedCaptures);
|
2017-03-07 00:23:04 +08:00
|
|
|
}
|
|
|
|
|
2018-07-27 00:51:21 +08:00
|
|
|
namespace {
|
|
|
|
/// Release a __block variable.
|
|
|
|
struct CallBlockRelease final : EHScopeStack::Cleanup {
|
|
|
|
Address Addr;
|
|
|
|
BlockFieldFlags FieldFlags;
|
2018-08-10 23:09:24 +08:00
|
|
|
bool LoadBlockVarAddr, CanThrow;
|
2018-07-27 00:51:21 +08:00
|
|
|
|
2018-08-10 23:09:24 +08:00
|
|
|
CallBlockRelease(Address Addr, BlockFieldFlags Flags, bool LoadValue,
|
|
|
|
bool CT)
|
|
|
|
: Addr(Addr), FieldFlags(Flags), LoadBlockVarAddr(LoadValue),
|
|
|
|
CanThrow(CT) {}
|
2018-07-27 00:51:21 +08:00
|
|
|
|
|
|
|
void Emit(CodeGenFunction &CGF, Flags flags) override {
|
|
|
|
llvm::Value *BlockVarAddr;
|
|
|
|
if (LoadBlockVarAddr) {
|
|
|
|
BlockVarAddr = CGF.Builder.CreateLoad(Addr);
|
|
|
|
BlockVarAddr = CGF.Builder.CreateBitCast(BlockVarAddr, CGF.VoidPtrTy);
|
|
|
|
} else {
|
|
|
|
BlockVarAddr = Addr.getPointer();
|
|
|
|
}
|
|
|
|
|
2018-08-10 23:09:24 +08:00
|
|
|
CGF.BuildBlockRelease(BlockVarAddr, FieldFlags, CanThrow);
|
2018-07-27 00:51:21 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
2018-08-10 23:09:24 +08:00
|
|
|
/// Check if \p T is a C++ class that has a destructor that can throw.
|
|
|
|
bool CodeGenFunction::cxxDestructorCanThrow(QualType T) {
|
|
|
|
if (const auto *RD = T->getAsCXXRecordDecl())
|
|
|
|
if (const CXXDestructorDecl *DD = RD->getDestructor())
|
2019-10-04 23:01:54 +08:00
|
|
|
return DD->getType()->castAs<FunctionProtoType>()->canThrow();
|
2018-08-10 23:09:24 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-08-17 23:46:07 +08:00
|
|
|
// Return a string that has the information about a capture.
|
|
|
|
static std::string getBlockCaptureStr(const BlockCaptureManagedEntity &E,
|
|
|
|
CaptureStrKind StrKind,
|
|
|
|
CharUnits BlockAlignment,
|
|
|
|
CodeGenModule &CGM) {
|
|
|
|
std::string Str;
|
2018-08-10 23:09:24 +08:00
|
|
|
ASTContext &Ctx = CGM.getContext();
|
2018-08-17 23:46:07 +08:00
|
|
|
const BlockDecl::Capture &CI = *E.CI;
|
|
|
|
QualType CaptureTy = CI.getVariable()->getType();
|
2018-08-10 23:09:24 +08:00
|
|
|
|
2018-08-17 23:46:07 +08:00
|
|
|
BlockCaptureEntityKind Kind;
|
|
|
|
BlockFieldFlags Flags;
|
|
|
|
|
|
|
|
// CaptureStrKind::Merged should be passed only when the operations and the
|
|
|
|
// flags are the same for copy and dispose.
|
|
|
|
assert((StrKind != CaptureStrKind::Merged ||
|
|
|
|
(E.CopyKind == E.DisposeKind && E.CopyFlags == E.DisposeFlags)) &&
|
|
|
|
"different operations and flags");
|
|
|
|
|
|
|
|
if (StrKind == CaptureStrKind::DisposeHelper) {
|
|
|
|
Kind = E.DisposeKind;
|
|
|
|
Flags = E.DisposeFlags;
|
|
|
|
} else {
|
|
|
|
Kind = E.CopyKind;
|
|
|
|
Flags = E.CopyFlags;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (Kind) {
|
|
|
|
case BlockCaptureEntityKind::CXXRecord: {
|
|
|
|
Str += "c";
|
|
|
|
SmallString<256> TyStr;
|
|
|
|
llvm::raw_svector_ostream Out(TyStr);
|
2018-10-20 13:45:01 +08:00
|
|
|
CGM.getCXXABI().getMangleContext().mangleTypeName(CaptureTy, Out);
|
2018-08-17 23:46:07 +08:00
|
|
|
Str += llvm::to_string(TyStr.size()) + TyStr.c_str();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case BlockCaptureEntityKind::ARCWeak:
|
|
|
|
Str += "w";
|
|
|
|
break;
|
|
|
|
case BlockCaptureEntityKind::ARCStrong:
|
|
|
|
Str += "s";
|
|
|
|
break;
|
|
|
|
case BlockCaptureEntityKind::BlockObject: {
|
|
|
|
const VarDecl *Var = CI.getVariable();
|
|
|
|
unsigned F = Flags.getBitMask();
|
|
|
|
if (F & BLOCK_FIELD_IS_BYREF) {
|
|
|
|
Str += "r";
|
|
|
|
if (F & BLOCK_FIELD_IS_WEAK)
|
|
|
|
Str += "w";
|
|
|
|
else {
|
|
|
|
// If CaptureStrKind::Merged is passed, check both the copy expression
|
|
|
|
// and the destructor.
|
|
|
|
if (StrKind != CaptureStrKind::DisposeHelper) {
|
|
|
|
if (Ctx.getBlockVarCopyInit(Var).canThrow())
|
|
|
|
Str += "c";
|
|
|
|
}
|
|
|
|
if (StrKind != CaptureStrKind::CopyHelper) {
|
|
|
|
if (CodeGenFunction::cxxDestructorCanThrow(CaptureTy))
|
|
|
|
Str += "d";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
assert((F & BLOCK_FIELD_IS_OBJECT) && "unexpected flag value");
|
|
|
|
if (F == BLOCK_FIELD_IS_BLOCK)
|
|
|
|
Str += "b";
|
|
|
|
else
|
|
|
|
Str += "o";
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case BlockCaptureEntityKind::NonTrivialCStruct: {
|
|
|
|
bool IsVolatile = CaptureTy.isVolatileQualified();
|
|
|
|
CharUnits Alignment =
|
|
|
|
BlockAlignment.alignmentAtOffset(E.Capture->getOffset());
|
|
|
|
|
|
|
|
Str += "n";
|
|
|
|
std::string FuncStr;
|
|
|
|
if (StrKind == CaptureStrKind::DisposeHelper)
|
|
|
|
FuncStr = CodeGenFunction::getNonTrivialDestructorStr(
|
|
|
|
CaptureTy, Alignment, IsVolatile, Ctx);
|
|
|
|
else
|
|
|
|
// If CaptureStrKind::Merged is passed, use the copy constructor string.
|
|
|
|
// It has all the information that the destructor string has.
|
|
|
|
FuncStr = CodeGenFunction::getNonTrivialCopyConstructorStr(
|
|
|
|
CaptureTy, Alignment, IsVolatile, Ctx);
|
|
|
|
// The underscore is necessary here because non-trivial copy constructor
|
|
|
|
// and destructor strings can start with a number.
|
|
|
|
Str += llvm::to_string(FuncStr.size()) + "_" + FuncStr;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case BlockCaptureEntityKind::None:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Str;
|
|
|
|
}
|
|
|
|
|
|
|
|
static std::string getCopyDestroyHelperFuncName(
|
|
|
|
const SmallVectorImpl<BlockCaptureManagedEntity> &Captures,
|
|
|
|
CharUnits BlockAlignment, CaptureStrKind StrKind, CodeGenModule &CGM) {
|
|
|
|
assert((StrKind == CaptureStrKind::CopyHelper ||
|
|
|
|
StrKind == CaptureStrKind::DisposeHelper) &&
|
|
|
|
"unexpected CaptureStrKind");
|
|
|
|
std::string Name = StrKind == CaptureStrKind::CopyHelper
|
|
|
|
? "__copy_helper_block_"
|
|
|
|
: "__destroy_helper_block_";
|
2018-08-10 23:09:24 +08:00
|
|
|
if (CGM.getLangOpts().Exceptions)
|
|
|
|
Name += "e";
|
|
|
|
if (CGM.getCodeGenOpts().ObjCAutoRefCountExceptions)
|
|
|
|
Name += "a";
|
|
|
|
Name += llvm::to_string(BlockAlignment.getQuantity()) + "_";
|
|
|
|
|
|
|
|
for (const BlockCaptureManagedEntity &E : Captures) {
|
|
|
|
Name += llvm::to_string(E.Capture->getOffset().getQuantity());
|
2018-08-17 23:46:07 +08:00
|
|
|
Name += getBlockCaptureStr(E, StrKind, BlockAlignment, CGM);
|
2018-08-10 23:09:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
2018-07-27 00:51:21 +08:00
|
|
|
static void pushCaptureCleanup(BlockCaptureEntityKind CaptureKind,
|
|
|
|
Address Field, QualType CaptureType,
|
2018-08-10 23:09:24 +08:00
|
|
|
BlockFieldFlags Flags, bool ForCopyHelper,
|
|
|
|
VarDecl *Var, CodeGenFunction &CGF) {
|
|
|
|
bool EHOnly = ForCopyHelper;
|
|
|
|
|
2018-07-27 00:51:21 +08:00
|
|
|
switch (CaptureKind) {
|
|
|
|
case BlockCaptureEntityKind::CXXRecord:
|
|
|
|
case BlockCaptureEntityKind::ARCWeak:
|
|
|
|
case BlockCaptureEntityKind::NonTrivialCStruct:
|
|
|
|
case BlockCaptureEntityKind::ARCStrong: {
|
|
|
|
if (CaptureType.isDestructedType() &&
|
|
|
|
(!EHOnly || CGF.needsEHCleanup(CaptureType.isDestructedType()))) {
|
|
|
|
CodeGenFunction::Destroyer *Destroyer =
|
|
|
|
CaptureKind == BlockCaptureEntityKind::ARCStrong
|
|
|
|
? CodeGenFunction::destroyARCStrongImprecise
|
|
|
|
: CGF.getDestroyer(CaptureType.isDestructedType());
|
|
|
|
CleanupKind Kind =
|
|
|
|
EHOnly ? EHCleanup
|
|
|
|
: CGF.getCleanupKind(CaptureType.isDestructedType());
|
|
|
|
CGF.pushDestroy(Kind, Field, CaptureType, Destroyer, Kind & EHCleanup);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case BlockCaptureEntityKind::BlockObject: {
|
|
|
|
if (!EHOnly || CGF.getLangOpts().Exceptions) {
|
|
|
|
CleanupKind Kind = EHOnly ? EHCleanup : NormalAndEHCleanup;
|
2018-08-10 23:09:24 +08:00
|
|
|
// Calls to _Block_object_dispose along the EH path in the copy helper
|
|
|
|
// function don't throw as newly-copied __block variables always have a
|
|
|
|
// reference count of 2.
|
|
|
|
bool CanThrow =
|
|
|
|
!ForCopyHelper && CGF.cxxDestructorCanThrow(CaptureType);
|
|
|
|
CGF.enterByrefCleanup(Kind, Field, Flags, /*LoadBlockVarAddr*/ true,
|
|
|
|
CanThrow);
|
2018-07-27 00:51:21 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case BlockCaptureEntityKind::None:
|
2018-08-17 23:46:07 +08:00
|
|
|
break;
|
2018-07-27 00:51:21 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-10 23:09:24 +08:00
|
|
|
static void setBlockHelperAttributesVisibility(bool CapturesNonExternalType,
|
|
|
|
llvm::Function *Fn,
|
|
|
|
const CGFunctionInfo &FI,
|
|
|
|
CodeGenModule &CGM) {
|
|
|
|
if (CapturesNonExternalType) {
|
|
|
|
CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);
|
|
|
|
} else {
|
|
|
|
Fn->setVisibility(llvm::GlobalValue::HiddenVisibility);
|
|
|
|
Fn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
|
2018-11-13 23:48:08 +08:00
|
|
|
CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Fn);
|
2018-08-10 23:09:24 +08:00
|
|
|
CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Fn);
|
|
|
|
}
|
|
|
|
}
|
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) {
|
2018-08-10 23:09:24 +08:00
|
|
|
SmallVector<BlockCaptureManagedEntity, 4> CopiedCaptures;
|
2018-08-17 23:46:07 +08:00
|
|
|
findBlockCapturedManagedEntities(blockInfo, getLangOpts(), CopiedCaptures);
|
2018-08-10 23:09:24 +08:00
|
|
|
std::string FuncName =
|
|
|
|
getCopyDestroyHelperFuncName(CopiedCaptures, blockInfo.BlockAlign,
|
2018-08-17 23:46:07 +08:00
|
|
|
CaptureStrKind::CopyHelper, CGM);
|
2018-08-10 23:09:24 +08:00
|
|
|
|
|
|
|
if (llvm::GlobalValue *Func = CGM.getModule().getNamedValue(FuncName))
|
2018-08-14 08:15:42 +08:00
|
|
|
return llvm::ConstantExpr::getBitCast(Func, VoidPtrTy);
|
2018-08-10 23:09:24 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
ASTContext &C = getContext();
|
|
|
|
|
2018-11-11 08:56:15 +08:00
|
|
|
QualType ReturnTy = C.VoidTy;
|
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
FunctionArgList args;
|
2018-11-11 08:56:15 +08:00
|
|
|
ImplicitParamDecl DstDecl(C, C.VoidPtrTy, ImplicitParamDecl::Other);
|
2017-06-09 21:40:18 +08:00
|
|
|
args.push_back(&DstDecl);
|
2018-11-11 08:56:15 +08:00
|
|
|
ImplicitParamDecl SrcDecl(C, C.VoidPtrTy, ImplicitParamDecl::Other);
|
2017-06-09 21:40:18 +08:00
|
|
|
args.push_back(&SrcDecl);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2016-03-11 12:30:31 +08:00
|
|
|
const CGFunctionInfo &FI =
|
2018-11-11 08:56:15 +08:00
|
|
|
CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, 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 =
|
2018-08-10 23:09:24 +08:00
|
|
|
llvm::Function::Create(LTy, llvm::GlobalValue::LinkOnceODRLinkage,
|
|
|
|
FuncName, &CGM.getModule());
|
2019-02-23 00:29:50 +08:00
|
|
|
if (CGM.supportsCOMDAT())
|
|
|
|
Fn->setComdat(CGM.getModule().getOrInsertComdat(FuncName));
|
2009-03-06 09:33:24 +08:00
|
|
|
|
2018-11-11 08:56:15 +08:00
|
|
|
IdentifierInfo *II = &C.Idents.get(FuncName);
|
2009-03-06 09:33:24 +08:00
|
|
|
|
2018-11-11 08:56:15 +08:00
|
|
|
SmallVector<QualType, 2> ArgTys;
|
|
|
|
ArgTys.push_back(C.VoidPtrTy);
|
|
|
|
ArgTys.push_back(C.VoidPtrTy);
|
|
|
|
QualType FunctionTy = C.getFunctionType(ReturnTy, ArgTys, {});
|
|
|
|
|
|
|
|
FunctionDecl *FD = FunctionDecl::Create(
|
|
|
|
C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II,
|
|
|
|
FunctionTy, nullptr, SC_Static, false, false);
|
2018-08-10 23:09:24 +08:00
|
|
|
setBlockHelperAttributesVisibility(blockInfo.CapturesNonExternalType, Fn, FI,
|
|
|
|
CGM);
|
2020-03-05 00:34:20 +08:00
|
|
|
// This is necessary to avoid inheriting the previous line number.
|
|
|
|
FD->setImplicit();
|
2018-11-11 08:56:15 +08:00
|
|
|
StartFunction(FD, ReturnTy, Fn, FI, args);
|
2020-03-05 00:34:20 +08:00
|
|
|
auto AL = ApplyDebugLocation::CreateArtificial(*this);
|
|
|
|
|
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
|
|
|
for (const auto &CopiedCapture : CopiedCaptures) {
|
2018-08-10 23:09:24 +08:00
|
|
|
const BlockDecl::Capture &CI = *CopiedCapture.CI;
|
|
|
|
const CGBlockInfo::Capture &capture = *CopiedCapture.Capture;
|
2018-07-27 00:51:21 +08:00
|
|
|
QualType captureType = CI.getVariable()->getType();
|
2018-08-17 23:46:07 +08:00
|
|
|
BlockFieldFlags flags = CopiedCapture.CopyFlags;
|
2011-02-07 18:33:21 +08:00
|
|
|
|
|
|
|
unsigned index = capture.getIndex();
|
2019-02-10 06:22:28 +08:00
|
|
|
Address srcField = Builder.CreateStructGEP(src, index);
|
|
|
|
Address dstField = Builder.CreateStructGEP(dst, index);
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2018-08-17 23:46:07 +08:00
|
|
|
switch (CopiedCapture.CopyKind) {
|
2018-08-14 04:59:57 +08:00
|
|
|
case BlockCaptureEntityKind::CXXRecord:
|
|
|
|
// If there's an explicit copy expression, we do that.
|
|
|
|
assert(CI.getCopyExpr() && "copy expression for variable is missing");
|
2017-03-07 00:23:04 +08:00
|
|
|
EmitSynthesizedCXXCopyCtor(dstField, srcField, CI.getCopyExpr());
|
2018-08-14 04:59:57 +08:00
|
|
|
break;
|
|
|
|
case BlockCaptureEntityKind::ARCWeak:
|
2011-06-16 07:02:42 +08:00
|
|
|
EmitARCCopyWeak(dstField, srcField);
|
2018-08-14 04:59:57 +08:00
|
|
|
break;
|
|
|
|
case BlockCaptureEntityKind::NonTrivialCStruct: {
|
|
|
|
// If this is a C struct that requires non-trivial copy construction,
|
|
|
|
// emit a call to its copy constructor.
|
2018-02-28 15:15:55 +08:00
|
|
|
QualType varType = CI.getVariable()->getType();
|
|
|
|
callCStructCopyConstructor(MakeAddrLValue(dstField, varType),
|
|
|
|
MakeAddrLValue(srcField, varType));
|
2018-08-14 04:59:57 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case BlockCaptureEntityKind::ARCStrong: {
|
2011-02-07 18:33:21 +08:00
|
|
|
llvm::Value *srcValue = Builder.CreateLoad(srcField, "blockcopy.src");
|
2018-08-14 04:59:57 +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) {
|
|
|
|
auto *ty = cast<llvm::PointerType>(srcValue->getType());
|
|
|
|
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.
|
2012-10-17 10:28:37 +08:00
|
|
|
} else {
|
2018-08-14 04:59:57 +08:00
|
|
|
EmitARCRetainNonBlock(srcValue);
|
2013-03-01 03:01:20 +08:00
|
|
|
|
2018-08-14 04:59:57 +08:00
|
|
|
// Unless EH cleanup is required, we don't need this anymore, so kill
|
|
|
|
// it. It's not quite worth the annoyance to avoid creating it in the
|
|
|
|
// first place.
|
|
|
|
if (!needsEHCleanup(captureType.isDestructedType()))
|
|
|
|
cast<llvm::Instruction>(dstField.getPointer())->eraseFromParent();
|
2012-10-17 10:28:37 +08:00
|
|
|
}
|
2018-08-14 04:59:57 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case BlockCaptureEntityKind::BlockObject: {
|
|
|
|
llvm::Value *srcValue = Builder.CreateLoad(srcField, "blockcopy.src");
|
|
|
|
srcValue = Builder.CreateBitCast(srcValue, VoidPtrTy);
|
|
|
|
llvm::Value *dstAddr =
|
|
|
|
Builder.CreateBitCast(dstField.getPointer(), VoidPtrTy);
|
|
|
|
llvm::Value *args[] = {
|
|
|
|
dstAddr, srcValue, llvm::ConstantInt::get(Int32Ty, flags.getBitMask())
|
|
|
|
};
|
|
|
|
|
|
|
|
if (CI.isByRef() && C.getBlockVarCopyInit(CI.getVariable()).canThrow())
|
|
|
|
EmitRuntimeCallOrInvoke(CGM.getBlockObjectAssign(), args);
|
|
|
|
else
|
|
|
|
EmitNounwindRuntimeCall(CGM.getBlockObjectAssign(), args);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case BlockCaptureEntityKind::None:
|
2018-08-17 23:46:07 +08:00
|
|
|
continue;
|
2009-03-07 10:35:30 +08:00
|
|
|
}
|
2018-07-27 00:51:21 +08:00
|
|
|
|
|
|
|
// Ensure that we destroy the copied object if an exception is thrown later
|
|
|
|
// in the helper function.
|
2018-08-17 23:46:07 +08:00
|
|
|
pushCaptureCleanup(CopiedCapture.CopyKind, dstField, captureType, flags,
|
2018-08-10 23:09:24 +08:00
|
|
|
/*ForCopyHelper*/ true, CI.getVariable(), *this);
|
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) {
|
2018-10-02 05:51:28 +08:00
|
|
|
if (CI.isEscapingByref()) {
|
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) {
|
2018-08-10 23:09:24 +08:00
|
|
|
SmallVector<BlockCaptureManagedEntity, 4> DestroyedCaptures;
|
2018-08-17 23:46:07 +08:00
|
|
|
findBlockCapturedManagedEntities(blockInfo, getLangOpts(), DestroyedCaptures);
|
2018-08-10 23:09:24 +08:00
|
|
|
std::string FuncName =
|
|
|
|
getCopyDestroyHelperFuncName(DestroyedCaptures, blockInfo.BlockAlign,
|
2018-08-17 23:46:07 +08:00
|
|
|
CaptureStrKind::DisposeHelper, CGM);
|
2018-08-10 23:09:24 +08:00
|
|
|
|
|
|
|
if (llvm::GlobalValue *Func = CGM.getModule().getNamedValue(FuncName))
|
2018-08-14 08:15:42 +08:00
|
|
|
return llvm::ConstantExpr::getBitCast(Func, VoidPtrTy);
|
2018-08-10 23:09:24 +08:00
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
ASTContext &C = getContext();
|
2009-03-06 09:33:24 +08:00
|
|
|
|
2018-11-11 08:56:15 +08:00
|
|
|
QualType ReturnTy = C.VoidTy;
|
|
|
|
|
2011-02-07 18:33:21 +08:00
|
|
|
FunctionArgList args;
|
2018-11-11 08:56:15 +08:00
|
|
|
ImplicitParamDecl SrcDecl(C, C.VoidPtrTy, ImplicitParamDecl::Other);
|
2017-06-09 21:40:18 +08:00
|
|
|
args.push_back(&SrcDecl);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2016-03-11 12:30:31 +08:00
|
|
|
const CGFunctionInfo &FI =
|
2018-11-11 08:56:15 +08:00
|
|
|
CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, 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 =
|
2018-08-10 23:09:24 +08:00
|
|
|
llvm::Function::Create(LTy, llvm::GlobalValue::LinkOnceODRLinkage,
|
|
|
|
FuncName, &CGM.getModule());
|
2019-02-23 00:29:50 +08:00
|
|
|
if (CGM.supportsCOMDAT())
|
|
|
|
Fn->setComdat(CGM.getModule().getOrInsertComdat(FuncName));
|
2009-03-06 09:33:24 +08:00
|
|
|
|
2018-11-11 08:56:15 +08:00
|
|
|
IdentifierInfo *II = &C.Idents.get(FuncName);
|
|
|
|
|
|
|
|
SmallVector<QualType, 1> ArgTys;
|
|
|
|
ArgTys.push_back(C.VoidPtrTy);
|
|
|
|
QualType FunctionTy = C.getFunctionType(ReturnTy, ArgTys, {});
|
2009-03-06 09:33:24 +08:00
|
|
|
|
2018-11-11 08:56:15 +08:00
|
|
|
FunctionDecl *FD = FunctionDecl::Create(
|
|
|
|
C, C.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II,
|
|
|
|
FunctionTy, nullptr, SC_Static, false, false);
|
2015-10-09 04:26:34 +08:00
|
|
|
|
2018-08-10 23:09:24 +08:00
|
|
|
setBlockHelperAttributesVisibility(blockInfo.CapturesNonExternalType, Fn, FI,
|
|
|
|
CGM);
|
2020-03-05 00:34:20 +08:00
|
|
|
// This is necessary to avoid inheriting the previous line number.
|
|
|
|
FD->setImplicit();
|
2018-11-11 08:56:15 +08:00
|
|
|
StartFunction(FD, ReturnTy, Fn, FI, args);
|
2018-08-10 23:09:24 +08:00
|
|
|
markAsIgnoreThreadCheckingAtRuntime(Fn);
|
|
|
|
|
2020-03-05 00:34:20 +08:00
|
|
|
auto AL = ApplyDebugLocation::CreateArtificial(*this);
|
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
|
|
|
for (const auto &DestroyedCapture : DestroyedCaptures) {
|
2018-08-10 23:09:24 +08:00
|
|
|
const BlockDecl::Capture &CI = *DestroyedCapture.CI;
|
|
|
|
const CGBlockInfo::Capture &capture = *DestroyedCapture.Capture;
|
2018-08-17 23:46:07 +08:00
|
|
|
BlockFieldFlags flags = DestroyedCapture.DisposeFlags;
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2019-02-10 06:22:28 +08:00
|
|
|
Address srcField = Builder.CreateStructGEP(src, capture.getIndex());
|
2011-02-07 18:33:21 +08:00
|
|
|
|
2018-08-17 23:46:07 +08:00
|
|
|
pushCaptureCleanup(DestroyedCapture.DisposeKind, srcField,
|
2018-08-10 23:09:24 +08:00
|
|
|
CI.getVariable()->getType(), flags,
|
|
|
|
/*ForCopyHelper*/ false, CI.getVariable(), *this);
|
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);
|
2019-02-06 00:42:33 +08:00
|
|
|
llvm::FunctionCallee 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);
|
|
|
|
|
2018-08-10 23:09:24 +08:00
|
|
|
CGF.BuildBlockRelease(value, Flags | BLOCK_BYREF_CALLER, false);
|
2011-03-31 16:03:29 +08:00
|
|
|
}
|
|
|
|
|
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);
|
2018-07-31 03:24:48 +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();
|
|
|
|
|
2018-11-11 08:56:15 +08:00
|
|
|
QualType ReturnTy = Context.VoidTy;
|
2009-03-06 10:29:21 +08:00
|
|
|
|
2011-03-09 12:27:21 +08:00
|
|
|
FunctionArgList args;
|
2018-11-11 08:56:15 +08:00
|
|
|
ImplicitParamDecl Dst(Context, Context.VoidPtrTy, ImplicitParamDecl::Other);
|
2017-06-09 21:40:18 +08:00
|
|
|
args.push_back(&Dst);
|
2011-03-09 12:27:21 +08:00
|
|
|
|
2018-11-11 08:56:15 +08:00
|
|
|
ImplicitParamDecl Src(Context, Context.VoidPtrTy, ImplicitParamDecl::Other);
|
2017-06-09 21:40:18 +08:00
|
|
|
args.push_back(&Src);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2016-03-11 12:30:31 +08:00
|
|
|
const CGFunctionInfo &FI =
|
2018-11-11 08:56:15 +08:00
|
|
|
CGF.CGM.getTypes().arrangeBuiltinFunctionDeclaration(ReturnTy, 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
|
|
|
|
2018-11-11 08:56:15 +08:00
|
|
|
SmallVector<QualType, 2> ArgTys;
|
|
|
|
ArgTys.push_back(Context.VoidPtrTy);
|
|
|
|
ArgTys.push_back(Context.VoidPtrTy);
|
|
|
|
QualType FunctionTy = Context.getFunctionType(ReturnTy, ArgTys, {});
|
|
|
|
|
|
|
|
FunctionDecl *FD = FunctionDecl::Create(
|
|
|
|
Context, Context.getTranslationUnitDecl(), SourceLocation(),
|
|
|
|
SourceLocation(), II, FunctionTy, nullptr, SC_Static, 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
|
|
|
|
2018-11-11 08:56:15 +08:00
|
|
|
CGF.StartFunction(FD, ReturnTy, 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);
|
2018-07-31 03:24:48 +08:00
|
|
|
}
|
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
|
|
|
|
2018-11-11 08:56:15 +08:00
|
|
|
SmallVector<QualType, 1> ArgTys;
|
|
|
|
ArgTys.push_back(Context.VoidPtrTy);
|
|
|
|
QualType FunctionTy = Context.getFunctionType(R, ArgTys, {});
|
|
|
|
|
|
|
|
FunctionDecl *FD = FunctionDecl::Create(
|
|
|
|
Context, Context.getTranslationUnitDecl(), SourceLocation(),
|
|
|
|
SourceLocation(), II, FunctionTy, nullptr, SC_Static, 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;
|
2018-10-02 05:51:28 +08:00
|
|
|
assert(var.isEscapingByref() &&
|
|
|
|
"only escaping __block variables need byref helpers");
|
|
|
|
|
2011-03-31 16:03:29 +08:00
|
|
|
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()) {
|
2018-08-10 23:09:24 +08:00
|
|
|
const Expr *copyExpr =
|
|
|
|
CGM.getContext().getBlockVarCopyInit(&var).getCopyExpr();
|
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;
|
2018-07-31 03:24:48 +08:00
|
|
|
} else if (CGM.getContext().isObjCNSObjectType(type) ||
|
2011-03-31 16:03:29 +08:00
|
|
|
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) {
|
2019-02-10 06:22:28 +08:00
|
|
|
Address forwardingAddr = Builder.CreateStructGEP(baseAddr, 1, "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
|
|
|
baseAddr = Address(Builder.CreateLoad(forwardingAddr), info.ByrefAlignment);
|
|
|
|
}
|
|
|
|
|
2019-02-10 06:22:28 +08:00
|
|
|
return Builder.CreateStructGEP(baseAddr, info.FieldIndex, 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());
|
2018-07-31 03:24:48 +08:00
|
|
|
|
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;
|
2018-07-31 03:24:48 +08:00
|
|
|
|
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();
|
2018-07-31 03:24:48 +08:00
|
|
|
|
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();
|
2018-07-31 03:24:48 +08:00
|
|
|
|
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);
|
2018-07-31 03:24:48 +08:00
|
|
|
|
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();
|
2018-07-31 03:24:48 +08:00
|
|
|
|
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) {
|
2019-02-10 06:22:28 +08:00
|
|
|
auto fieldAddr = Builder.CreateStructGEP(addr, nextHeaderIndex, name);
|
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, 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
|
|
|
}
|
|
|
|
|
2018-08-10 23:09:24 +08:00
|
|
|
void CodeGenFunction::BuildBlockRelease(llvm::Value *V, BlockFieldFlags flags,
|
|
|
|
bool CanThrow) {
|
2019-02-06 00:42:33 +08:00
|
|
|
llvm::FunctionCallee F = CGM.getBlockObjectDispose();
|
2013-03-01 03:01:20 +08:00
|
|
|
llvm::Value *args[] = {
|
|
|
|
Builder.CreateBitCast(V, Int8PtrTy),
|
|
|
|
llvm::ConstantInt::get(Int32Ty, flags.getBitMask())
|
|
|
|
};
|
2018-08-10 23:09:24 +08:00
|
|
|
|
|
|
|
if (CanThrow)
|
|
|
|
EmitRuntimeCallOrInvoke(F, args);
|
|
|
|
else
|
|
|
|
EmitNounwindRuntimeCall(F, args);
|
2009-03-05 09:23:13 +08:00
|
|
|
}
|
2011-03-31 09:59:53 +08:00
|
|
|
|
2018-07-27 00:51:21 +08:00
|
|
|
void CodeGenFunction::enterByrefCleanup(CleanupKind Kind, Address Addr,
|
|
|
|
BlockFieldFlags Flags,
|
2018-08-10 23:09:24 +08:00
|
|
|
bool LoadBlockVarAddr, bool CanThrow) {
|
|
|
|
EHStack.pushCleanup<CallBlockRelease>(Kind, Addr, Flags, LoadBlockVarAddr,
|
|
|
|
CanThrow);
|
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
|
|
|
}
|
|
|
|
|
2019-02-06 00:42:33 +08:00
|
|
|
llvm::FunctionCallee CodeGenModule::getBlockObjectDispose() {
|
2011-09-10 04:41:01 +08:00
|
|
|
if (BlockObjectDispose)
|
|
|
|
return BlockObjectDispose;
|
|
|
|
|
|
|
|
llvm::Type *args[] = { Int8PtrTy, Int32Ty };
|
|
|
|
llvm::FunctionType *fty
|
|
|
|
= llvm::FunctionType::get(VoidTy, args, false);
|
|
|
|
BlockObjectDispose = CreateRuntimeFunction(fty, "_Block_object_dispose");
|
2019-02-06 00:42:33 +08:00
|
|
|
configureBlocksRuntimeObject(
|
|
|
|
*this, cast<llvm::Constant>(BlockObjectDispose.getCallee()));
|
2011-09-10 04:41:01 +08:00
|
|
|
return BlockObjectDispose;
|
|
|
|
}
|
|
|
|
|
2019-02-06 00:42:33 +08:00
|
|
|
llvm::FunctionCallee CodeGenModule::getBlockObjectAssign() {
|
2011-09-10 04:41:01 +08:00
|
|
|
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");
|
2019-02-06 00:42:33 +08:00
|
|
|
configureBlocksRuntimeObject(
|
|
|
|
*this, cast<llvm::Constant>(BlockObjectAssign.getCallee()));
|
2011-09-10 04:41:01 +08:00
|
|
|
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
|
|
|
}
|