2007-06-02 12:16:21 +08:00
|
|
|
//===--- CGDecl.cpp - Emit LLVM Code for declarations ---------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 03:59:25 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2007-06-02 12:16:21 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This contains code to emit Decl nodes as LLVM code.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "CodeGenFunction.h"
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
#include "CGBlocks.h"
|
2015-04-23 05:38:15 +08:00
|
|
|
#include "CGCleanup.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "CGDebugInfo.h"
|
2011-09-20 05:14:35 +08:00
|
|
|
#include "CGOpenCLRuntime.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "CodeGenModule.h"
|
2008-08-11 13:00:27 +08:00
|
|
|
#include "clang/AST/ASTContext.h"
|
2009-12-22 22:23:30 +08:00
|
|
|
#include "clang/AST/CharUnits.h"
|
2008-08-11 13:35:13 +08:00
|
|
|
#include "clang/AST/Decl.h"
|
2008-08-25 09:38:19 +08:00
|
|
|
#include "clang/AST/DeclObjC.h"
|
2008-04-19 12:17:09 +08:00
|
|
|
#include "clang/Basic/SourceManager.h"
|
2008-05-08 13:58:21 +08:00
|
|
|
#include "clang/Basic/TargetInfo.h"
|
2013-10-31 05:53:58 +08:00
|
|
|
#include "clang/CodeGen/CGFunctionInfo.h"
|
2010-06-16 07:19:56 +08:00
|
|
|
#include "clang/Frontend/CodeGenOptions.h"
|
2013-01-02 19:45:17 +08:00
|
|
|
#include "llvm/IR/DataLayout.h"
|
|
|
|
#include "llvm/IR/GlobalVariable.h"
|
|
|
|
#include "llvm/IR/Intrinsics.h"
|
|
|
|
#include "llvm/IR/Type.h"
|
2007-06-02 12:16:21 +08:00
|
|
|
using namespace clang;
|
|
|
|
using namespace CodeGen;
|
|
|
|
|
|
|
|
|
2007-06-09 09:20:56 +08:00
|
|
|
void CodeGenFunction::EmitDecl(const Decl &D) {
|
|
|
|
switch (D.getKind()) {
|
2015-11-04 11:40:30 +08:00
|
|
|
case Decl::BuiltinTemplate:
|
2010-04-23 10:02:43 +08:00
|
|
|
case Decl::TranslationUnit:
|
2015-03-07 08:04:49 +08:00
|
|
|
case Decl::ExternCContext:
|
2010-04-23 10:02:43 +08:00
|
|
|
case Decl::Namespace:
|
|
|
|
case Decl::UnresolvedUsingTypename:
|
|
|
|
case Decl::ClassTemplateSpecialization:
|
|
|
|
case Decl::ClassTemplatePartialSpecialization:
|
2013-08-06 09:03:05 +08:00
|
|
|
case Decl::VarTemplateSpecialization:
|
|
|
|
case Decl::VarTemplatePartialSpecialization:
|
2010-04-23 10:02:43 +08:00
|
|
|
case Decl::TemplateTypeParm:
|
|
|
|
case Decl::UnresolvedUsingValue:
|
2010-05-30 15:21:58 +08:00
|
|
|
case Decl::NonTypeTemplateParm:
|
2010-04-23 10:02:43 +08:00
|
|
|
case Decl::CXXMethod:
|
|
|
|
case Decl::CXXConstructor:
|
|
|
|
case Decl::CXXDestructor:
|
|
|
|
case Decl::CXXConversion:
|
|
|
|
case Decl::Field:
|
2013-04-16 15:28:30 +08:00
|
|
|
case Decl::MSProperty:
|
2010-11-21 14:49:41 +08:00
|
|
|
case Decl::IndirectField:
|
2010-04-23 10:02:43 +08:00
|
|
|
case Decl::ObjCIvar:
|
2011-08-24 06:38:00 +08:00
|
|
|
case Decl::ObjCAtDefsField:
|
2007-10-09 05:37:32 +08:00
|
|
|
case Decl::ParmVar:
|
2010-04-23 10:02:43 +08:00
|
|
|
case Decl::ImplicitParam:
|
|
|
|
case Decl::ClassTemplate:
|
2013-08-06 09:03:05 +08:00
|
|
|
case Decl::VarTemplate:
|
2010-04-23 10:02:43 +08:00
|
|
|
case Decl::FunctionTemplate:
|
2011-05-06 05:57:07 +08:00
|
|
|
case Decl::TypeAliasTemplate:
|
2010-04-23 10:02:43 +08:00
|
|
|
case Decl::TemplateTemplateParm:
|
|
|
|
case Decl::ObjCMethod:
|
|
|
|
case Decl::ObjCCategory:
|
|
|
|
case Decl::ObjCProtocol:
|
|
|
|
case Decl::ObjCInterface:
|
|
|
|
case Decl::ObjCCategoryImpl:
|
|
|
|
case Decl::ObjCImplementation:
|
|
|
|
case Decl::ObjCProperty:
|
|
|
|
case Decl::ObjCCompatibleAlias:
|
2010-06-05 13:09:32 +08:00
|
|
|
case Decl::AccessSpec:
|
2010-04-23 10:02:43 +08:00
|
|
|
case Decl::LinkageSpec:
|
|
|
|
case Decl::ObjCPropertyImpl:
|
|
|
|
case Decl::FileScopeAsm:
|
|
|
|
case Decl::Friend:
|
|
|
|
case Decl::FriendTemplate:
|
|
|
|
case Decl::Block:
|
2013-04-17 03:37:38 +08:00
|
|
|
case Decl::Captured:
|
2011-08-14 11:52:19 +08:00
|
|
|
case Decl::ClassScopeFunctionSpecialization:
|
2013-05-20 12:58:53 +08:00
|
|
|
case Decl::UsingShadow:
|
Parsing, semantic analysis, and AST for Objective-C type parameters.
Produce type parameter declarations for Objective-C type parameters,
and attach lists of type parameters to Objective-C classes,
categories, forward declarations, and extensions as
appropriate. Perform semantic analysis of type bounds for type
parameters, both in isolation and across classes/categories/extensions
to ensure consistency.
Also handle (de-)serialization of Objective-C type parameter lists,
along with sundry other things one must do to add a new declaration to
Clang.
Note that Objective-C type parameters are typedef name declarations,
like typedefs and C++11 type aliases, in support of type erasure.
Part of rdar://problem/6294649.
llvm-svn: 241541
2015-07-07 11:57:15 +08:00
|
|
|
case Decl::ObjCTypeParam:
|
2011-09-23 13:06:16 +08:00
|
|
|
llvm_unreachable("Declaration should not be in declstmts!");
|
2007-06-02 12:16:21 +08:00
|
|
|
case Decl::Function: // void X();
|
2015-07-02 02:07:22 +08:00
|
|
|
case Decl::Record: // struct/union/class X;
|
2007-06-02 12:16:21 +08:00
|
|
|
case Decl::Enum: // enum X;
|
2009-09-09 23:08:12 +08:00
|
|
|
case Decl::EnumConstant: // enum ? { X = ? }
|
2015-07-02 02:07:22 +08:00
|
|
|
case Decl::CXXRecord: // struct/union/class X; [C++]
|
2009-12-04 01:26:31 +08:00
|
|
|
case Decl::StaticAssert: // static_assert(X, ""); [C++0x]
|
2011-02-18 10:08:43 +08:00
|
|
|
case Decl::Label: // __label__ x;
|
2011-12-03 07:23:56 +08:00
|
|
|
case Decl::Import:
|
2013-03-22 14:34:35 +08:00
|
|
|
case Decl::OMPThreadPrivate:
|
2013-02-23 01:15:32 +08:00
|
|
|
case Decl::Empty:
|
2007-06-02 12:16:21 +08:00
|
|
|
// None of these decls require codegen support.
|
|
|
|
return;
|
2013-02-02 08:39:32 +08:00
|
|
|
|
2013-05-21 06:50:41 +08:00
|
|
|
case Decl::NamespaceAlias:
|
|
|
|
if (CGDebugInfo *DI = getDebugInfo())
|
|
|
|
DI->EmitNamespaceAlias(cast<NamespaceAliasDecl>(D));
|
|
|
|
return;
|
2013-05-20 12:58:53 +08:00
|
|
|
case Decl::Using: // using X; [C++]
|
|
|
|
if (CGDebugInfo *DI = getDebugInfo())
|
|
|
|
DI->EmitUsingDecl(cast<UsingDecl>(D));
|
|
|
|
return;
|
2013-04-22 14:13:21 +08:00
|
|
|
case Decl::UsingDirective: // using namespace X; [C++]
|
|
|
|
if (CGDebugInfo *DI = getDebugInfo())
|
|
|
|
DI->EmitUsingDirective(cast<UsingDirectiveDecl>(D));
|
|
|
|
return;
|
2008-08-30 01:28:43 +08:00
|
|
|
case Decl::Var: {
|
|
|
|
const VarDecl &VD = cast<VarDecl>(D);
|
2010-10-15 12:57:14 +08:00
|
|
|
assert(VD.isLocalVarDecl() &&
|
2008-08-30 01:28:43 +08:00
|
|
|
"Should not see file-scope variables inside a function!");
|
2010-10-15 12:57:14 +08:00
|
|
|
return EmitVarDecl(VD);
|
2008-08-30 01:28:43 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2011-04-15 22:24:37 +08:00
|
|
|
case Decl::Typedef: // typedef int X;
|
|
|
|
case Decl::TypeAlias: { // using X = int; [C++0x]
|
|
|
|
const TypedefNameDecl &TD = cast<TypedefNameDecl>(D);
|
2008-12-21 05:51:53 +08:00
|
|
|
QualType Ty = TD.getUnderlyingType();
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2008-12-21 05:51:53 +08:00
|
|
|
if (Ty->isVariablyModifiedType())
|
2011-06-25 05:55:10 +08:00
|
|
|
EmitVariablyModifiedType(Ty);
|
2008-12-21 05:51:53 +08:00
|
|
|
}
|
2007-06-02 12:16:21 +08:00
|
|
|
}
|
2007-06-02 12:53:11 +08:00
|
|
|
}
|
|
|
|
|
2010-10-15 12:57:14 +08:00
|
|
|
/// EmitVarDecl - This method handles emission of any variable declaration
|
2007-06-02 12:53:11 +08:00
|
|
|
/// inside a function, including static vars etc.
|
2010-10-15 12:57:14 +08:00
|
|
|
void CodeGenFunction::EmitVarDecl(const VarDecl &D) {
|
2013-05-16 19:27:56 +08:00
|
|
|
if (D.isStaticLocal()) {
|
2011-08-24 06:38:00 +08:00
|
|
|
llvm::GlobalValue::LinkageTypes Linkage =
|
2014-04-29 06:17:59 +08:00
|
|
|
CGM.getLLVMLinkageVarDefinition(&D, /*isConstant=*/false);
|
2010-02-07 10:03:08 +08:00
|
|
|
|
2014-04-29 06:17:59 +08:00
|
|
|
// FIXME: We need to force the emission/use of a guard variable for
|
|
|
|
// some variables even if we can constant-evaluate them because
|
|
|
|
// we can't guarantee every translation unit will constant-evaluate them.
|
2011-08-24 06:38:00 +08:00
|
|
|
|
2010-10-15 12:57:14 +08:00
|
|
|
return EmitStaticVarDecl(D, Linkage);
|
2010-02-07 10:03:08 +08:00
|
|
|
}
|
2013-05-16 19:27:56 +08:00
|
|
|
|
|
|
|
if (D.hasExternalStorage())
|
2008-02-17 06:30:38 +08:00
|
|
|
// Don't emit it now, allow it to be emitted lazily on its first use.
|
|
|
|
return;
|
2013-05-16 19:27:56 +08:00
|
|
|
|
2015-09-30 22:08:20 +08:00
|
|
|
if (D.getType().getAddressSpace() == LangAS::opencl_local)
|
2011-09-20 05:14:35 +08:00
|
|
|
return CGM.getOpenCLRuntime().EmitWorkGroupLocalVarDecl(*this, D);
|
2009-04-14 10:25:56 +08:00
|
|
|
|
2013-05-16 19:27:56 +08:00
|
|
|
assert(D.hasLocalStorage());
|
|
|
|
return EmitAutoVarDecl(D);
|
2007-06-02 12:16:21 +08:00
|
|
|
}
|
|
|
|
|
2014-10-08 09:07:54 +08:00
|
|
|
static std::string getStaticDeclName(CodeGenModule &CGM, const VarDecl &D) {
|
|
|
|
if (CGM.getLangOpts().CPlusPlus)
|
2014-06-06 06:10:59 +08:00
|
|
|
return CGM.getMangledName(&D).str();
|
|
|
|
|
2014-10-08 09:07:54 +08:00
|
|
|
// If this isn't C++, we don't need a mangled name, just a pretty one.
|
|
|
|
assert(!D.isExternallyVisible() && "name shouldn't matter");
|
|
|
|
std::string ContextName;
|
|
|
|
const DeclContext *DC = D.getDeclContext();
|
2015-05-07 14:28:46 +08:00
|
|
|
if (auto *CD = dyn_cast<CapturedDecl>(DC))
|
|
|
|
DC = cast<DeclContext>(CD->getNonClosureContext());
|
2014-10-08 09:07:54 +08:00
|
|
|
if (const auto *FD = dyn_cast<FunctionDecl>(DC))
|
2014-06-06 06:10:59 +08:00
|
|
|
ContextName = CGM.getMangledName(FD);
|
2014-10-08 09:07:54 +08:00
|
|
|
else if (const auto *BD = dyn_cast<BlockDecl>(DC))
|
|
|
|
ContextName = CGM.getBlockMangledName(GlobalDecl(), BD);
|
|
|
|
else if (const auto *OMD = dyn_cast<ObjCMethodDecl>(DC))
|
|
|
|
ContextName = OMD->getSelector().getAsString();
|
2009-12-05 16:22:11 +08:00
|
|
|
else
|
2011-09-23 13:06:16 +08:00
|
|
|
llvm_unreachable("Unknown context for static var decl");
|
2011-08-24 06:38:00 +08:00
|
|
|
|
2014-10-08 09:07:54 +08:00
|
|
|
ContextName += "." + D.getNameAsString();
|
|
|
|
return ContextName;
|
2009-12-05 16:22:11 +08:00
|
|
|
}
|
|
|
|
|
2014-10-08 09:07:54 +08:00
|
|
|
llvm::Constant *CodeGenModule::getOrCreateStaticVarDecl(
|
|
|
|
const VarDecl &D, llvm::GlobalValue::LinkageTypes Linkage) {
|
|
|
|
// In general, we don't always emit static var decls once before we reference
|
|
|
|
// them. It is possible to reference them before emitting the function that
|
|
|
|
// contains them, and it is possible to emit the containing function multiple
|
|
|
|
// times.
|
|
|
|
if (llvm::Constant *ExistingGV = StaticLocalDeclMap[&D])
|
|
|
|
return ExistingGV;
|
|
|
|
|
2009-02-26 03:24:29 +08:00
|
|
|
QualType Ty = D.getType();
|
|
|
|
assert(Ty->isConstantSizeType() && "VLAs can't be static");
|
|
|
|
|
2011-11-21 05:05:04 +08:00
|
|
|
// Use the label if the variable is renamed with the asm-label extension.
|
|
|
|
std::string Name;
|
2011-11-21 23:47:23 +08:00
|
|
|
if (D.hasAttr<AsmLabelAttr>())
|
2014-10-08 09:07:54 +08:00
|
|
|
Name = getMangledName(&D);
|
2011-11-21 23:47:23 +08:00
|
|
|
else
|
2014-10-08 09:07:54 +08:00
|
|
|
Name = getStaticDeclName(*this, D);
|
2009-02-26 03:24:29 +08:00
|
|
|
|
2014-10-08 09:07:54 +08:00
|
|
|
llvm::Type *LTy = getTypes().ConvertTypeForMem(Ty);
|
2012-08-29 04:37:10 +08:00
|
|
|
unsigned AddrSpace =
|
2014-10-08 09:07:54 +08:00
|
|
|
GetGlobalVarAddressSpace(&D, getContext().getTargetAddressSpace(Ty));
|
2014-11-04 00:51:53 +08:00
|
|
|
|
|
|
|
// Local address space cannot have an initializer.
|
|
|
|
llvm::Constant *Init = nullptr;
|
|
|
|
if (Ty.getAddressSpace() != LangAS::opencl_local)
|
|
|
|
Init = EmitNullConstant(Ty);
|
|
|
|
else
|
|
|
|
Init = llvm::UndefValue::get(LTy);
|
|
|
|
|
2009-09-27 02:16:06 +08:00
|
|
|
llvm::GlobalVariable *GV =
|
2014-10-08 09:07:54 +08:00
|
|
|
new llvm::GlobalVariable(getModule(), LTy,
|
2009-09-27 02:16:06 +08:00
|
|
|
Ty.isConstant(getContext()), Linkage,
|
2014-11-04 00:51:53 +08:00
|
|
|
Init, Name, nullptr,
|
2012-06-28 16:01:44 +08:00
|
|
|
llvm::GlobalVariable::NotThreadLocal,
|
2012-08-29 04:37:10 +08:00
|
|
|
AddrSpace);
|
2010-01-28 01:10:57 +08:00
|
|
|
GV->setAlignment(getContext().getDeclAlign(&D).getQuantity());
|
2014-10-08 09:07:54 +08:00
|
|
|
setGlobalVisibility(GV, &D);
|
2012-06-28 16:01:44 +08:00
|
|
|
|
2015-05-10 05:10:07 +08:00
|
|
|
if (supportsCOMDAT() && GV->isWeakForLinker())
|
|
|
|
GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
|
2015-01-13 06:13:53 +08:00
|
|
|
|
2013-04-13 10:43:54 +08:00
|
|
|
if (D.getTLSKind())
|
2014-10-08 09:07:54 +08:00
|
|
|
setTLSMode(GV, D);
|
2012-06-28 16:01:44 +08:00
|
|
|
|
2014-06-18 23:55:13 +08:00
|
|
|
if (D.isExternallyVisible()) {
|
|
|
|
if (D.hasAttr<DLLImportAttr>())
|
|
|
|
GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
|
|
|
|
else if (D.hasAttr<DLLExportAttr>())
|
|
|
|
GV->setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass);
|
|
|
|
}
|
|
|
|
|
2014-03-25 06:05:38 +08:00
|
|
|
// Make sure the result is of the correct type.
|
2014-10-08 09:07:54 +08:00
|
|
|
unsigned ExpectedAddrSpace = getContext().getTargetAddressSpace(Ty);
|
|
|
|
llvm::Constant *Addr = GV;
|
2014-03-25 06:05:38 +08:00
|
|
|
if (AddrSpace != ExpectedAddrSpace) {
|
|
|
|
llvm::PointerType *PTy = llvm::PointerType::get(LTy, ExpectedAddrSpace);
|
2014-10-08 09:07:54 +08:00
|
|
|
Addr = llvm::ConstantExpr::getAddrSpaceCast(GV, PTy);
|
2014-03-25 06:05:38 +08:00
|
|
|
}
|
|
|
|
|
2014-10-08 09:07:54 +08:00
|
|
|
setStaticLocalDeclAddress(&D, Addr);
|
|
|
|
|
|
|
|
// Ensure that the static local gets initialized by making sure the parent
|
|
|
|
// function gets emitted eventually.
|
|
|
|
const Decl *DC = cast<Decl>(D.getDeclContext());
|
|
|
|
|
|
|
|
// We can't name blocks or captured statements directly, so try to emit their
|
|
|
|
// parents.
|
|
|
|
if (isa<BlockDecl>(DC) || isa<CapturedDecl>(DC)) {
|
|
|
|
DC = DC->getNonClosureContext();
|
|
|
|
// FIXME: Ensure that global blocks get emitted.
|
|
|
|
if (!DC)
|
|
|
|
return Addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
GlobalDecl GD;
|
|
|
|
if (const auto *CD = dyn_cast<CXXConstructorDecl>(DC))
|
|
|
|
GD = GlobalDecl(CD, Ctor_Base);
|
|
|
|
else if (const auto *DD = dyn_cast<CXXDestructorDecl>(DC))
|
|
|
|
GD = GlobalDecl(DD, Dtor_Base);
|
|
|
|
else if (const auto *FD = dyn_cast<FunctionDecl>(DC))
|
|
|
|
GD = GlobalDecl(FD);
|
|
|
|
else {
|
|
|
|
// Don't do anything for Obj-C method decls or global closures. We should
|
|
|
|
// never defer them.
|
|
|
|
assert(isa<ObjCMethodDecl>(DC) && "unexpected parent code decl");
|
|
|
|
}
|
|
|
|
if (GD.getDecl())
|
|
|
|
(void)GetAddrOfGlobal(GD);
|
|
|
|
|
|
|
|
return Addr;
|
2009-02-26 03:24:29 +08:00
|
|
|
}
|
|
|
|
|
2012-02-14 06:16:19 +08:00
|
|
|
/// hasNontrivialDestruction - Determine whether a type's destruction is
|
|
|
|
/// non-trivial. If so, and the variable uses static initialization, we must
|
|
|
|
/// register its destructor to run on exit.
|
|
|
|
static bool hasNontrivialDestruction(QualType T) {
|
|
|
|
CXXRecordDecl *RD = T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
|
|
|
|
return RD && !RD->hasTrivialDestructor();
|
|
|
|
}
|
|
|
|
|
2012-03-31 03:44:53 +08:00
|
|
|
/// AddInitializerToStaticVarDecl - Add the initializer for 'D' to the
|
|
|
|
/// global variable that has already been created for it. If the initializer
|
|
|
|
/// has a different type than GV does, this may free GV and return a different
|
|
|
|
/// one. Otherwise it just returns GV.
|
|
|
|
llvm::GlobalVariable *
|
2010-10-15 12:57:14 +08:00
|
|
|
CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
|
2012-03-31 03:44:53 +08:00
|
|
|
llvm::GlobalVariable *GV) {
|
|
|
|
llvm::Constant *Init = CGM.EmitConstantInit(D, this);
|
2010-07-16 07:40:35 +08:00
|
|
|
|
2009-12-05 16:22:11 +08:00
|
|
|
// If constant emission failed, then this should be a C++ static
|
|
|
|
// initializer.
|
2012-03-31 03:44:53 +08:00
|
|
|
if (!Init) {
|
2012-11-02 06:30:59 +08:00
|
|
|
if (!getLangOpts().CPlusPlus)
|
2009-12-05 16:22:11 +08:00
|
|
|
CGM.ErrorUnsupported(D.getInit(), "constant l-value expression");
|
2010-09-08 09:44:27 +08:00
|
|
|
else if (Builder.GetInsertBlock()) {
|
2011-08-24 06:38:00 +08:00
|
|
|
// Since we have a static initializer, this global variable can't
|
2010-01-26 12:02:23 +08:00
|
|
|
// be constant.
|
2012-03-31 03:44:53 +08:00
|
|
|
GV->setConstant(false);
|
2010-09-08 09:44:27 +08:00
|
|
|
|
2012-03-31 03:44:53 +08:00
|
|
|
EmitCXXGuardedInit(D, GV, /*PerformInit*/true);
|
2010-01-26 12:02:23 +08:00
|
|
|
}
|
2012-03-31 03:44:53 +08:00
|
|
|
return GV;
|
2009-12-05 16:22:11 +08:00
|
|
|
}
|
2010-07-16 07:40:35 +08:00
|
|
|
|
2009-12-05 16:22:11 +08:00
|
|
|
// The initializer may differ in type from the global. Rewrite
|
|
|
|
// the global to match the initializer. (We have to do this
|
|
|
|
// because some types, like unions, can't be completely represented
|
|
|
|
// in the LLVM type system.)
|
2012-03-31 03:44:53 +08:00
|
|
|
if (GV->getType()->getElementType() != Init->getType()) {
|
|
|
|
llvm::GlobalVariable *OldGV = GV;
|
|
|
|
|
|
|
|
GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(),
|
|
|
|
OldGV->isConstant(),
|
|
|
|
OldGV->getLinkage(), Init, "",
|
|
|
|
/*InsertBefore*/ OldGV,
|
2012-06-23 19:51:46 +08:00
|
|
|
OldGV->getThreadLocalMode(),
|
2012-03-31 03:44:53 +08:00
|
|
|
CGM.getContext().getTargetAddressSpace(D.getType()));
|
|
|
|
GV->setVisibility(OldGV->getVisibility());
|
2015-07-21 04:35:30 +08:00
|
|
|
GV->setComdat(OldGV->getComdat());
|
2011-08-24 06:38:00 +08:00
|
|
|
|
2009-12-05 16:22:11 +08:00
|
|
|
// Steal the name of the old global
|
2012-03-31 03:44:53 +08:00
|
|
|
GV->takeName(OldGV);
|
2011-08-24 06:38:00 +08:00
|
|
|
|
2009-12-05 16:22:11 +08:00
|
|
|
// Replace all uses of the old global with the new global
|
2012-03-31 03:44:53 +08:00
|
|
|
llvm::Constant *NewPtrForOldDecl =
|
|
|
|
llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
|
|
|
|
OldGV->replaceAllUsesWith(NewPtrForOldDecl);
|
2011-08-24 06:38:00 +08:00
|
|
|
|
2009-12-05 16:22:11 +08:00
|
|
|
// Erase the old global, since it is no longer used.
|
2012-03-31 03:44:53 +08:00
|
|
|
OldGV->eraseFromParent();
|
2009-12-05 16:22:11 +08:00
|
|
|
}
|
2011-08-24 06:38:00 +08:00
|
|
|
|
2012-03-31 03:44:53 +08:00
|
|
|
GV->setConstant(CGM.isTypeConstant(D.getType(), true));
|
|
|
|
GV->setInitializer(Init);
|
2012-02-14 06:16:19 +08:00
|
|
|
|
|
|
|
if (hasNontrivialDestruction(D.getType())) {
|
|
|
|
// We have a constant initializer, but a nontrivial destructor. We still
|
|
|
|
// need to perform a guarded "initialization" in order to register the
|
2012-02-17 14:48:11 +08:00
|
|
|
// destructor.
|
2012-03-31 03:44:53 +08:00
|
|
|
EmitCXXGuardedInit(D, GV, /*PerformInit*/false);
|
2012-02-14 06:16:19 +08:00
|
|
|
}
|
|
|
|
|
2012-03-31 03:44:53 +08:00
|
|
|
return GV;
|
2009-12-05 16:22:11 +08:00
|
|
|
}
|
|
|
|
|
2010-10-15 12:57:14 +08:00
|
|
|
void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
|
2010-02-07 10:03:08 +08:00
|
|
|
llvm::GlobalValue::LinkageTypes Linkage) {
|
2012-03-31 05:00:39 +08:00
|
|
|
// Check to see if we already have a global variable for this
|
|
|
|
// declaration. This can happen when double-emitting function
|
|
|
|
// bodies, e.g. with complete and base constructors.
|
2014-10-08 09:07:54 +08:00
|
|
|
llvm::Constant *addr = CGM.getOrCreateStaticVarDecl(D, Linkage);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 alignment = getContext().getDeclAlign(&D);
|
2009-02-26 03:45:19 +08:00
|
|
|
|
2009-02-26 04:08:33 +08:00
|
|
|
// Store into LocalDeclMap before generating initializer to handle
|
|
|
|
// circular references.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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(&D, Address(addr, alignment));
|
2009-02-26 04:08:33 +08:00
|
|
|
|
2010-05-05 04:45:42 +08:00
|
|
|
// We can't have a VLA here, but we can have a pointer to a VLA,
|
|
|
|
// even though that doesn't really make any sense.
|
2009-04-20 11:54:15 +08:00
|
|
|
// Make sure to evaluate VLA bounds now so that we have them for later.
|
|
|
|
if (D.getType()->isVariablyModifiedType())
|
2011-06-25 05:55:10 +08:00
|
|
|
EmitVariablyModifiedType(D.getType());
|
2011-08-24 06:38:00 +08:00
|
|
|
|
2012-03-31 05:00:39 +08:00
|
|
|
// Save the type in case adding the initializer forces a type change.
|
|
|
|
llvm::Type *expectedType = addr->getType();
|
2009-04-20 11:54:15 +08:00
|
|
|
|
2014-03-25 06:05:38 +08:00
|
|
|
llvm::GlobalVariable *var =
|
|
|
|
cast<llvm::GlobalVariable>(addr->stripPointerCasts());
|
2009-12-05 16:22:11 +08:00
|
|
|
// If this value has an initializer, emit it.
|
|
|
|
if (D.getInit())
|
2012-03-31 05:00:39 +08:00
|
|
|
var = AddInitializerToStaticVarDecl(D, var);
|
2008-04-19 12:17:09 +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
|
|
|
var->setAlignment(alignment.getQuantity());
|
2010-03-11 07:59:59 +08:00
|
|
|
|
2011-09-10 06:41:49 +08:00
|
|
|
if (D.hasAttr<AnnotateAttr>())
|
2012-03-31 05:00:39 +08:00
|
|
|
CGM.AddGlobalAnnotations(&D, var);
|
2008-04-19 12:17:09 +08:00
|
|
|
|
2009-06-30 10:34:44 +08:00
|
|
|
if (const SectionAttr *SA = D.getAttr<SectionAttr>())
|
2012-03-31 05:00:39 +08:00
|
|
|
var->setSection(SA->getName());
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-06-30 10:34:44 +08:00
|
|
|
if (D.hasAttr<UsedAttr>())
|
2014-03-07 06:15:10 +08:00
|
|
|
CGM.addUsedGlobal(var);
|
2012-03-31 03:44:53 +08:00
|
|
|
|
|
|
|
// We may have to cast the constant because of the initializer
|
|
|
|
// mismatch above.
|
|
|
|
//
|
|
|
|
// FIXME: It is really dangerous to store this in the map; if anyone
|
|
|
|
// RAUW's the GV uses of this constant will be invalid.
|
2014-03-25 06:05:38 +08:00
|
|
|
llvm::Constant *castedAddr =
|
|
|
|
llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(var, expectedType);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 (var != castedAddr)
|
|
|
|
LocalDeclMap.find(&D)->second = Address(castedAddr, alignment);
|
2012-03-31 05:00:39 +08:00
|
|
|
CGM.setStaticLocalDeclAddress(&D, castedAddr);
|
2008-06-05 16:59:10 +08:00
|
|
|
|
2014-08-02 05:35:28 +08:00
|
|
|
CGM.getSanitizerMetadata()->reportGlobalToASan(var, D);
|
2014-07-03 00:54:41 +08:00
|
|
|
|
2008-06-05 16:59:10 +08:00
|
|
|
// Emit global variable debug descriptor for static vars.
|
2009-02-13 16:11:52 +08:00
|
|
|
CGDebugInfo *DI = getDebugInfo();
|
2012-05-04 15:39:27 +08:00
|
|
|
if (DI &&
|
2016-02-02 19:06:51 +08:00
|
|
|
CGM.getCodeGenOpts().getDebugInfo() >= codegenoptions::LimitedDebugInfo) {
|
2008-10-18 00:15:48 +08:00
|
|
|
DI->setLocation(D.getLocation());
|
2012-03-31 05:00:39 +08:00
|
|
|
DI->EmitGlobalVariable(var, &D);
|
2008-06-05 16:59:10 +08:00
|
|
|
}
|
2007-10-17 08:52:43 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-07-14 04:32:21 +08:00
|
|
|
namespace {
|
2015-08-19 06:40:54 +08:00
|
|
|
struct DestroyObject final : EHScopeStack::Cleanup {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
DestroyObject(Address addr, QualType type,
|
2011-07-11 16:38:19 +08:00
|
|
|
CodeGenFunction::Destroyer *destroyer,
|
|
|
|
bool useEHCleanupForArray)
|
2012-01-26 11:33:36 +08:00
|
|
|
: addr(addr), type(type), destroyer(destroyer),
|
2011-07-11 16:38:19 +08:00
|
|
|
useEHCleanupForArray(useEHCleanupForArray) {}
|
2010-07-14 04:32: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 addr;
|
2011-07-09 09:37:26 +08:00
|
|
|
QualType type;
|
2012-01-26 11:33:36 +08:00
|
|
|
CodeGenFunction::Destroyer *destroyer;
|
2011-07-11 16:38:19 +08:00
|
|
|
bool useEHCleanupForArray;
|
2010-07-14 04:32:21 +08:00
|
|
|
|
2014-03-12 14:41:41 +08:00
|
|
|
void Emit(CodeGenFunction &CGF, Flags flags) override {
|
2011-07-11 16:38:19 +08:00
|
|
|
// Don't use an EH cleanup recursively from an EH cleanup.
|
2011-07-13 04:27:29 +08:00
|
|
|
bool useEHCleanupForArray =
|
|
|
|
flags.isForNormalCleanup() && this->useEHCleanupForArray;
|
2011-07-11 16:38:19 +08:00
|
|
|
|
|
|
|
CGF.emitDestroy(addr, type, destroyer, useEHCleanupForArray);
|
2010-07-14 04:32:21 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-08-19 06:40:54 +08:00
|
|
|
struct DestroyNRVOVariable final : EHScopeStack::Cleanup {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
DestroyNRVOVariable(Address addr,
|
2011-07-09 09:37:26 +08:00
|
|
|
const CXXDestructorDecl *Dtor,
|
|
|
|
llvm::Value *NRVOFlag)
|
|
|
|
: Dtor(Dtor), NRVOFlag(NRVOFlag), Loc(addr) {}
|
2010-07-14 04:32:21 +08:00
|
|
|
|
|
|
|
const CXXDestructorDecl *Dtor;
|
|
|
|
llvm::Value *NRVOFlag;
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 Loc;
|
2010-07-14 04:32:21 +08:00
|
|
|
|
2014-03-12 14:41:41 +08:00
|
|
|
void Emit(CodeGenFunction &CGF, Flags flags) override {
|
2010-07-14 04:32:21 +08:00
|
|
|
// Along the exceptions path we always execute the dtor.
|
2011-07-13 04:27:29 +08:00
|
|
|
bool NRVO = flags.isForNormalCleanup() && NRVOFlag;
|
2010-07-14 04:32:21 +08:00
|
|
|
|
2014-05-21 13:09:00 +08:00
|
|
|
llvm::BasicBlock *SkipDtorBB = nullptr;
|
2010-07-14 04:32:21 +08:00
|
|
|
if (NRVO) {
|
|
|
|
// If we exited via NRVO, we skip the destructor call.
|
|
|
|
llvm::BasicBlock *RunDtorBB = CGF.createBasicBlock("nrvo.unused");
|
|
|
|
SkipDtorBB = CGF.createBasicBlock("nrvo.skipdtor");
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 *DidNRVO =
|
|
|
|
CGF.Builder.CreateFlagLoad(NRVOFlag, "nrvo.val");
|
2010-07-14 04:32:21 +08:00
|
|
|
CGF.Builder.CreateCondBr(DidNRVO, SkipDtorBB, RunDtorBB);
|
|
|
|
CGF.EmitBlock(RunDtorBB);
|
|
|
|
}
|
2011-08-24 06:38:00 +08:00
|
|
|
|
2010-07-14 04:32:21 +08:00
|
|
|
CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
|
2013-01-31 13:50:40 +08:00
|
|
|
/*ForVirtualBase=*/false,
|
|
|
|
/*Delegating=*/false,
|
|
|
|
Loc);
|
2010-07-14 04:32:21 +08:00
|
|
|
|
|
|
|
if (NRVO) CGF.EmitBlock(SkipDtorBB);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-08-19 06:40:54 +08:00
|
|
|
struct CallStackRestore final : EHScopeStack::Cleanup {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 Stack;
|
|
|
|
CallStackRestore(Address Stack) : Stack(Stack) {}
|
2014-03-12 14:41:41 +08:00
|
|
|
void Emit(CodeGenFunction &CGF, Flags flags) override {
|
2011-09-28 05:06:10 +08:00
|
|
|
llvm::Value *V = CGF.Builder.CreateLoad(Stack);
|
2010-07-21 14:13:08 +08:00
|
|
|
llvm::Value *F = CGF.CGM.getIntrinsic(llvm::Intrinsic::stackrestore);
|
|
|
|
CGF.Builder.CreateCall(F, V);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-08-19 06:40:54 +08:00
|
|
|
struct ExtendGCLifetime final : EHScopeStack::Cleanup {
|
2011-06-25 07:21:27 +08:00
|
|
|
const VarDecl &Var;
|
|
|
|
ExtendGCLifetime(const VarDecl *var) : Var(*var) {}
|
|
|
|
|
2014-03-12 14:41:41 +08:00
|
|
|
void Emit(CodeGenFunction &CGF, Flags flags) override {
|
2011-06-25 07:21:27 +08:00
|
|
|
// Compute the address of the local variable, in case it's a
|
|
|
|
// byref or something.
|
2012-03-10 17:33:50 +08:00
|
|
|
DeclRefExpr DRE(const_cast<VarDecl*>(&Var), false,
|
|
|
|
Var.getType(), VK_LValue, SourceLocation());
|
2013-10-02 10:29:49 +08:00
|
|
|
llvm::Value *value = CGF.EmitLoadOfScalar(CGF.EmitDeclRefLValue(&DRE),
|
|
|
|
SourceLocation());
|
2011-06-25 07:21:27 +08:00
|
|
|
CGF.EmitExtendGCLifetime(value);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-08-19 06:40:54 +08:00
|
|
|
struct CallCleanupFunction final : EHScopeStack::Cleanup {
|
2010-07-21 14:13:08 +08:00
|
|
|
llvm::Constant *CleanupFn;
|
|
|
|
const CGFunctionInfo &FnInfo;
|
|
|
|
const VarDecl &Var;
|
2011-08-24 06:38:00 +08:00
|
|
|
|
2010-07-21 14:13:08 +08:00
|
|
|
CallCleanupFunction(llvm::Constant *CleanupFn, const CGFunctionInfo *Info,
|
2011-02-22 14:44:22 +08:00
|
|
|
const VarDecl *Var)
|
|
|
|
: CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var) {}
|
2010-07-21 14:13:08 +08:00
|
|
|
|
2014-03-12 14:41:41 +08:00
|
|
|
void Emit(CodeGenFunction &CGF, Flags flags) override {
|
2012-03-10 17:33:50 +08:00
|
|
|
DeclRefExpr DRE(const_cast<VarDecl*>(&Var), false,
|
|
|
|
Var.getType(), VK_LValue, SourceLocation());
|
2011-02-22 14:44:22 +08:00
|
|
|
// Compute the address of the local variable, in case it's a byref
|
|
|
|
// or something.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 *Addr = CGF.EmitDeclRefLValue(&DRE).getPointer();
|
2011-02-22 14:44:22 +08:00
|
|
|
|
2010-07-21 14:13:08 +08:00
|
|
|
// In some cases, the type of the function argument will be different from
|
|
|
|
// the type of the pointer. An example of this is
|
|
|
|
// void f(void* arg);
|
|
|
|
// __attribute__((cleanup(f))) void *g;
|
|
|
|
//
|
|
|
|
// To fix this we insert a bitcast here.
|
|
|
|
QualType ArgTy = FnInfo.arg_begin()->type;
|
|
|
|
llvm::Value *Arg =
|
|
|
|
CGF.Builder.CreateBitCast(Addr, CGF.ConvertType(ArgTy));
|
|
|
|
|
|
|
|
CallArgList Args;
|
2011-05-03 01:57:46 +08:00
|
|
|
Args.add(RValue::get(Arg),
|
|
|
|
CGF.getContext().getPointerType(Var.getType()));
|
2010-07-21 14:13:08 +08:00
|
|
|
CGF.EmitCall(FnInfo, CleanupFn, ReturnValueSlot(), Args);
|
|
|
|
}
|
|
|
|
};
|
2014-07-22 03:47:02 +08:00
|
|
|
|
|
|
|
/// A cleanup to call @llvm.lifetime.end.
|
2015-08-19 06:40:54 +08:00
|
|
|
class CallLifetimeEnd final : public EHScopeStack::Cleanup {
|
2014-07-22 03:47:02 +08:00
|
|
|
llvm::Value *Addr;
|
|
|
|
llvm::Value *Size;
|
|
|
|
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
|
|
|
CallLifetimeEnd(Address addr, llvm::Value *size)
|
|
|
|
: Addr(addr.getPointer()), Size(size) {}
|
2014-07-22 03:47:02 +08:00
|
|
|
|
|
|
|
void Emit(CodeGenFunction &CGF, Flags flags) override {
|
2015-04-23 05:38:15 +08:00
|
|
|
CGF.EmitLifetimeEnd(Size, Addr);
|
2014-07-22 03:47:02 +08:00
|
|
|
}
|
|
|
|
};
|
2015-06-23 07:07:51 +08:00
|
|
|
}
|
2010-07-21 14:13:08 +08:00
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
/// EmitAutoVarWithLifetime - Does the setup required for an automatic
|
|
|
|
/// variable with lifetime.
|
|
|
|
static void EmitAutoVarWithLifetime(CodeGenFunction &CGF, const VarDecl &var,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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,
|
2011-06-16 07:02:42 +08:00
|
|
|
Qualifiers::ObjCLifetime lifetime) {
|
|
|
|
switch (lifetime) {
|
|
|
|
case Qualifiers::OCL_None:
|
|
|
|
llvm_unreachable("present but none");
|
|
|
|
|
|
|
|
case Qualifiers::OCL_ExplicitNone:
|
|
|
|
// nothing to do
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Qualifiers::OCL_Strong: {
|
2012-01-26 11:33:36 +08:00
|
|
|
CodeGenFunction::Destroyer *destroyer =
|
2011-07-13 00:41:08 +08:00
|
|
|
(var.hasAttr<ObjCPreciseLifetimeAttr>()
|
|
|
|
? CodeGenFunction::destroyARCStrongPrecise
|
|
|
|
: CodeGenFunction::destroyARCStrongImprecise);
|
|
|
|
|
|
|
|
CleanupKind cleanupKind = CGF.getARCCleanupKind();
|
|
|
|
CGF.pushDestroy(cleanupKind, addr, var.getType(), destroyer,
|
|
|
|
cleanupKind & EHCleanup);
|
2011-06-16 07:02:42 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Qualifiers::OCL_Autoreleasing:
|
|
|
|
// nothing to do
|
|
|
|
break;
|
2011-08-24 06:38:00 +08:00
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
case Qualifiers::OCL_Weak:
|
|
|
|
// __weak objects always get EH cleanups; otherwise, exceptions
|
|
|
|
// could cause really nasty crashes instead of mere leaks.
|
2011-07-13 00:41:08 +08:00
|
|
|
CGF.pushDestroy(NormalAndEHCleanup, addr, var.getType(),
|
|
|
|
CodeGenFunction::destroyARCWeak,
|
|
|
|
/*useEHCleanup*/ true);
|
2011-06-16 07:02:42 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool isAccessedBy(const VarDecl &var, const Stmt *s) {
|
|
|
|
if (const Expr *e = dyn_cast<Expr>(s)) {
|
|
|
|
// Skip the most common kinds of expressions that make
|
|
|
|
// hierarchy-walking expensive.
|
|
|
|
s = e = e->IgnoreParenCasts();
|
|
|
|
|
|
|
|
if (const DeclRefExpr *ref = dyn_cast<DeclRefExpr>(e))
|
|
|
|
return (ref->getDecl() == &var);
|
2012-06-20 04:53:26 +08:00
|
|
|
if (const BlockExpr *be = dyn_cast<BlockExpr>(e)) {
|
|
|
|
const BlockDecl *block = be->getBlockDecl();
|
2014-03-15 02:34:04 +08:00
|
|
|
for (const auto &I : block->captures()) {
|
|
|
|
if (I.getVariable() == &var)
|
2012-06-20 04:53:26 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2011-06-16 07:02:42 +08:00
|
|
|
}
|
|
|
|
|
2015-07-03 05:03:14 +08:00
|
|
|
for (const Stmt *SubStmt : s->children())
|
|
|
|
// SubStmt might be null; as in missing decl or conditional of an if-stmt.
|
|
|
|
if (SubStmt && isAccessedBy(var, SubStmt))
|
2011-06-16 07:02:42 +08:00
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool isAccessedBy(const ValueDecl *decl, const Expr *e) {
|
|
|
|
if (!decl) return false;
|
|
|
|
if (!isa<VarDecl>(decl)) return false;
|
|
|
|
const VarDecl *var = cast<VarDecl>(decl);
|
|
|
|
return isAccessedBy(*var, e);
|
|
|
|
}
|
|
|
|
|
2015-10-22 02:06:31 +08:00
|
|
|
static bool tryEmitARCCopyWeakInit(CodeGenFunction &CGF,
|
|
|
|
const LValue &destLV, const Expr *init) {
|
2015-11-17 06:11:41 +08:00
|
|
|
bool needsCast = false;
|
|
|
|
|
2015-10-22 02:06:31 +08:00
|
|
|
while (auto castExpr = dyn_cast<CastExpr>(init->IgnoreParens())) {
|
|
|
|
switch (castExpr->getCastKind()) {
|
|
|
|
// Look through casts that don't require representation changes.
|
|
|
|
case CK_NoOp:
|
|
|
|
case CK_BitCast:
|
|
|
|
case CK_BlockPointerToObjCPointerCast:
|
2015-11-17 06:11:41 +08:00
|
|
|
needsCast = true;
|
2015-10-22 02:06:31 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
// If we find an l-value to r-value cast from a __weak variable,
|
|
|
|
// emit this operation as a copy or move.
|
|
|
|
case CK_LValueToRValue: {
|
|
|
|
const Expr *srcExpr = castExpr->getSubExpr();
|
|
|
|
if (srcExpr->getType().getObjCLifetime() != Qualifiers::OCL_Weak)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Emit the source l-value.
|
|
|
|
LValue srcLV = CGF.EmitLValue(srcExpr);
|
|
|
|
|
2015-11-17 06:11:41 +08:00
|
|
|
// Handle a formal type change to avoid asserting.
|
|
|
|
auto srcAddr = srcLV.getAddress();
|
|
|
|
if (needsCast) {
|
|
|
|
srcAddr = CGF.Builder.CreateElementBitCast(srcAddr,
|
|
|
|
destLV.getAddress().getElementType());
|
|
|
|
}
|
|
|
|
|
2015-10-22 02:06:31 +08:00
|
|
|
// If it was an l-value, use objc_copyWeak.
|
|
|
|
if (srcExpr->getValueKind() == VK_LValue) {
|
2015-11-17 06:11:41 +08:00
|
|
|
CGF.EmitARCCopyWeak(destLV.getAddress(), srcAddr);
|
2015-10-22 02:06:31 +08:00
|
|
|
} else {
|
|
|
|
assert(srcExpr->getValueKind() == VK_XValue);
|
2015-11-17 06:11:41 +08:00
|
|
|
CGF.EmitARCMoveWeak(destLV.getAddress(), srcAddr);
|
2015-10-22 02:06:31 +08:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Stop at anything else.
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
init = castExpr->getSubExpr();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-06-16 12:16:24 +08:00
|
|
|
static void drillIntoBlockVariable(CodeGenFunction &CGF,
|
|
|
|
LValue &lvalue,
|
|
|
|
const VarDecl *var) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
lvalue.setAddress(CGF.emitBlockByrefAddress(lvalue.getAddress(), var));
|
2011-06-16 12:16:24 +08:00
|
|
|
}
|
|
|
|
|
2014-12-09 08:32:22 +08:00
|
|
|
void CodeGenFunction::EmitScalarInit(const Expr *init, const ValueDecl *D,
|
2015-01-14 15:38:27 +08:00
|
|
|
LValue lvalue, bool capturedByInit) {
|
2011-06-16 12:16:24 +08:00
|
|
|
Qualifiers::ObjCLifetime lifetime = lvalue.getObjCLifetime();
|
2011-06-16 07:02:42 +08:00
|
|
|
if (!lifetime) {
|
|
|
|
llvm::Value *value = EmitScalarExpr(init);
|
2011-06-16 12:16:24 +08:00
|
|
|
if (capturedByInit)
|
|
|
|
drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
|
2015-01-14 15:38:27 +08:00
|
|
|
EmitStoreThroughLValue(RValue::get(value), lvalue, true);
|
2011-06-16 07:02:42 +08:00
|
|
|
return;
|
|
|
|
}
|
2014-03-14 23:40:54 +08:00
|
|
|
|
|
|
|
if (const CXXDefaultInitExpr *DIE = dyn_cast<CXXDefaultInitExpr>(init))
|
|
|
|
init = DIE->getExpr();
|
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
// If we're emitting a value with lifetime, we have to do the
|
|
|
|
// initialization *before* we leave the cleanup scopes.
|
2011-11-10 16:15:53 +08:00
|
|
|
if (const ExprWithCleanups *ewc = dyn_cast<ExprWithCleanups>(init)) {
|
|
|
|
enterFullExpression(ewc);
|
2011-06-16 07:02:42 +08:00
|
|
|
init = ewc->getSubExpr();
|
2011-11-10 16:15:53 +08:00
|
|
|
}
|
|
|
|
CodeGenFunction::RunCleanupsScope Scope(*this);
|
2011-06-16 07:02:42 +08:00
|
|
|
|
|
|
|
// We have to maintain the illusion that the variable is
|
|
|
|
// zero-initialized. If the variable might be accessed in its
|
|
|
|
// initializer, zero-initialize before running the initializer, then
|
|
|
|
// actually perform the initialization with an assign.
|
|
|
|
bool accessedByInit = false;
|
|
|
|
if (lifetime != Qualifiers::OCL_ExplicitNone)
|
2011-07-28 15:23:35 +08:00
|
|
|
accessedByInit = (capturedByInit || isAccessedBy(D, init));
|
2011-06-16 07:02:42 +08:00
|
|
|
if (accessedByInit) {
|
2011-06-16 12:16:24 +08:00
|
|
|
LValue tempLV = lvalue;
|
2011-06-16 07:02:42 +08:00
|
|
|
// Drill down to the __block object if necessary.
|
|
|
|
if (capturedByInit) {
|
|
|
|
// We can use a simple GEP for this because it can't have been
|
|
|
|
// moved yet.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
tempLV.setAddress(emitBlockByrefAddress(tempLV.getAddress(),
|
|
|
|
cast<VarDecl>(D),
|
|
|
|
/*follow*/ false));
|
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
|
|
|
auto ty = cast<llvm::PointerType>(tempLV.getAddress().getElementType());
|
2011-06-16 07:02:42 +08:00
|
|
|
llvm::Value *zero = llvm::ConstantPointerNull::get(ty);
|
2011-08-24 06:38:00 +08:00
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
// If __weak, we want to use a barrier under certain conditions.
|
|
|
|
if (lifetime == Qualifiers::OCL_Weak)
|
2011-06-16 12:16:24 +08:00
|
|
|
EmitARCInitWeak(tempLV.getAddress(), zero);
|
2011-06-16 07:02:42 +08:00
|
|
|
|
|
|
|
// Otherwise just do a simple store.
|
|
|
|
else
|
2012-01-17 01:27:18 +08:00
|
|
|
EmitStoreOfScalar(zero, tempLV, /* isInitialization */ true);
|
2011-06-16 07:02:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Emit the initializer.
|
2014-05-21 13:09:00 +08:00
|
|
|
llvm::Value *value = nullptr;
|
2011-06-16 07:02:42 +08:00
|
|
|
|
|
|
|
switch (lifetime) {
|
|
|
|
case Qualifiers::OCL_None:
|
|
|
|
llvm_unreachable("present but none");
|
|
|
|
|
|
|
|
case Qualifiers::OCL_ExplicitNone:
|
2016-01-28 02:32:30 +08:00
|
|
|
value = EmitARCUnsafeUnretainedScalarExpr(init);
|
2011-06-16 07:02:42 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case Qualifiers::OCL_Strong: {
|
|
|
|
value = EmitARCRetainScalarExpr(init);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case Qualifiers::OCL_Weak: {
|
2015-10-22 02:06:31 +08:00
|
|
|
// If it's not accessed by the initializer, try to emit the
|
|
|
|
// initialization with a copy or move.
|
|
|
|
if (!accessedByInit && tryEmitARCCopyWeakInit(*this, lvalue, init)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
// No way to optimize a producing initializer into this. It's not
|
|
|
|
// worth optimizing for, because the value will immediately
|
|
|
|
// disappear in the common case.
|
|
|
|
value = EmitScalarExpr(init);
|
|
|
|
|
2011-06-16 12:16:24 +08:00
|
|
|
if (capturedByInit) drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
|
2011-06-16 07:02:42 +08:00
|
|
|
if (accessedByInit)
|
2011-06-16 12:16:24 +08:00
|
|
|
EmitARCStoreWeak(lvalue.getAddress(), value, /*ignored*/ true);
|
2011-06-16 07:02:42 +08:00
|
|
|
else
|
2011-06-16 12:16:24 +08:00
|
|
|
EmitARCInitWeak(lvalue.getAddress(), value);
|
2011-06-16 07:02:42 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
case Qualifiers::OCL_Autoreleasing:
|
|
|
|
value = EmitARCRetainAutoreleaseScalarExpr(init);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2011-06-16 12:16:24 +08:00
|
|
|
if (capturedByInit) drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
|
2011-06-16 07:02:42 +08:00
|
|
|
|
|
|
|
// If the variable might have been accessed by its initializer, we
|
|
|
|
// might have to initialize with a barrier. We have to do this for
|
|
|
|
// both __weak and __strong, but __weak got filtered out above.
|
|
|
|
if (accessedByInit && lifetime == Qualifiers::OCL_Strong) {
|
2013-10-02 10:29:49 +08:00
|
|
|
llvm::Value *oldValue = EmitLoadOfScalar(lvalue, init->getExprLoc());
|
2012-01-17 01:27:18 +08:00
|
|
|
EmitStoreOfScalar(value, lvalue, /* isInitialization */ true);
|
2013-03-13 11:10:54 +08:00
|
|
|
EmitARCRelease(oldValue, ARCImpreciseLifetime);
|
2011-06-16 07:02:42 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-01-17 01:27:18 +08:00
|
|
|
EmitStoreOfScalar(value, lvalue, /* isInitialization */ true);
|
2011-06-16 07:02:42 +08:00
|
|
|
}
|
2010-12-01 10:05:19 +08:00
|
|
|
|
2011-06-17 14:42:21 +08:00
|
|
|
/// EmitScalarInit - Initialize the given lvalue with the given object.
|
|
|
|
void CodeGenFunction::EmitScalarInit(llvm::Value *init, LValue lvalue) {
|
|
|
|
Qualifiers::ObjCLifetime lifetime = lvalue.getObjCLifetime();
|
|
|
|
if (!lifetime)
|
2012-01-17 01:27:18 +08:00
|
|
|
return EmitStoreThroughLValue(RValue::get(init), lvalue, true);
|
2011-06-17 14:42:21 +08:00
|
|
|
|
|
|
|
switch (lifetime) {
|
|
|
|
case Qualifiers::OCL_None:
|
|
|
|
llvm_unreachable("present but none");
|
|
|
|
|
|
|
|
case Qualifiers::OCL_ExplicitNone:
|
|
|
|
// nothing to do
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Qualifiers::OCL_Strong:
|
|
|
|
init = EmitARCRetain(lvalue.getType(), init);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Qualifiers::OCL_Weak:
|
|
|
|
// Initialize and then skip the primitive store.
|
|
|
|
EmitARCInitWeak(lvalue.getAddress(), init);
|
|
|
|
return;
|
|
|
|
|
|
|
|
case Qualifiers::OCL_Autoreleasing:
|
|
|
|
init = EmitARCRetainAutorelease(lvalue.getType(), init);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2012-01-17 01:27:18 +08:00
|
|
|
EmitStoreOfScalar(init, lvalue, /* isInitialization */ true);
|
2011-06-17 14:42:21 +08:00
|
|
|
}
|
|
|
|
|
2010-12-01 10:05:19 +08:00
|
|
|
/// canEmitInitWithFewStoresAfterMemset - Decide whether we can emit the
|
|
|
|
/// non-zero parts of the specified initializer with equal or fewer than
|
|
|
|
/// NumStores scalar stores.
|
|
|
|
static bool canEmitInitWithFewStoresAfterMemset(llvm::Constant *Init,
|
|
|
|
unsigned &NumStores) {
|
Enhance the init generation logic to emit a memset followed by a few stores when
a global is larger than 32 bytes and has fewer than 6 non-zero values in the
initializer. Previously we'd turn something like this:
char test8(int X) {
char str[10000] = "abc";
into a 10K global variable which we then memcpy'd from. Now we generate:
%str = alloca [10000 x i8], align 16
%tmp = getelementptr inbounds [10000 x i8]* %str, i64 0, i64 0
call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 10000, i32 16, i1 false)
store i8 97, i8* %tmp, align 16
%0 = getelementptr [10000 x i8]* %str, i64 0, i64 1
store i8 98, i8* %0, align 1
%1 = getelementptr [10000 x i8]* %str, i64 0, i64 2
store i8 99, i8* %1, align 2
Which is much smaller in space and also likely faster.
This is part of PR279
llvm-svn: 120645
2010-12-02 09:58:41 +08:00
|
|
|
// Zero and Undef never requires any extra stores.
|
|
|
|
if (isa<llvm::ConstantAggregateZero>(Init) ||
|
|
|
|
isa<llvm::ConstantPointerNull>(Init) ||
|
|
|
|
isa<llvm::UndefValue>(Init))
|
|
|
|
return true;
|
|
|
|
if (isa<llvm::ConstantInt>(Init) || isa<llvm::ConstantFP>(Init) ||
|
|
|
|
isa<llvm::ConstantVector>(Init) || isa<llvm::BlockAddress>(Init) ||
|
|
|
|
isa<llvm::ConstantExpr>(Init))
|
|
|
|
return Init->isNullValue() || NumStores--;
|
|
|
|
|
|
|
|
// See if we can emit each element.
|
|
|
|
if (isa<llvm::ConstantArray>(Init) || isa<llvm::ConstantStruct>(Init)) {
|
|
|
|
for (unsigned i = 0, e = Init->getNumOperands(); i != e; ++i) {
|
|
|
|
llvm::Constant *Elt = cast<llvm::Constant>(Init->getOperand(i));
|
|
|
|
if (!canEmitInitWithFewStoresAfterMemset(Elt, NumStores))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2012-01-31 12:36:19 +08:00
|
|
|
|
|
|
|
if (llvm::ConstantDataSequential *CDS =
|
|
|
|
dyn_cast<llvm::ConstantDataSequential>(Init)) {
|
|
|
|
for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
|
|
|
|
llvm::Constant *Elt = CDS->getElementAsConstant(i);
|
|
|
|
if (!canEmitInitWithFewStoresAfterMemset(Elt, NumStores))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2011-08-24 06:38:00 +08:00
|
|
|
|
2010-12-01 10:05:19 +08:00
|
|
|
// Anything else is hard and scary.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// emitStoresForInitAfterMemset - For inits that
|
|
|
|
/// canEmitInitWithFewStoresAfterMemset returned true for, emit the scalar
|
|
|
|
/// stores that would be required.
|
|
|
|
static void emitStoresForInitAfterMemset(llvm::Constant *Init, llvm::Value *Loc,
|
2011-02-22 14:44:22 +08:00
|
|
|
bool isVolatile, CGBuilderTy &Builder) {
|
2012-08-28 06:07:02 +08:00
|
|
|
assert(!Init->isNullValue() && !isa<llvm::UndefValue>(Init) &&
|
|
|
|
"called emitStoresForInitAfterMemset for zero or undef value.");
|
2011-08-24 06:38:00 +08:00
|
|
|
|
Enhance the init generation logic to emit a memset followed by a few stores when
a global is larger than 32 bytes and has fewer than 6 non-zero values in the
initializer. Previously we'd turn something like this:
char test8(int X) {
char str[10000] = "abc";
into a 10K global variable which we then memcpy'd from. Now we generate:
%str = alloca [10000 x i8], align 16
%tmp = getelementptr inbounds [10000 x i8]* %str, i64 0, i64 0
call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 10000, i32 16, i1 false)
store i8 97, i8* %tmp, align 16
%0 = getelementptr [10000 x i8]* %str, i64 0, i64 1
store i8 98, i8* %0, align 1
%1 = getelementptr [10000 x i8]* %str, i64 0, i64 2
store i8 99, i8* %1, align 2
Which is much smaller in space and also likely faster.
This is part of PR279
llvm-svn: 120645
2010-12-02 09:58:41 +08:00
|
|
|
if (isa<llvm::ConstantInt>(Init) || isa<llvm::ConstantFP>(Init) ||
|
|
|
|
isa<llvm::ConstantVector>(Init) || isa<llvm::BlockAddress>(Init) ||
|
|
|
|
isa<llvm::ConstantExpr>(Init)) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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.CreateDefaultAlignedStore(Init, Loc, isVolatile);
|
2012-01-31 12:36:19 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (llvm::ConstantDataSequential *CDS =
|
|
|
|
dyn_cast<llvm::ConstantDataSequential>(Init)) {
|
|
|
|
for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
|
|
|
|
llvm::Constant *Elt = CDS->getElementAsConstant(i);
|
2012-08-28 05:35:58 +08:00
|
|
|
|
|
|
|
// If necessary, get a pointer to the element and emit it.
|
|
|
|
if (!Elt->isNullValue() && !isa<llvm::UndefValue>(Elt))
|
2015-04-05 05:07:17 +08:00
|
|
|
emitStoresForInitAfterMemset(
|
|
|
|
Elt, Builder.CreateConstGEP2_32(Init->getType(), Loc, 0, i),
|
|
|
|
isVolatile, Builder);
|
2012-01-31 12:36:19 +08:00
|
|
|
}
|
Enhance the init generation logic to emit a memset followed by a few stores when
a global is larger than 32 bytes and has fewer than 6 non-zero values in the
initializer. Previously we'd turn something like this:
char test8(int X) {
char str[10000] = "abc";
into a 10K global variable which we then memcpy'd from. Now we generate:
%str = alloca [10000 x i8], align 16
%tmp = getelementptr inbounds [10000 x i8]* %str, i64 0, i64 0
call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 10000, i32 16, i1 false)
store i8 97, i8* %tmp, align 16
%0 = getelementptr [10000 x i8]* %str, i64 0, i64 1
store i8 98, i8* %0, align 1
%1 = getelementptr [10000 x i8]* %str, i64 0, i64 2
store i8 99, i8* %1, align 2
Which is much smaller in space and also likely faster.
This is part of PR279
llvm-svn: 120645
2010-12-02 09:58:41 +08:00
|
|
|
return;
|
|
|
|
}
|
2011-08-24 06:38:00 +08:00
|
|
|
|
Enhance the init generation logic to emit a memset followed by a few stores when
a global is larger than 32 bytes and has fewer than 6 non-zero values in the
initializer. Previously we'd turn something like this:
char test8(int X) {
char str[10000] = "abc";
into a 10K global variable which we then memcpy'd from. Now we generate:
%str = alloca [10000 x i8], align 16
%tmp = getelementptr inbounds [10000 x i8]* %str, i64 0, i64 0
call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 10000, i32 16, i1 false)
store i8 97, i8* %tmp, align 16
%0 = getelementptr [10000 x i8]* %str, i64 0, i64 1
store i8 98, i8* %0, align 1
%1 = getelementptr [10000 x i8]* %str, i64 0, i64 2
store i8 99, i8* %1, align 2
Which is much smaller in space and also likely faster.
This is part of PR279
llvm-svn: 120645
2010-12-02 09:58:41 +08:00
|
|
|
assert((isa<llvm::ConstantStruct>(Init) || isa<llvm::ConstantArray>(Init)) &&
|
|
|
|
"Unknown value type!");
|
2011-08-24 06:38:00 +08:00
|
|
|
|
Enhance the init generation logic to emit a memset followed by a few stores when
a global is larger than 32 bytes and has fewer than 6 non-zero values in the
initializer. Previously we'd turn something like this:
char test8(int X) {
char str[10000] = "abc";
into a 10K global variable which we then memcpy'd from. Now we generate:
%str = alloca [10000 x i8], align 16
%tmp = getelementptr inbounds [10000 x i8]* %str, i64 0, i64 0
call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 10000, i32 16, i1 false)
store i8 97, i8* %tmp, align 16
%0 = getelementptr [10000 x i8]* %str, i64 0, i64 1
store i8 98, i8* %0, align 1
%1 = getelementptr [10000 x i8]* %str, i64 0, i64 2
store i8 99, i8* %1, align 2
Which is much smaller in space and also likely faster.
This is part of PR279
llvm-svn: 120645
2010-12-02 09:58:41 +08:00
|
|
|
for (unsigned i = 0, e = Init->getNumOperands(); i != e; ++i) {
|
|
|
|
llvm::Constant *Elt = cast<llvm::Constant>(Init->getOperand(i));
|
2012-08-28 05:35:58 +08:00
|
|
|
|
|
|
|
// If necessary, get a pointer to the element and emit it.
|
|
|
|
if (!Elt->isNullValue() && !isa<llvm::UndefValue>(Elt))
|
2015-04-05 05:07:17 +08:00
|
|
|
emitStoresForInitAfterMemset(
|
|
|
|
Elt, Builder.CreateConstGEP2_32(Init->getType(), Loc, 0, i),
|
|
|
|
isVolatile, Builder);
|
Enhance the init generation logic to emit a memset followed by a few stores when
a global is larger than 32 bytes and has fewer than 6 non-zero values in the
initializer. Previously we'd turn something like this:
char test8(int X) {
char str[10000] = "abc";
into a 10K global variable which we then memcpy'd from. Now we generate:
%str = alloca [10000 x i8], align 16
%tmp = getelementptr inbounds [10000 x i8]* %str, i64 0, i64 0
call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 10000, i32 16, i1 false)
store i8 97, i8* %tmp, align 16
%0 = getelementptr [10000 x i8]* %str, i64 0, i64 1
store i8 98, i8* %0, align 1
%1 = getelementptr [10000 x i8]* %str, i64 0, i64 2
store i8 99, i8* %1, align 2
Which is much smaller in space and also likely faster.
This is part of PR279
llvm-svn: 120645
2010-12-02 09:58:41 +08:00
|
|
|
}
|
2010-12-01 10:05:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// shouldUseMemSetPlusStoresToInitialize - Decide whether we should use memset
|
|
|
|
/// plus some stores to initialize a local variable instead of using a memcpy
|
|
|
|
/// from a constant global. It is beneficial to use memset if the global is all
|
|
|
|
/// zeros, or mostly zeros and large.
|
|
|
|
static bool shouldUseMemSetPlusStoresToInitialize(llvm::Constant *Init,
|
|
|
|
uint64_t GlobalSize) {
|
|
|
|
// If a global is all zeros, always use a memset.
|
|
|
|
if (isa<llvm::ConstantAggregateZero>(Init)) return true;
|
|
|
|
|
|
|
|
// If a non-zero global is <= 32 bytes, always use a memcpy. If it is large,
|
|
|
|
// do it if it will require 6 or fewer scalar stores.
|
|
|
|
// TODO: Should budget depends on the size? Avoiding a large global warrants
|
|
|
|
// plopping in more stores.
|
|
|
|
unsigned StoreBudget = 6;
|
|
|
|
uint64_t SizeLimit = 32;
|
2011-08-24 06:38:00 +08:00
|
|
|
|
|
|
|
return GlobalSize > SizeLimit &&
|
2010-12-01 10:05:19 +08:00
|
|
|
canEmitInitWithFewStoresAfterMemset(Init, StoreBudget);
|
|
|
|
}
|
|
|
|
|
2010-12-31 04:21:55 +08:00
|
|
|
/// EmitAutoVarDecl - Emit code and set up an entry in LocalDeclMap for a
|
2007-06-02 12:53:11 +08:00
|
|
|
/// variable declaration with auto, register, or no storage class specifier.
|
2008-05-08 13:58:21 +08:00
|
|
|
/// These turn into simple stack objects, or GlobalValues depending on target.
|
2011-02-22 14:44:22 +08:00
|
|
|
void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D) {
|
|
|
|
AutoVarEmission emission = EmitAutoVarAlloca(D);
|
|
|
|
EmitAutoVarInit(emission);
|
|
|
|
EmitAutoVarCleanups(emission);
|
|
|
|
}
|
|
|
|
|
2015-04-23 05:38:15 +08:00
|
|
|
/// Emit a lifetime.begin marker if some criteria are satisfied.
|
|
|
|
/// \return a pointer to the temporary size Value if a marker was emitted, null
|
|
|
|
/// otherwise
|
|
|
|
llvm::Value *CodeGenFunction::EmitLifetimeStart(uint64_t Size,
|
|
|
|
llvm::Value *Addr) {
|
|
|
|
// For now, only in optimized builds.
|
|
|
|
if (CGM.getCodeGenOpts().OptimizationLevel == 0)
|
|
|
|
return nullptr;
|
2015-04-24 02:07:13 +08:00
|
|
|
|
|
|
|
// Disable lifetime markers in msan builds.
|
|
|
|
// FIXME: Remove this when msan works with lifetime markers.
|
|
|
|
if (getLangOpts().Sanitize.has(SanitizerKind::Memory))
|
|
|
|
return nullptr;
|
2015-04-23 05:38:15 +08:00
|
|
|
|
|
|
|
llvm::Value *SizeV = llvm::ConstantInt::get(Int64Ty, Size);
|
2015-06-13 06:31:32 +08:00
|
|
|
Addr = Builder.CreateBitCast(Addr, Int8PtrTy);
|
|
|
|
llvm::CallInst *C =
|
|
|
|
Builder.CreateCall(CGM.getLLVMLifetimeStartFn(), {SizeV, Addr});
|
2015-04-23 05:38:15 +08:00
|
|
|
C->setDoesNotThrow();
|
|
|
|
return SizeV;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) {
|
2015-06-13 06:31:32 +08:00
|
|
|
Addr = Builder.CreateBitCast(Addr, Int8PtrTy);
|
|
|
|
llvm::CallInst *C =
|
|
|
|
Builder.CreateCall(CGM.getLLVMLifetimeEndFn(), {Size, Addr});
|
2015-04-23 05:38:15 +08:00
|
|
|
C->setDoesNotThrow();
|
|
|
|
}
|
|
|
|
|
2011-02-22 14:44:22 +08:00
|
|
|
/// EmitAutoVarAlloca - Emit the alloca and debug information for a
|
2013-12-06 00:25:25 +08:00
|
|
|
/// local variable. Does not emit initialization or destruction.
|
2011-02-22 14:44:22 +08:00
|
|
|
CodeGenFunction::AutoVarEmission
|
|
|
|
CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
|
2008-04-07 07:10:54 +08:00
|
|
|
QualType Ty = D.getType();
|
2011-02-22 14:44:22 +08:00
|
|
|
|
|
|
|
AutoVarEmission emission(D);
|
|
|
|
|
2009-06-30 10:34:44 +08:00
|
|
|
bool isByRef = D.hasAttr<BlocksAttr>();
|
2011-02-22 14:44:22 +08:00
|
|
|
emission.IsByRef = isByRef;
|
|
|
|
|
|
|
|
CharUnits alignment = getContext().getDeclAlign(&D);
|
2007-06-02 12:53:11 +08:00
|
|
|
|
2011-06-25 05:55:10 +08:00
|
|
|
// If the type is variably-modified, emit all the VLA sizes for it.
|
|
|
|
if (Ty->isVariablyModifiedType())
|
|
|
|
EmitVariablyModifiedType(Ty);
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 address = Address::invalid();
|
2008-02-15 20:20:59 +08:00
|
|
|
if (Ty->isConstantSizeType()) {
|
2013-03-27 02:41:47 +08:00
|
|
|
bool NRVO = getLangOpts().ElideConstructors &&
|
|
|
|
D.isNRVOVariable();
|
|
|
|
|
2013-06-02 08:09:52 +08:00
|
|
|
// If this value is an array or struct with a statically determinable
|
|
|
|
// constant initializer, there are optimizations we can do.
|
2013-03-27 02:41:47 +08:00
|
|
|
//
|
|
|
|
// TODO: We should constant-evaluate the initializer of any variable,
|
|
|
|
// as long as it is initialized by a constant expression. Currently,
|
|
|
|
// isConstantInitializer produces wrong answers for structs with
|
|
|
|
// reference or bitfield members, and a few other cases, and checking
|
|
|
|
// for POD-ness protects us from some of these.
|
2013-06-02 08:09:52 +08:00
|
|
|
if (D.getInit() && (Ty->isArrayType() || Ty->isRecordType()) &&
|
|
|
|
(D.isConstexpr() ||
|
|
|
|
((Ty.isPODType(getContext()) ||
|
|
|
|
getContext().getBaseElementType(Ty)->isObjCObjectPointerType()) &&
|
|
|
|
D.getInit()->isConstantInitializer(getContext(), false)))) {
|
2013-03-27 02:41:47 +08:00
|
|
|
|
|
|
|
// If the variable's a const type, and it's neither an NRVO
|
|
|
|
// candidate nor a __block variable and has no mutable members,
|
|
|
|
// emit it as a global instead.
|
|
|
|
if (CGM.getCodeGenOpts().MergeAllConstants && !NRVO && !isByRef &&
|
|
|
|
CGM.isTypeConstant(Ty, true)) {
|
|
|
|
EmitStaticVarDecl(D, llvm::GlobalValue::InternalLinkage);
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
// Signal this condition to later callbacks.
|
|
|
|
emission.Addr = Address::invalid();
|
2013-03-27 02:41:47 +08:00
|
|
|
assert(emission.wasEmittedAsGlobal());
|
|
|
|
return emission;
|
2009-11-04 09:18:09 +08:00
|
|
|
}
|
2011-08-24 06:38:00 +08:00
|
|
|
|
2013-03-27 02:41:47 +08:00
|
|
|
// Otherwise, tell the initialization code that we're in this case.
|
|
|
|
emission.IsConstantAggregate = true;
|
|
|
|
}
|
2011-08-24 06:38:00 +08:00
|
|
|
|
2013-03-27 02:41:47 +08:00
|
|
|
// A normal fixed sized variable becomes an alloca in the entry block,
|
|
|
|
// unless it's an NRVO variable.
|
|
|
|
|
|
|
|
if (NRVO) {
|
|
|
|
// The named return value optimization: allocate this variable in the
|
|
|
|
// return slot, so that we can elide the copy when returning this
|
|
|
|
// variable (C++0x [class.copy]p34).
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 = ReturnValue;
|
2013-03-27 02:41:47 +08:00
|
|
|
|
|
|
|
if (const RecordType *RecordTy = Ty->getAs<RecordType>()) {
|
|
|
|
if (!cast<CXXRecordDecl>(RecordTy->getDecl())->hasTrivialDestructor()) {
|
|
|
|
// Create a flag that is used to indicate when the NRVO was applied
|
|
|
|
// to this variable. Set it to zero to indicate that NRVO was not
|
|
|
|
// applied.
|
|
|
|
llvm::Value *Zero = Builder.getFalse();
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 NRVOFlag =
|
|
|
|
CreateTempAlloca(Zero->getType(), CharUnits::One(), "nrvo");
|
2013-03-27 02:41:47 +08:00
|
|
|
EnsureInsertPoint();
|
|
|
|
Builder.CreateStore(Zero, NRVOFlag);
|
|
|
|
|
|
|
|
// Record the NRVO flag for this 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
|
|
|
NRVOFlags[&D] = NRVOFlag.getPointer();
|
|
|
|
emission.NRVOFlag = NRVOFlag.getPointer();
|
2013-03-23 14:43:35 +08:00
|
|
|
}
|
2010-05-15 14:46:45 +08:00
|
|
|
}
|
2008-05-08 13:58:21 +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
|
|
|
CharUnits allocaAlignment;
|
|
|
|
llvm::Type *allocaTy;
|
|
|
|
if (isByRef) {
|
|
|
|
auto &byrefInfo = getBlockByrefInfo(&D);
|
|
|
|
allocaTy = byrefInfo.Type;
|
|
|
|
allocaAlignment = byrefInfo.ByrefAlignment;
|
|
|
|
} else {
|
|
|
|
allocaTy = ConvertTypeForMem(Ty);
|
|
|
|
allocaAlignment = alignment;
|
|
|
|
}
|
2013-03-27 02:41:47 +08:00
|
|
|
|
2015-09-08 17:18:30 +08:00
|
|
|
// Create the alloca. Note that we set the name separately from
|
|
|
|
// building the instruction so that it's there even in no-asserts
|
|
|
|
// builds.
|
|
|
|
address = CreateTempAlloca(allocaTy, allocaAlignment);
|
|
|
|
address.getPointer()->setName(D.getName());
|
2013-03-27 02:41:47 +08:00
|
|
|
|
2015-10-08 05:03:41 +08:00
|
|
|
// Don't emit lifetime markers for MSVC catch parameters. The lifetime of
|
|
|
|
// the catch parameter starts in the catchpad instruction, and we can't
|
|
|
|
// insert code in those basic blocks.
|
|
|
|
bool IsMSCatchParam =
|
|
|
|
D.isExceptionVariable() && getTarget().getCXXABI().isMicrosoft();
|
|
|
|
|
2013-03-27 02:41:47 +08:00
|
|
|
// Emit a lifetime intrinsic if meaningful. There's no point
|
|
|
|
// in doing this if we don't have a valid insertion point (?).
|
2015-10-08 05:03:41 +08:00
|
|
|
if (HaveInsertPoint() && !IsMSCatchParam) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
uint64_t size = CGM.getDataLayout().getTypeAllocSize(allocaTy);
|
|
|
|
emission.SizeForLifetimeMarkers =
|
|
|
|
EmitLifetimeStart(size, address.getPointer());
|
2014-10-08 22:04:26 +08:00
|
|
|
} else {
|
2013-03-27 02:41:47 +08:00
|
|
|
assert(!emission.useLifetimeMarkers());
|
2014-10-08 22:04:26 +08:00
|
|
|
}
|
2008-05-08 13:58:21 +08:00
|
|
|
}
|
2007-06-02 12:53:11 +08:00
|
|
|
} else {
|
2009-07-19 14:58:07 +08:00
|
|
|
EnsureInsertPoint();
|
|
|
|
|
2009-02-10 04:41:50 +08:00
|
|
|
if (!DidCallStackSave) {
|
2008-12-12 15:38:43 +08:00
|
|
|
// Save the stack.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 Stack =
|
|
|
|
CreateTempAlloca(Int8PtrTy, getPointerAlign(), "saved_stack");
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2008-12-12 15:38:43 +08:00
|
|
|
llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::stacksave);
|
2015-07-15 01:27:39 +08:00
|
|
|
llvm::Value *V = Builder.CreateCall(F);
|
2008-12-12 15:38:43 +08:00
|
|
|
Builder.CreateStore(V, Stack);
|
2009-02-10 04:41:50 +08:00
|
|
|
|
|
|
|
DidCallStackSave = true;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-07-21 14:13:08 +08:00
|
|
|
// Push a cleanup block and restore the stack there.
|
2011-01-28 16:37:24 +08:00
|
|
|
// FIXME: in general circumstances, this should be an EH cleanup.
|
2014-02-01 08:04:45 +08:00
|
|
|
pushStackRestore(NormalCleanup, Stack);
|
2008-12-12 15:38:43 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2011-06-25 05:55:10 +08:00
|
|
|
llvm::Value *elementCount;
|
|
|
|
QualType elementType;
|
2014-03-02 21:01:17 +08:00
|
|
|
std::tie(elementCount, elementType) = getVLASize(Ty);
|
2008-12-12 15:38:43 +08:00
|
|
|
|
2011-07-18 12:24:23 +08:00
|
|
|
llvm::Type *llvmTy = ConvertTypeForMem(elementType);
|
2008-12-12 15:38:43 +08:00
|
|
|
|
|
|
|
// Allocate memory for the array.
|
2011-06-25 05:55:10 +08:00
|
|
|
llvm::AllocaInst *vla = Builder.CreateAlloca(llvmTy, elementCount, "vla");
|
|
|
|
vla->setAlignment(alignment.getQuantity());
|
2009-09-27 02:16: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
|
|
|
address = Address(vla, alignment);
|
2007-06-02 12:53:11 +08:00
|
|
|
}
|
2008-12-21 07:11:59 +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(&D, address);
|
|
|
|
emission.Addr = address;
|
2008-05-30 18:30:31 +08:00
|
|
|
|
|
|
|
// Emit debug info for local var declaration.
|
2011-06-04 03:21:47 +08:00
|
|
|
if (HaveInsertPoint())
|
|
|
|
if (CGDebugInfo *DI = getDebugInfo()) {
|
2016-02-02 19:06:51 +08:00
|
|
|
if (CGM.getCodeGenOpts().getDebugInfo() >=
|
|
|
|
codegenoptions::LimitedDebugInfo) {
|
2012-05-04 15:39:27 +08:00
|
|
|
DI->setLocation(D.getLocation());
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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->EmitDeclareOfAutoVariable(&D, address.getPointer(), Builder);
|
2012-05-04 15:39:27 +08:00
|
|
|
}
|
2011-06-04 03:21:47 +08:00
|
|
|
}
|
2008-05-30 18:30:31 +08:00
|
|
|
|
2011-09-10 06:41:49 +08:00
|
|
|
if (D.hasAttr<AnnotateAttr>())
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
EmitVarAnnotations(&D, address.getPointer());
|
2011-09-10 06:41:49 +08:00
|
|
|
|
2011-02-22 14:44:22 +08:00
|
|
|
return emission;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Determines whether the given __block variable is potentially
|
|
|
|
/// captured by the given expression.
|
|
|
|
static bool isCapturedBy(const VarDecl &var, const Expr *e) {
|
|
|
|
// Skip the most common kinds of expressions that make
|
|
|
|
// hierarchy-walking expensive.
|
|
|
|
e = e->IgnoreParenCasts();
|
|
|
|
|
|
|
|
if (const BlockExpr *be = dyn_cast<BlockExpr>(e)) {
|
|
|
|
const BlockDecl *block = be->getBlockDecl();
|
2014-03-15 02:34:04 +08:00
|
|
|
for (const auto &I : block->captures()) {
|
|
|
|
if (I.getVariable() == &var)
|
2011-02-22 14:44:22 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// No need to walk into the subexpressions.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-08-24 00:47:15 +08:00
|
|
|
if (const StmtExpr *SE = dyn_cast<StmtExpr>(e)) {
|
|
|
|
const CompoundStmt *CS = SE->getSubStmt();
|
2014-03-17 22:19:37 +08:00
|
|
|
for (const auto *BI : CS->body())
|
|
|
|
if (const auto *E = dyn_cast<Expr>(BI)) {
|
2011-08-24 00:47:15 +08:00
|
|
|
if (isCapturedBy(var, E))
|
|
|
|
return true;
|
2011-08-25 08:06:26 +08:00
|
|
|
}
|
2014-03-17 22:19:37 +08:00
|
|
|
else if (const auto *DS = dyn_cast<DeclStmt>(BI)) {
|
2011-08-25 08:06:26 +08:00
|
|
|
// special case declarations
|
2014-03-15 01:01:24 +08:00
|
|
|
for (const auto *I : DS->decls()) {
|
|
|
|
if (const auto *VD = dyn_cast<VarDecl>((I))) {
|
|
|
|
const Expr *Init = VD->getInit();
|
2011-08-25 08:06:26 +08:00
|
|
|
if (Init && isCapturedBy(var, Init))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
// FIXME. Make safe assumption assuming arbitrary statements cause capturing.
|
|
|
|
// Later, provide code to poke into statements for capture analysis.
|
|
|
|
return true;
|
2011-08-24 00:47:15 +08:00
|
|
|
return false;
|
|
|
|
}
|
2011-08-24 06:38:00 +08:00
|
|
|
|
2015-07-03 05:03:14 +08:00
|
|
|
for (const Stmt *SubStmt : e->children())
|
|
|
|
if (isCapturedBy(var, cast<Expr>(SubStmt)))
|
2011-02-22 14:44:22 +08:00
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-07-02 05:08:19 +08:00
|
|
|
/// \brief Determine whether the given initializer is trivial in the sense
|
|
|
|
/// that it requires no code to be generated.
|
2014-10-08 22:01:46 +08:00
|
|
|
bool CodeGenFunction::isTrivialInitializer(const Expr *Init) {
|
2011-07-02 05:08:19 +08:00
|
|
|
if (!Init)
|
|
|
|
return true;
|
2011-08-24 06:38:00 +08:00
|
|
|
|
2011-07-02 05:08:19 +08:00
|
|
|
if (const CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init))
|
|
|
|
if (CXXConstructorDecl *Constructor = Construct->getConstructor())
|
|
|
|
if (Constructor->isTrivial() &&
|
|
|
|
Constructor->isDefaultConstructor() &&
|
|
|
|
!Construct->requiresZeroInitialization())
|
|
|
|
return true;
|
2011-08-24 06:38:00 +08:00
|
|
|
|
2011-07-02 05:08:19 +08:00
|
|
|
return false;
|
|
|
|
}
|
2011-02-22 14:44:22 +08:00
|
|
|
void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
|
2011-02-22 15:16:58 +08:00
|
|
|
assert(emission.Variable && "emission was not valid!");
|
|
|
|
|
2011-02-22 14:44:22 +08:00
|
|
|
// If this was emitted as a global constant, we're done.
|
|
|
|
if (emission.wasEmittedAsGlobal()) return;
|
|
|
|
|
2011-02-22 15:16:58 +08:00
|
|
|
const VarDecl &D = *emission.Variable;
|
2015-02-04 04:00:54 +08:00
|
|
|
auto DL = ApplyDebugLocation::CreateDefaultArtificial(*this, D.getLocation());
|
2011-02-22 14:44:22 +08:00
|
|
|
QualType type = D.getType();
|
|
|
|
|
2007-07-12 08:39:48 +08:00
|
|
|
// If this local has an initializer, emit it now.
|
2009-07-19 14:58:07 +08:00
|
|
|
const Expr *Init = D.getInit();
|
|
|
|
|
|
|
|
// If we are at an unreachable point, we don't need to emit the initializer
|
|
|
|
// unless it contains a label.
|
|
|
|
if (!HaveInsertPoint()) {
|
2011-02-22 14:44:22 +08:00
|
|
|
if (!Init || !ContainsLabel(Init)) return;
|
|
|
|
EnsureInsertPoint();
|
2009-07-19 14:58:07 +08:00
|
|
|
}
|
|
|
|
|
2011-03-31 09:59:53 +08:00
|
|
|
// Initialize the structure of a __block variable.
|
|
|
|
if (emission.IsByRef)
|
|
|
|
emitByrefStructureInit(emission);
|
2009-02-08 07:51:38 +08:00
|
|
|
|
2011-07-02 05:08:19 +08:00
|
|
|
if (isTrivialInitializer(Init))
|
|
|
|
return;
|
2011-08-24 06:38:00 +08:00
|
|
|
|
2011-02-22 14:44:22 +08:00
|
|
|
// Check whether this is a byref variable that's potentially
|
|
|
|
// captured and moved by its own initializer. If so, we'll need to
|
|
|
|
// emit the initializer first, then copy into the variable.
|
|
|
|
bool capturedByInit = emission.IsByRef && isCapturedBy(D, Init);
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 Loc =
|
|
|
|
capturedByInit ? emission.Addr : emission.getObjectAddress(*this);
|
2011-02-22 14:44:22 +08:00
|
|
|
|
2014-05-21 13:09:00 +08:00
|
|
|
llvm::Constant *constant = nullptr;
|
2013-06-02 08:09:52 +08:00
|
|
|
if (emission.IsConstantAggregate || D.isConstexpr()) {
|
2011-12-31 05:15:51 +08:00
|
|
|
assert(!capturedByInit && "constant init contains a capturing block?");
|
2012-01-14 12:30:29 +08:00
|
|
|
constant = CGM.EmitConstantInit(D, this);
|
2011-12-31 05:15:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!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
|
|
|
LValue lv = MakeAddrLValue(Loc, type);
|
2011-06-16 12:16:24 +08:00
|
|
|
lv.setNonGC(true);
|
2015-01-14 15:38:27 +08:00
|
|
|
return EmitExprAsInit(Init, &D, lv, capturedByInit);
|
2011-06-16 12:16:24 +08:00
|
|
|
}
|
2011-03-08 17:11:50 +08:00
|
|
|
|
2013-06-02 08:09:52 +08:00
|
|
|
if (!emission.IsConstantAggregate) {
|
|
|
|
// For simple scalar/complex initialization, store the value 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
|
|
|
LValue lv = MakeAddrLValue(Loc, type);
|
2013-06-02 08:09:52 +08:00
|
|
|
lv.setNonGC(true);
|
|
|
|
return EmitStoreThroughLValue(RValue::get(constant), lv, true);
|
|
|
|
}
|
|
|
|
|
2011-02-22 14:44:22 +08:00
|
|
|
// If this is a simple aggregate initialization, we can optimize it
|
|
|
|
// in various ways.
|
2011-03-08 17:11:50 +08:00
|
|
|
bool isVolatile = type.isVolatileQualified();
|
2010-04-04 11:10:52 +08:00
|
|
|
|
2011-03-08 17:11:50 +08:00
|
|
|
llvm::Value *SizeVal =
|
2011-08-24 06:38:00 +08:00
|
|
|
llvm::ConstantInt::get(IntPtrTy,
|
2011-03-08 17:11:50 +08:00
|
|
|
getContext().getTypeSizeInChars(type).getQuantity());
|
|
|
|
|
2011-07-18 12:24:23 +08:00
|
|
|
llvm::Type *BP = 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
|
|
|
if (Loc.getType() != BP)
|
2011-09-28 05:06:10 +08:00
|
|
|
Loc = Builder.CreateBitCast(Loc, BP);
|
2011-03-08 17:11:50 +08:00
|
|
|
|
|
|
|
// If the initializer is all or mostly zeros, codegen with memset then do
|
|
|
|
// a few stores afterward.
|
2011-08-24 06:38:00 +08:00
|
|
|
if (shouldUseMemSetPlusStoresToInitialize(constant,
|
2012-10-09 00:25:52 +08:00
|
|
|
CGM.getDataLayout().getTypeAllocSize(constant->getType()))) {
|
2011-03-08 17:11:50 +08:00
|
|
|
Builder.CreateMemSet(Loc, llvm::ConstantInt::get(Int8Ty, 0), SizeVal,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
isVolatile);
|
2012-08-28 06:07:02 +08:00
|
|
|
// Zero and undef don't require a stores.
|
|
|
|
if (!constant->isNullValue() && !isa<llvm::UndefValue>(constant)) {
|
2011-03-08 17:11:50 +08:00
|
|
|
Loc = Builder.CreateBitCast(Loc, constant->getType()->getPointerTo());
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
emitStoresForInitAfterMemset(constant, Loc.getPointer(),
|
|
|
|
isVolatile, Builder);
|
2010-03-13 05:40:43 +08:00
|
|
|
}
|
2011-03-08 17:11:50 +08:00
|
|
|
} else {
|
2011-08-24 06:38:00 +08:00
|
|
|
// Otherwise, create a temporary global with the initializer then
|
2011-03-08 17:11:50 +08:00
|
|
|
// memcpy from the global to the alloca.
|
2014-10-08 09:07:54 +08:00
|
|
|
std::string Name = getStaticDeclName(CGM, D);
|
2011-03-08 17:11:50 +08:00
|
|
|
llvm::GlobalVariable *GV =
|
|
|
|
new llvm::GlobalVariable(CGM.getModule(), constant->getType(), true,
|
2011-08-24 08:33:55 +08:00
|
|
|
llvm::GlobalValue::PrivateLinkage,
|
2012-06-23 19:51:46 +08:00
|
|
|
constant, 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
|
|
|
GV->setAlignment(Loc.getAlignment().getQuantity());
|
2011-05-28 06:32:55 +08:00
|
|
|
GV->setUnnamedAddr(true);
|
2011-08-24 06:38:00 +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 SrcPtr = Address(GV, Loc.getAlignment());
|
|
|
|
if (SrcPtr.getType() != BP)
|
2011-09-28 05:06:10 +08:00
|
|
|
SrcPtr = Builder.CreateBitCast(SrcPtr, BP);
|
2011-03-08 17:11:50 +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.CreateMemCpy(Loc, SrcPtr, SizeVal, isVolatile);
|
2011-03-08 17:11:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Emit an expression as an initializer for a variable at the given
|
|
|
|
/// location. The expression is not necessarily the normal
|
|
|
|
/// initializer for the variable, and the address is not necessarily
|
|
|
|
/// its normal location.
|
|
|
|
///
|
|
|
|
/// \param init the initializing expression
|
|
|
|
/// \param var the variable to act as if we're initializing
|
|
|
|
/// \param loc the address to initialize; its type is a pointer
|
|
|
|
/// to the LLVM mapping of the variable's type
|
|
|
|
/// \param alignment the alignment of the address
|
|
|
|
/// \param capturedByInit true if the variable is a __block variable
|
|
|
|
/// whose address is potentially changed by the initializer
|
2014-12-09 08:32:22 +08:00
|
|
|
void CodeGenFunction::EmitExprAsInit(const Expr *init, const ValueDecl *D,
|
2015-01-14 15:38:27 +08:00
|
|
|
LValue lvalue, bool capturedByInit) {
|
2011-06-16 07:02:42 +08:00
|
|
|
QualType type = D->getType();
|
2011-03-08 17:11:50 +08:00
|
|
|
|
|
|
|
if (type->isReferenceType()) {
|
2013-06-13 07:38:09 +08:00
|
|
|
RValue rvalue = EmitReferenceBindingToExpr(init);
|
2011-08-24 06:38:00 +08:00
|
|
|
if (capturedByInit)
|
2011-06-16 12:16:24 +08:00
|
|
|
drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
|
2015-01-14 15:38:27 +08:00
|
|
|
EmitStoreThroughLValue(rvalue, lvalue, true);
|
2013-03-08 05:37:08 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
switch (getEvaluationKind(type)) {
|
|
|
|
case TEK_Scalar:
|
2015-01-14 15:38:27 +08:00
|
|
|
EmitScalarInit(init, D, lvalue, capturedByInit);
|
2013-03-08 05:37:08 +08:00
|
|
|
return;
|
|
|
|
case TEK_Complex: {
|
2011-03-08 17:11:50 +08:00
|
|
|
ComplexPairTy complex = EmitComplexExpr(init);
|
2011-06-16 12:16:24 +08:00
|
|
|
if (capturedByInit)
|
|
|
|
drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
|
2015-01-14 15:38:27 +08:00
|
|
|
EmitStoreOfComplex(complex, lvalue, /*init*/ true);
|
2013-03-08 05:37:08 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
case TEK_Aggregate:
|
2013-03-08 05:37:17 +08:00
|
|
|
if (type->isAtomicType()) {
|
|
|
|
EmitAtomicInit(const_cast<Expr*>(init), lvalue);
|
|
|
|
} else {
|
|
|
|
// TODO: how can we delay here if D is captured by its initializer?
|
|
|
|
EmitAggExpr(init, AggValueSlot::forLValue(lvalue,
|
2012-03-30 01:37:10 +08:00
|
|
|
AggValueSlot::IsDestructed,
|
2011-08-26 07:04:34 +08:00
|
|
|
AggValueSlot::DoesNotNeedGCBarriers,
|
2012-03-30 01:37:10 +08:00
|
|
|
AggValueSlot::IsNotAliased));
|
2013-03-08 05:37:17 +08:00
|
|
|
}
|
2013-03-08 05:37:08 +08:00
|
|
|
return;
|
2010-03-13 05:40:43 +08:00
|
|
|
}
|
2013-03-08 05:37:08 +08:00
|
|
|
llvm_unreachable("bad evaluation kind");
|
2011-02-22 14:44:22 +08:00
|
|
|
}
|
|
|
|
|
2011-07-09 09:37:26 +08:00
|
|
|
/// Enter a destroy cleanup for the given local variable.
|
|
|
|
void CodeGenFunction::emitAutoVarTypeCleanup(
|
|
|
|
const CodeGenFunction::AutoVarEmission &emission,
|
|
|
|
QualType::DestructionKind dtorKind) {
|
|
|
|
assert(dtorKind != QualType::DK_none);
|
|
|
|
|
|
|
|
// Note that for __block variables, we want to destroy the
|
|
|
|
// original stack object, not the possibly forwarded object.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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.getObjectAddress(*this);
|
2011-07-09 09:37:26 +08:00
|
|
|
|
|
|
|
const VarDecl *var = emission.Variable;
|
|
|
|
QualType type = var->getType();
|
|
|
|
|
|
|
|
CleanupKind cleanupKind = NormalAndEHCleanup;
|
2014-05-21 13:09:00 +08:00
|
|
|
CodeGenFunction::Destroyer *destroyer = nullptr;
|
2011-07-09 09:37:26 +08:00
|
|
|
|
|
|
|
switch (dtorKind) {
|
|
|
|
case QualType::DK_none:
|
|
|
|
llvm_unreachable("no cleanup for trivially-destructible variable");
|
|
|
|
|
|
|
|
case QualType::DK_cxx_destructor:
|
|
|
|
// If there's an NRVO flag on the emission, we need a different
|
|
|
|
// cleanup.
|
|
|
|
if (emission.NRVOFlag) {
|
|
|
|
assert(!type->isArrayType());
|
|
|
|
CXXDestructorDecl *dtor = type->getAsCXXRecordDecl()->getDestructor();
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
EHStack.pushCleanup<DestroyNRVOVariable>(cleanupKind, addr,
|
|
|
|
dtor, emission.NRVOFlag);
|
2011-07-09 09:37:26 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QualType::DK_objc_strong_lifetime:
|
|
|
|
// Suppress cleanups for pseudo-strong variables.
|
|
|
|
if (var->isARCPseudoStrong()) return;
|
2011-08-24 06:38:00 +08:00
|
|
|
|
2011-07-09 09:37:26 +08:00
|
|
|
// Otherwise, consider whether to use an EH cleanup or not.
|
|
|
|
cleanupKind = getARCCleanupKind();
|
|
|
|
|
|
|
|
// Use the imprecise destroyer by default.
|
|
|
|
if (!var->hasAttr<ObjCPreciseLifetimeAttr>())
|
|
|
|
destroyer = CodeGenFunction::destroyARCStrongImprecise;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QualType::DK_objc_weak_lifetime:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we haven't chosen a more specific destroyer, use the default.
|
2012-01-26 11:33:36 +08:00
|
|
|
if (!destroyer) destroyer = getDestroyer(dtorKind);
|
2011-07-11 16:38:19 +08:00
|
|
|
|
2012-09-27 18:16:10 +08:00
|
|
|
// Use an EH cleanup in array destructors iff the destructor itself
|
2011-07-11 16:38:19 +08:00
|
|
|
// is being pushed as an EH cleanup.
|
|
|
|
bool useEHCleanup = (cleanupKind & EHCleanup);
|
|
|
|
EHStack.pushCleanup<DestroyObject>(cleanupKind, addr, type, destroyer,
|
|
|
|
useEHCleanup);
|
2011-07-09 09:37:26 +08:00
|
|
|
}
|
|
|
|
|
2011-02-22 14:44:22 +08:00
|
|
|
void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) {
|
2011-02-22 15:16:58 +08:00
|
|
|
assert(emission.Variable && "emission was not valid!");
|
|
|
|
|
2011-02-22 14:44:22 +08:00
|
|
|
// If this was emitted as a global constant, we're done.
|
|
|
|
if (emission.wasEmittedAsGlobal()) return;
|
|
|
|
|
2012-04-14 02:44:05 +08:00
|
|
|
// If we don't have an insertion point, we're done. Sema prevents
|
|
|
|
// us from jumping into any of these scopes anyway.
|
|
|
|
if (!HaveInsertPoint()) return;
|
|
|
|
|
2011-02-22 15:16:58 +08:00
|
|
|
const VarDecl &D = *emission.Variable;
|
2010-07-06 09:34:17 +08:00
|
|
|
|
2013-03-23 14:43:35 +08:00
|
|
|
// Make sure we call @llvm.lifetime.end. This needs to happen
|
|
|
|
// *last*, so the cleanup needs to be pushed *first*.
|
|
|
|
if (emission.useLifetimeMarkers()) {
|
|
|
|
EHStack.pushCleanup<CallLifetimeEnd>(NormalCleanup,
|
|
|
|
emission.getAllocatedAddress(),
|
|
|
|
emission.getSizeForLifetimeMarkers());
|
2015-04-23 05:38:15 +08:00
|
|
|
EHCleanupScope &cleanup = cast<EHCleanupScope>(*EHStack.begin());
|
|
|
|
cleanup.setLifetimeMarker();
|
2013-03-23 14:43:35 +08:00
|
|
|
}
|
|
|
|
|
2011-07-09 09:37:26 +08:00
|
|
|
// Check the type for a cleanup.
|
|
|
|
if (QualType::DestructionKind dtorKind = D.getType().isDestructedType())
|
|
|
|
emitAutoVarTypeCleanup(emission, dtorKind);
|
2011-06-16 07:02:42 +08:00
|
|
|
|
2011-06-25 07:21:27 +08:00
|
|
|
// In GC mode, honor objc_precise_lifetime.
|
2012-03-11 15:00:24 +08:00
|
|
|
if (getLangOpts().getGC() != LangOptions::NonGC &&
|
2011-06-25 07:21:27 +08:00
|
|
|
D.hasAttr<ObjCPreciseLifetimeAttr>()) {
|
|
|
|
EHStack.pushCleanup<ExtendGCLifetime>(NormalCleanup, &D);
|
|
|
|
}
|
|
|
|
|
2011-02-22 14:44:22 +08:00
|
|
|
// Handle the cleanup attribute.
|
2009-06-30 10:34:44 +08:00
|
|
|
if (const CleanupAttr *CA = D.getAttr<CleanupAttr>()) {
|
2009-02-08 07:51:38 +08:00
|
|
|
const FunctionDecl *FD = CA->getFunctionDecl();
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2011-02-22 14:44:22 +08:00
|
|
|
llvm::Constant *F = CGM.GetAddrOfFunction(FD);
|
2009-02-08 07:51:38 +08:00
|
|
|
assert(F && "Could not find function!");
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2012-02-17 11:33:10 +08:00
|
|
|
const CGFunctionInfo &Info = CGM.getTypes().arrangeFunctionDeclaration(FD);
|
2011-02-22 14:44:22 +08:00
|
|
|
EHStack.pushCleanup<CallCleanupFunction>(NormalAndEHCleanup, F, &Info, &D);
|
2009-02-08 07:51:38 +08:00
|
|
|
}
|
2009-03-05 09:23:13 +08:00
|
|
|
|
2011-02-22 14:44:22 +08:00
|
|
|
// If this is a block variable, call _Block_object_destroy
|
|
|
|
// (on the unforwarded address).
|
2011-03-31 09:59:53 +08:00
|
|
|
if (emission.IsByRef)
|
|
|
|
enterByrefCleanup(emission);
|
2007-06-02 12:16:21 +08:00
|
|
|
}
|
2007-06-14 04:44:40 +08:00
|
|
|
|
2012-01-26 11:33:36 +08:00
|
|
|
CodeGenFunction::Destroyer *
|
2011-07-09 09:37:26 +08:00
|
|
|
CodeGenFunction::getDestroyer(QualType::DestructionKind kind) {
|
|
|
|
switch (kind) {
|
|
|
|
case QualType::DK_none: llvm_unreachable("no destroyer for trivial dtor");
|
2011-07-09 17:09:00 +08:00
|
|
|
case QualType::DK_cxx_destructor:
|
2012-01-26 11:33:36 +08:00
|
|
|
return destroyCXXObject;
|
2011-07-09 17:09:00 +08:00
|
|
|
case QualType::DK_objc_strong_lifetime:
|
2012-01-26 11:33:36 +08:00
|
|
|
return destroyARCStrongPrecise;
|
2011-07-09 17:09:00 +08:00
|
|
|
case QualType::DK_objc_weak_lifetime:
|
2012-01-26 11:33:36 +08:00
|
|
|
return destroyARCWeak;
|
2011-07-09 09:37:26 +08:00
|
|
|
}
|
2012-01-27 08:46:27 +08:00
|
|
|
llvm_unreachable("Unknown DestructionKind");
|
2011-07-09 09:37:26 +08:00
|
|
|
}
|
|
|
|
|
2013-02-01 13:11:40 +08:00
|
|
|
/// pushEHDestroy - Push the standard destructor for the given type as
|
|
|
|
/// an EH-only cleanup.
|
|
|
|
void CodeGenFunction::pushEHDestroy(QualType::DestructionKind dtorKind,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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, QualType type) {
|
2013-02-01 13:11:40 +08:00
|
|
|
assert(dtorKind && "cannot push destructor for trivial type");
|
|
|
|
assert(needsEHCleanup(dtorKind));
|
|
|
|
|
|
|
|
pushDestroy(EHCleanup, addr, type, getDestroyer(dtorKind), true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// pushDestroy - Push the standard destructor for the given type as
|
|
|
|
/// at least a normal cleanup.
|
2011-07-13 00:41:08 +08:00
|
|
|
void CodeGenFunction::pushDestroy(QualType::DestructionKind dtorKind,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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, QualType type) {
|
2011-07-13 00:41:08 +08:00
|
|
|
assert(dtorKind && "cannot push destructor for trivial type");
|
|
|
|
|
|
|
|
CleanupKind cleanupKind = getCleanupKind(dtorKind);
|
|
|
|
pushDestroy(cleanupKind, addr, type, getDestroyer(dtorKind),
|
|
|
|
cleanupKind & EHCleanup);
|
|
|
|
}
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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::pushDestroy(CleanupKind cleanupKind, Address addr,
|
2012-01-26 11:33:36 +08:00
|
|
|
QualType type, Destroyer *destroyer,
|
2011-07-11 16:38:19 +08:00
|
|
|
bool useEHCleanupForArray) {
|
2011-07-13 00:41:08 +08:00
|
|
|
pushFullExprCleanup<DestroyObject>(cleanupKind, addr, type,
|
|
|
|
destroyer, useEHCleanupForArray);
|
2011-07-09 09:37: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 CodeGenFunction::pushStackRestore(CleanupKind Kind, Address SPMem) {
|
2014-02-01 08:04:45 +08:00
|
|
|
EHStack.pushCleanup<CallStackRestore>(Kind, SPMem);
|
|
|
|
}
|
|
|
|
|
2013-06-13 04:42:33 +08:00
|
|
|
void CodeGenFunction::pushLifetimeExtendedDestroy(
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
CleanupKind cleanupKind, Address addr, QualType type,
|
2013-06-13 04:42:33 +08:00
|
|
|
Destroyer *destroyer, bool useEHCleanupForArray) {
|
|
|
|
assert(!isInConditionalBranch() &&
|
|
|
|
"performing lifetime extension from within conditional");
|
|
|
|
|
|
|
|
// Push an EH-only cleanup for the object now.
|
|
|
|
// FIXME: When popping normal cleanups, we need to keep this EH cleanup
|
|
|
|
// around in case a temporary's destructor throws an exception.
|
|
|
|
if (cleanupKind & EHCleanup)
|
|
|
|
EHStack.pushCleanup<DestroyObject>(
|
|
|
|
static_cast<CleanupKind>(cleanupKind & ~NormalCleanup), addr, type,
|
|
|
|
destroyer, useEHCleanupForArray);
|
|
|
|
|
|
|
|
// Remember that we need to push a full cleanup for the object at the
|
|
|
|
// end of the full-expression.
|
|
|
|
pushCleanupAfterFullExpr<DestroyObject>(
|
|
|
|
cleanupKind, addr, type, destroyer, useEHCleanupForArray);
|
|
|
|
}
|
|
|
|
|
2011-07-11 16:38:19 +08:00
|
|
|
/// emitDestroy - Immediately perform the destruction of the given
|
|
|
|
/// object.
|
|
|
|
///
|
|
|
|
/// \param addr - the address of the object; a type*
|
|
|
|
/// \param type - the type of the object; if an array type, all
|
|
|
|
/// objects are destroyed in reverse order
|
|
|
|
/// \param destroyer - the function to call to destroy individual
|
|
|
|
/// elements
|
|
|
|
/// \param useEHCleanupForArray - whether an EH cleanup should be
|
|
|
|
/// used when destroying array elements, in case one of the
|
|
|
|
/// destructions throws an exception
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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::emitDestroy(Address addr, QualType type,
|
2012-01-26 11:33:36 +08:00
|
|
|
Destroyer *destroyer,
|
2011-07-11 16:38:19 +08:00
|
|
|
bool useEHCleanupForArray) {
|
2011-07-09 09:37:26 +08:00
|
|
|
const ArrayType *arrayType = getContext().getAsArrayType(type);
|
|
|
|
if (!arrayType)
|
|
|
|
return destroyer(*this, addr, 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
|
|
|
llvm::Value *length = emitArrayLength(arrayType, type, addr);
|
|
|
|
|
|
|
|
CharUnits elementAlign =
|
|
|
|
addr.getAlignment()
|
|
|
|
.alignmentOfArrayElement(getContext().getTypeSizeInChars(type));
|
2011-07-13 16:09:46 +08:00
|
|
|
|
|
|
|
// Normally we have to check whether the array is zero-length.
|
|
|
|
bool checkZeroLength = true;
|
|
|
|
|
|
|
|
// But if the array length is constant, we can suppress that.
|
|
|
|
if (llvm::ConstantInt *constLength = dyn_cast<llvm::ConstantInt>(length)) {
|
|
|
|
// ...and if it's constant zero, we can just skip the entire thing.
|
|
|
|
if (constLength->isZero()) return;
|
|
|
|
checkZeroLength = false;
|
|
|
|
}
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
llvm::Value *begin = addr.getPointer();
|
2011-07-09 09:37:26 +08:00
|
|
|
llvm::Value *end = Builder.CreateInBoundsGEP(begin, length);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
emitArrayDestroy(begin, end, type, elementAlign, destroyer,
|
2011-07-13 16:09:46 +08:00
|
|
|
checkZeroLength, useEHCleanupForArray);
|
2011-07-09 09:37:26 +08:00
|
|
|
}
|
|
|
|
|
2011-07-11 16:38:19 +08:00
|
|
|
/// emitArrayDestroy - Destroys all the elements of the given array,
|
|
|
|
/// beginning from last to first. The array cannot be zero-length.
|
|
|
|
///
|
|
|
|
/// \param begin - a type* denoting the first element of the array
|
|
|
|
/// \param end - a type* denoting one past the end of the array
|
2015-09-08 17:42:41 +08:00
|
|
|
/// \param elementType - the element type of the array
|
2011-07-11 16:38:19 +08:00
|
|
|
/// \param destroyer - the function to call to destroy elements
|
|
|
|
/// \param useEHCleanup - whether to push an EH cleanup to destroy
|
|
|
|
/// the remaining elements in case the destruction of a single
|
|
|
|
/// element throws
|
2011-07-09 09:37:26 +08:00
|
|
|
void CodeGenFunction::emitArrayDestroy(llvm::Value *begin,
|
|
|
|
llvm::Value *end,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
QualType elementType,
|
|
|
|
CharUnits elementAlign,
|
2012-01-26 11:33:36 +08:00
|
|
|
Destroyer *destroyer,
|
2011-07-13 16:09:46 +08:00
|
|
|
bool checkZeroLength,
|
2011-07-11 16:38:19 +08:00
|
|
|
bool useEHCleanup) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
assert(!elementType->isArrayType());
|
2011-07-09 09:37:26 +08:00
|
|
|
|
|
|
|
// The basic structure here is a do-while loop, because we don't
|
|
|
|
// need to check for the zero-element case.
|
|
|
|
llvm::BasicBlock *bodyBB = createBasicBlock("arraydestroy.body");
|
|
|
|
llvm::BasicBlock *doneBB = createBasicBlock("arraydestroy.done");
|
|
|
|
|
2011-07-13 16:09:46 +08:00
|
|
|
if (checkZeroLength) {
|
|
|
|
llvm::Value *isEmpty = Builder.CreateICmpEQ(begin, end,
|
|
|
|
"arraydestroy.isempty");
|
|
|
|
Builder.CreateCondBr(isEmpty, doneBB, bodyBB);
|
|
|
|
}
|
|
|
|
|
2011-07-09 09:37:26 +08:00
|
|
|
// Enter the loop body, making that address the current address.
|
|
|
|
llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
|
|
|
|
EmitBlock(bodyBB);
|
|
|
|
llvm::PHINode *elementPast =
|
|
|
|
Builder.CreatePHI(begin->getType(), 2, "arraydestroy.elementPast");
|
|
|
|
elementPast->addIncoming(end, entryBB);
|
|
|
|
|
|
|
|
// Shift the address back by one element.
|
|
|
|
llvm::Value *negativeOne = llvm::ConstantInt::get(SizeTy, -1, true);
|
|
|
|
llvm::Value *element = Builder.CreateInBoundsGEP(elementPast, negativeOne,
|
|
|
|
"arraydestroy.element");
|
|
|
|
|
2011-07-11 16:38:19 +08:00
|
|
|
if (useEHCleanup)
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
pushRegularPartialArrayCleanup(begin, element, elementType, elementAlign,
|
|
|
|
destroyer);
|
2011-07-11 16:38:19 +08:00
|
|
|
|
2011-07-09 09:37:26 +08:00
|
|
|
// Perform the actual destruction there.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
destroyer(*this, Address(element, elementAlign), elementType);
|
2011-07-09 09:37:26 +08:00
|
|
|
|
2011-07-11 16:38:19 +08:00
|
|
|
if (useEHCleanup)
|
|
|
|
PopCleanupBlock();
|
|
|
|
|
2011-07-09 09:37:26 +08:00
|
|
|
// Check whether we've reached the end.
|
|
|
|
llvm::Value *done = Builder.CreateICmpEQ(element, begin, "arraydestroy.done");
|
|
|
|
Builder.CreateCondBr(done, doneBB, bodyBB);
|
|
|
|
elementPast->addIncoming(element, Builder.GetInsertBlock());
|
|
|
|
|
|
|
|
// Done.
|
|
|
|
EmitBlock(doneBB);
|
|
|
|
}
|
|
|
|
|
2011-07-11 16:38:19 +08:00
|
|
|
/// Perform partial array destruction as if in an EH cleanup. Unlike
|
|
|
|
/// emitArrayDestroy, the element type here may still be an array type.
|
|
|
|
static void emitPartialArrayDestroy(CodeGenFunction &CGF,
|
|
|
|
llvm::Value *begin, llvm::Value *end,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
QualType type, CharUnits elementAlign,
|
2012-01-26 11:33:36 +08:00
|
|
|
CodeGenFunction::Destroyer *destroyer) {
|
2011-07-11 16:38:19 +08:00
|
|
|
// If the element type is itself an array, drill down.
|
2011-07-13 16:09:46 +08:00
|
|
|
unsigned arrayDepth = 0;
|
2011-07-11 16:38:19 +08:00
|
|
|
while (const ArrayType *arrayType = CGF.getContext().getAsArrayType(type)) {
|
|
|
|
// VLAs don't require a GEP index to walk into.
|
|
|
|
if (!isa<VariableArrayType>(arrayType))
|
2011-07-13 16:09:46 +08:00
|
|
|
arrayDepth++;
|
2011-07-11 16:38:19 +08:00
|
|
|
type = arrayType->getElementType();
|
|
|
|
}
|
2011-07-13 16:09:46 +08:00
|
|
|
|
|
|
|
if (arrayDepth) {
|
2015-09-15 02:57:08 +08:00
|
|
|
llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
|
2011-07-13 16:09:46 +08:00
|
|
|
|
2015-09-15 02:57:08 +08:00
|
|
|
SmallVector<llvm::Value*,4> gepIndices(arrayDepth+1, zero);
|
2011-07-22 16:16:57 +08:00
|
|
|
begin = CGF.Builder.CreateInBoundsGEP(begin, gepIndices, "pad.arraybegin");
|
|
|
|
end = CGF.Builder.CreateInBoundsGEP(end, gepIndices, "pad.arrayend");
|
2011-07-11 16:38:19 +08:00
|
|
|
}
|
|
|
|
|
2011-07-13 16:09:46 +08:00
|
|
|
// Destroy the array. We don't ever need an EH cleanup because we
|
|
|
|
// assume that we're in an EH cleanup ourselves, so a throwing
|
|
|
|
// destructor causes an immediate terminate.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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.emitArrayDestroy(begin, end, type, elementAlign, destroyer,
|
2011-07-13 16:09:46 +08:00
|
|
|
/*checkZeroLength*/ true, /*useEHCleanup*/ false);
|
2011-07-11 16:38:19 +08:00
|
|
|
}
|
|
|
|
|
2011-07-09 09:37:26 +08:00
|
|
|
namespace {
|
2011-07-11 16:38:19 +08:00
|
|
|
/// RegularPartialArrayDestroy - a cleanup which performs a partial
|
|
|
|
/// array destroy where the end pointer is regularly determined and
|
|
|
|
/// does not need to be loaded from a local.
|
2015-08-19 06:40:54 +08:00
|
|
|
class RegularPartialArrayDestroy final : public EHScopeStack::Cleanup {
|
2011-07-11 16:38:19 +08:00
|
|
|
llvm::Value *ArrayBegin;
|
|
|
|
llvm::Value *ArrayEnd;
|
|
|
|
QualType ElementType;
|
2012-01-26 11:33:36 +08:00
|
|
|
CodeGenFunction::Destroyer *Destroyer;
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 ElementAlign;
|
2011-07-11 16:38:19 +08:00
|
|
|
public:
|
|
|
|
RegularPartialArrayDestroy(llvm::Value *arrayBegin, llvm::Value *arrayEnd,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
QualType elementType, CharUnits elementAlign,
|
2011-07-11 16:38:19 +08:00
|
|
|
CodeGenFunction::Destroyer *destroyer)
|
|
|
|
: ArrayBegin(arrayBegin), ArrayEnd(arrayEnd),
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
ElementType(elementType), Destroyer(destroyer),
|
|
|
|
ElementAlign(elementAlign) {}
|
2011-07-11 16:38:19 +08:00
|
|
|
|
2014-03-12 14:41:41 +08:00
|
|
|
void Emit(CodeGenFunction &CGF, Flags flags) override {
|
2011-07-11 16:38:19 +08:00
|
|
|
emitPartialArrayDestroy(CGF, ArrayBegin, ArrayEnd,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
ElementType, ElementAlign, Destroyer);
|
2011-07-11 16:38:19 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// IrregularPartialArrayDestroy - a cleanup which performs a
|
|
|
|
/// partial array destroy where the end pointer is irregularly
|
|
|
|
/// determined and must be loaded from a local.
|
2015-08-19 06:40:54 +08:00
|
|
|
class IrregularPartialArrayDestroy final : public EHScopeStack::Cleanup {
|
2011-07-09 09:37:26 +08:00
|
|
|
llvm::Value *ArrayBegin;
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 ArrayEndPointer;
|
2011-07-09 09:37:26 +08:00
|
|
|
QualType ElementType;
|
2012-01-26 11:33:36 +08:00
|
|
|
CodeGenFunction::Destroyer *Destroyer;
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 ElementAlign;
|
2011-07-09 09:37:26 +08:00
|
|
|
public:
|
2011-07-11 16:38:19 +08:00
|
|
|
IrregularPartialArrayDestroy(llvm::Value *arrayBegin,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 arrayEndPointer,
|
2011-07-11 16:38:19 +08:00
|
|
|
QualType elementType,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 elementAlign,
|
2011-07-11 16:38:19 +08:00
|
|
|
CodeGenFunction::Destroyer *destroyer)
|
2011-07-09 09:37:26 +08:00
|
|
|
: ArrayBegin(arrayBegin), ArrayEndPointer(arrayEndPointer),
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
ElementType(elementType), Destroyer(destroyer),
|
|
|
|
ElementAlign(elementAlign) {}
|
2011-07-09 09:37:26 +08:00
|
|
|
|
2014-03-12 14:41:41 +08:00
|
|
|
void Emit(CodeGenFunction &CGF, Flags flags) override {
|
2011-07-09 09:37:26 +08:00
|
|
|
llvm::Value *arrayEnd = CGF.Builder.CreateLoad(ArrayEndPointer);
|
2011-07-11 16:38:19 +08:00
|
|
|
emitPartialArrayDestroy(CGF, ArrayBegin, arrayEnd,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
ElementType, ElementAlign, Destroyer);
|
2011-07-09 09:37:26 +08:00
|
|
|
}
|
|
|
|
};
|
2015-06-23 07:07:51 +08:00
|
|
|
}
|
2011-07-09 09:37:26 +08:00
|
|
|
|
2011-07-11 16:38:19 +08:00
|
|
|
/// pushIrregularPartialArrayCleanup - Push an EH cleanup to destroy
|
|
|
|
/// already-constructed elements of the given array. The cleanup
|
|
|
|
/// may be popped with DeactivateCleanupBlock or PopCleanupBlock.
|
2011-08-24 06:38:00 +08:00
|
|
|
///
|
2011-07-11 16:38:19 +08:00
|
|
|
/// \param elementType - the immediate element type of the array;
|
|
|
|
/// possibly still an array type
|
2011-07-13 00:41:08 +08:00
|
|
|
void CodeGenFunction::pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 arrayEndPointer,
|
2011-07-11 16:38:19 +08:00
|
|
|
QualType elementType,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 elementAlign,
|
2012-01-26 11:33:36 +08:00
|
|
|
Destroyer *destroyer) {
|
2011-07-13 00:41:08 +08:00
|
|
|
pushFullExprCleanup<IrregularPartialArrayDestroy>(EHCleanup,
|
|
|
|
arrayBegin, arrayEndPointer,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
elementType, elementAlign,
|
|
|
|
destroyer);
|
2011-07-11 16:38:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// pushRegularPartialArrayCleanup - Push an EH cleanup to destroy
|
2011-07-09 09:37:26 +08:00
|
|
|
/// already-constructed elements of the given array. The cleanup
|
2011-07-11 16:38:19 +08:00
|
|
|
/// may be popped with DeactivateCleanupBlock or PopCleanupBlock.
|
2011-08-24 06:38:00 +08:00
|
|
|
///
|
2011-07-09 09:37:26 +08:00
|
|
|
/// \param elementType - the immediate element type of the array;
|
|
|
|
/// possibly still an array type
|
2011-07-11 16:38:19 +08:00
|
|
|
void CodeGenFunction::pushRegularPartialArrayCleanup(llvm::Value *arrayBegin,
|
|
|
|
llvm::Value *arrayEnd,
|
|
|
|
QualType elementType,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 elementAlign,
|
2012-01-26 11:33:36 +08:00
|
|
|
Destroyer *destroyer) {
|
2011-07-13 00:41:08 +08:00
|
|
|
pushFullExprCleanup<RegularPartialArrayDestroy>(EHCleanup,
|
2011-07-11 16:38:19 +08:00
|
|
|
arrayBegin, arrayEnd,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
elementType, elementAlign,
|
|
|
|
destroyer);
|
2011-07-09 09:37:26 +08:00
|
|
|
}
|
|
|
|
|
2013-03-23 14:43:35 +08:00
|
|
|
/// Lazily declare the @llvm.lifetime.start intrinsic.
|
|
|
|
llvm::Constant *CodeGenModule::getLLVMLifetimeStartFn() {
|
|
|
|
if (LifetimeStartFn) return LifetimeStartFn;
|
|
|
|
LifetimeStartFn = llvm::Intrinsic::getDeclaration(&getModule(),
|
|
|
|
llvm::Intrinsic::lifetime_start);
|
|
|
|
return LifetimeStartFn;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Lazily declare the @llvm.lifetime.end intrinsic.
|
|
|
|
llvm::Constant *CodeGenModule::getLLVMLifetimeEndFn() {
|
|
|
|
if (LifetimeEndFn) return LifetimeEndFn;
|
|
|
|
LifetimeEndFn = llvm::Intrinsic::getDeclaration(&getModule(),
|
|
|
|
llvm::Intrinsic::lifetime_end);
|
|
|
|
return LifetimeEndFn;
|
|
|
|
}
|
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
namespace {
|
|
|
|
/// A cleanup to perform a release of an object at the end of a
|
|
|
|
/// function. This is used to balance out the incoming +1 of a
|
|
|
|
/// ns_consumed argument when we can't reasonably do that just by
|
|
|
|
/// not doing the initial retain for a __block argument.
|
2015-08-19 06:40:54 +08:00
|
|
|
struct ConsumeARCParameter final : EHScopeStack::Cleanup {
|
2013-03-13 11:10:54 +08:00
|
|
|
ConsumeARCParameter(llvm::Value *param,
|
|
|
|
ARCPreciseLifetime_t precise)
|
|
|
|
: Param(param), Precise(precise) {}
|
2011-06-16 07:02:42 +08:00
|
|
|
|
|
|
|
llvm::Value *Param;
|
2013-03-13 11:10:54 +08:00
|
|
|
ARCPreciseLifetime_t Precise;
|
2011-06-16 07:02:42 +08:00
|
|
|
|
2014-03-12 14:41:41 +08:00
|
|
|
void Emit(CodeGenFunction &CGF, Flags flags) override {
|
2013-03-13 11:10:54 +08:00
|
|
|
CGF.EmitARCRelease(Param, Precise);
|
2011-06-16 07:02:42 +08:00
|
|
|
}
|
|
|
|
};
|
2015-06-23 07:07:51 +08:00
|
|
|
}
|
2011-06-16 07:02:42 +08:00
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
/// Emit an alloca (or GlobalValue depending on target)
|
2008-05-08 13:58:21 +08:00
|
|
|
/// for the specified parameter and set up LocalDeclMap.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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::EmitParmDecl(const VarDecl &D, ParamValue Arg,
|
|
|
|
unsigned ArgNo) {
|
2008-08-16 11:19:19 +08:00
|
|
|
// FIXME: Why isn't ImplicitParamDecl a ParmVarDecl?
|
2008-10-31 17:52:39 +08:00
|
|
|
assert((isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)) &&
|
2008-08-16 11:19:19 +08:00
|
|
|
"Invalid argument to EmitParmDecl");
|
2011-02-23 06:38:33 +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
|
|
|
Arg.getAnyValue()->setName(D.getName());
|
2011-02-23 06:38:33 +08:00
|
|
|
|
2013-03-15 01:53:33 +08:00
|
|
|
QualType Ty = D.getType();
|
|
|
|
|
2011-02-23 06:38:33 +08:00
|
|
|
// Use better IR generation for certain implicit parameters.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 (auto IPD = dyn_cast<ImplicitParamDecl>(&D)) {
|
2011-02-23 06:38:33 +08:00
|
|
|
// The only implicit argument a block has is its 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
|
|
|
// We assume this is always passed directly.
|
2011-02-23 06:38:33 +08:00
|
|
|
if (BlockInfo) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
setBlockContextParameter(IPD, ArgNo, Arg.getDirectValue());
|
2011-02-23 06:38:33 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Address DeclPtr = Address::invalid();
|
2014-02-01 08:04:45 +08:00
|
|
|
bool DoStore = false;
|
|
|
|
bool IsScalar = hasScalarEvaluationKind(Ty);
|
|
|
|
// If we already have a pointer to the argument, reuse the input 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
|
|
|
if (Arg.isIndirect()) {
|
|
|
|
DeclPtr = Arg.getIndirectAddress();
|
2014-04-02 08:16:53 +08:00
|
|
|
// If we have a prettier pointer type at this point, bitcast to that.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
unsigned AS = DeclPtr.getType()->getAddressSpace();
|
2014-04-02 08:16:53 +08:00
|
|
|
llvm::Type *IRTy = ConvertTypeForMem(Ty)->getPointerTo(AS);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more 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 (DeclPtr.getType() != IRTy)
|
|
|
|
DeclPtr = Builder.CreateBitCast(DeclPtr, IRTy, D.getName());
|
|
|
|
|
2013-06-21 20:45:15 +08:00
|
|
|
// Push a destructor cleanup for this parameter if the ABI requires it.
|
2014-07-26 05:39:46 +08:00
|
|
|
// Don't push a cleanup in a thunk for a method that will also emit a
|
|
|
|
// cleanup.
|
|
|
|
if (!IsScalar && !CurFuncIsThunk &&
|
2013-12-05 03:23:12 +08:00
|
|
|
getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) {
|
2014-02-01 08:04:45 +08:00
|
|
|
const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
|
|
|
|
if (RD && RD->hasNonTrivialDestructor())
|
|
|
|
pushDestroy(QualType::DK_cxx_destructor, DeclPtr, Ty);
|
2013-06-21 20:45:15 +08:00
|
|
|
}
|
2007-06-14 04:44:40 +08:00
|
|
|
} else {
|
2010-02-09 06:53:07 +08:00
|
|
|
// Otherwise, create a temporary to hold the value.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
DeclPtr = CreateMemTemp(Ty, getContext().getDeclAlign(&D),
|
|
|
|
D.getName() + ".addr");
|
2014-02-01 08:04:45 +08:00
|
|
|
DoStore = true;
|
|
|
|
}
|
2010-02-09 06:53:07 +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 *ArgVal = (DoStore ? Arg.getDirectValue() : nullptr);
|
|
|
|
|
|
|
|
LValue lv = MakeAddrLValue(DeclPtr, Ty);
|
2014-02-01 08:04:45 +08:00
|
|
|
if (IsScalar) {
|
2011-06-16 07:02:42 +08:00
|
|
|
Qualifiers qs = Ty.getQualifiers();
|
|
|
|
if (Qualifiers::ObjCLifetime lt = qs.getObjCLifetime()) {
|
|
|
|
// We honor __attribute__((ns_consumed)) for types with lifetime.
|
|
|
|
// For __strong, it's handled by just skipping the initial retain;
|
|
|
|
// otherwise we have to balance out the initial +1 with an extra
|
|
|
|
// cleanup to do the release at the end of the function.
|
|
|
|
bool isConsumed = D.hasAttr<NSConsumedAttr>();
|
|
|
|
|
|
|
|
// 'self' is always formally __strong, but if this is not an
|
|
|
|
// init method then we don't want to retain it.
|
2011-06-17 14:42:21 +08:00
|
|
|
if (D.isARCPseudoStrong()) {
|
2011-06-16 07:02:42 +08:00
|
|
|
const ObjCMethodDecl *method = cast<ObjCMethodDecl>(CurCodeDecl);
|
|
|
|
assert(&D == method->getSelfDecl());
|
2011-06-17 14:42:21 +08:00
|
|
|
assert(lt == Qualifiers::OCL_Strong);
|
|
|
|
assert(qs.hasConst());
|
2011-06-16 07:02:42 +08:00
|
|
|
assert(method->getMethodFamily() != OMF_init);
|
2011-06-16 07:40:09 +08:00
|
|
|
(void) method;
|
2011-06-16 07:02:42 +08:00
|
|
|
lt = Qualifiers::OCL_ExplicitNone;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lt == Qualifiers::OCL_Strong) {
|
2013-02-21 08:40:10 +08:00
|
|
|
if (!isConsumed) {
|
|
|
|
if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
|
|
|
|
// use objc_storeStrong(&dest, value) for retaining the
|
|
|
|
// object. But first, store a null into 'dest' because
|
|
|
|
// objc_storeStrong attempts to release its old value.
|
2013-10-02 10:29:49 +08:00
|
|
|
llvm::Value *Null = CGM.EmitNullConstant(D.getType());
|
2013-02-21 08:40:10 +08:00
|
|
|
EmitStoreOfScalar(Null, lv, /* isInitialization */ 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
|
|
|
EmitARCStoreStrongCall(lv.getAddress(), ArgVal, true);
|
2014-02-01 08:04:45 +08:00
|
|
|
DoStore = false;
|
2013-02-21 08:40:10 +08:00
|
|
|
}
|
|
|
|
else
|
2011-06-16 07:02:42 +08:00
|
|
|
// Don't use objc_retainBlock for block pointers, because we
|
|
|
|
// don't want to Block_copy something just because we got it
|
|
|
|
// as a parameter.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
ArgVal = EmitARCRetainNonBlock(ArgVal);
|
2013-02-21 08:40:10 +08:00
|
|
|
}
|
2011-06-16 07:02:42 +08:00
|
|
|
} else {
|
|
|
|
// Push the cleanup for a consumed parameter.
|
2013-03-13 11:10:54 +08:00
|
|
|
if (isConsumed) {
|
|
|
|
ARCPreciseLifetime_t precise = (D.hasAttr<ObjCPreciseLifetimeAttr>()
|
|
|
|
? ARCPreciseLifetime : ARCImpreciseLifetime);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
EHStack.pushCleanup<ConsumeARCParameter>(getARCCleanupKind(), ArgVal,
|
2013-03-13 11:10:54 +08:00
|
|
|
precise);
|
|
|
|
}
|
2011-06-16 07:02:42 +08:00
|
|
|
|
|
|
|
if (lt == 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
|
|
|
EmitARCInitWeak(DeclPtr, ArgVal);
|
2014-02-01 08:04:45 +08:00
|
|
|
DoStore = false; // The weak init is a store, no need to do two.
|
2011-06-16 07:02:42 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Enter the cleanup scope.
|
|
|
|
EmitAutoVarWithLifetime(*this, D, DeclPtr, lt);
|
|
|
|
}
|
2007-06-14 04:44:40 +08:00
|
|
|
}
|
|
|
|
|
2014-02-01 08:04:45 +08:00
|
|
|
// Store the initial value into the alloca.
|
|
|
|
if (DoStore)
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
EmitStoreOfScalar(ArgVal, lv, /* isInitialization */ true);
|
2014-02-01 08:04:45 +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(&D, DeclPtr);
|
2008-05-30 18:30:31 +08:00
|
|
|
|
|
|
|
// Emit debug info for param declaration.
|
2012-05-04 15:39:27 +08:00
|
|
|
if (CGDebugInfo *DI = getDebugInfo()) {
|
2016-02-02 19:06:51 +08:00
|
|
|
if (CGM.getCodeGenOpts().getDebugInfo() >=
|
|
|
|
codegenoptions::LimitedDebugInfo) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
DI->EmitDeclareOfArgVariable(&D, DeclPtr.getPointer(), ArgNo, Builder);
|
2012-05-04 15:39:27 +08:00
|
|
|
}
|
|
|
|
}
|
2011-09-10 06:41:49 +08:00
|
|
|
|
|
|
|
if (D.hasAttr<AnnotateAttr>())
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
EmitVarAnnotations(&D, DeclPtr.getPointer());
|
2007-06-14 04:44:40 +08:00
|
|
|
}
|