2007-06-01 18:02:12 +00:00
|
|
|
//===--- CGExpr.cpp - Emit LLVM Code from Expressions ---------------------===//
|
|
|
|
|
//
|
2019-01-19 08:50:56 +00:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2007-06-01 18:02:12 +00:00
|
|
|
//
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
//
|
|
|
|
|
// This contains code to emit Expr nodes as LLVM code.
|
|
|
|
|
//
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
2010-08-31 07:33:07 +00:00
|
|
|
#include "CGCXXABI.h"
|
2012-12-04 09:13:33 +00:00
|
|
|
#include "CGCall.h"
|
2016-07-01 21:08:47 +00:00
|
|
|
#include "CGCleanup.h"
|
2011-03-04 18:54:42 +00:00
|
|
|
#include "CGDebugInfo.h"
|
2008-08-13 00:59:25 +00:00
|
|
|
#include "CGObjCRuntime.h"
|
2014-11-11 04:05:39 +00:00
|
|
|
#include "CGOpenMPRuntime.h"
|
2012-12-04 09:13:33 +00:00
|
|
|
#include "CGRecordLayout.h"
|
2016-07-01 21:08:47 +00:00
|
|
|
#include "CodeGenFunction.h"
|
2012-12-04 09:13:33 +00:00
|
|
|
#include "CodeGenModule.h"
|
2017-08-15 21:42:52 +00:00
|
|
|
#include "ConstantEmitter.h"
|
2011-09-21 08:08:30 +00:00
|
|
|
#include "TargetInfo.h"
|
2008-08-11 05:00:27 +00:00
|
|
|
#include "clang/AST/ASTContext.h"
|
2014-05-19 18:15:42 +00:00
|
|
|
#include "clang/AST/Attr.h"
|
2015-01-14 11:29:14 +00:00
|
|
|
#include "clang/AST/DeclObjC.h"
|
2016-12-09 23:48:18 +00:00
|
|
|
#include "clang/AST/NSAPI.h"
|
[BPF] Preserve debuginfo array/union/struct type/access index
For background of BPF CO-RE project, please refer to
http://vger.kernel.org/bpfconf2019.html
In summary, BPF CO-RE intends to compile bpf programs
adjustable on struct/union layout change so the same
program can run on multiple kernels with adjustment
before loading based on native kernel structures.
In order to do this, we need keep track of GEP(getelementptr)
instruction base and result debuginfo types, so we
can adjust on the host based on kernel BTF info.
Capturing such information as an IR optimization is hard
as various optimization may have tweaked GEP and also
union is replaced by structure it is impossible to track
fieldindex for union member accesses.
Three intrinsic functions, preserve_{array,union,struct}_access_index,
are introducted.
addr = preserve_array_access_index(base, index, dimension)
addr = preserve_union_access_index(base, di_index)
addr = preserve_struct_access_index(base, gep_index, di_index)
here,
base: the base pointer for the array/union/struct access.
index: the last access index for array, the same for IR/DebugInfo layout.
dimension: the array dimension.
gep_index: the access index based on IR layout.
di_index: the access index based on user/debuginfo types.
If using these intrinsics blindly, i.e., transforming all GEPs
to these intrinsics and later on reducing them to GEPs, we have
seen up to 7% more instructions generated. To avoid such an overhead,
a clang builtin is proposed:
base = __builtin_preserve_access_index(base)
such that user wraps to-be-relocated GEPs in this builtin
and preserve_*_access_index intrinsics only apply to
those GEPs. Such a buyin will prevent performance degradation
if people do not use CO-RE, even for programs which use
bpf_probe_read().
For example, for the following example,
$ cat test.c
struct sk_buff {
int i;
int b1:1;
int b2:2;
union {
struct {
int o1;
int o2;
} o;
struct {
char flags;
char dev_id;
} dev;
int netid;
} u[10];
};
static int (*bpf_probe_read)(void *dst, int size, const void *unsafe_ptr)
= (void *) 4;
#define _(x) (__builtin_preserve_access_index(x))
int bpf_prog(struct sk_buff *ctx) {
char dev_id;
bpf_probe_read(&dev_id, sizeof(char), _(&ctx->u[5].dev.dev_id));
return dev_id;
}
$ clang -target bpf -O2 -g -emit-llvm -S -mllvm -print-before-all \
test.c >& log
The generated IR looks like below:
...
define dso_local i32 @bpf_prog(%struct.sk_buff*) #0 !dbg !15 {
%2 = alloca %struct.sk_buff*, align 8
%3 = alloca i8, align 1
store %struct.sk_buff* %0, %struct.sk_buff** %2, align 8, !tbaa !45
call void @llvm.dbg.declare(metadata %struct.sk_buff** %2, metadata !43, metadata !DIExpression()), !dbg !49
call void @llvm.lifetime.start.p0i8(i64 1, i8* %3) #4, !dbg !50
call void @llvm.dbg.declare(metadata i8* %3, metadata !44, metadata !DIExpression()), !dbg !51
%4 = load i32 (i8*, i32, i8*)*, i32 (i8*, i32, i8*)** @bpf_probe_read, align 8, !dbg !52, !tbaa !45
%5 = load %struct.sk_buff*, %struct.sk_buff** %2, align 8, !dbg !53, !tbaa !45
%6 = call [10 x %union.anon]* @llvm.preserve.struct.access.index.p0a10s_union.anons.p0s_struct.sk_buffs(
%struct.sk_buff* %5, i32 2, i32 3), !dbg !53, !llvm.preserve.access.index !19
%7 = call %union.anon* @llvm.preserve.array.access.index.p0s_union.anons.p0a10s_union.anons(
[10 x %union.anon]* %6, i32 1, i32 5), !dbg !53
%8 = call %union.anon* @llvm.preserve.union.access.index.p0s_union.anons.p0s_union.anons(
%union.anon* %7, i32 1), !dbg !53, !llvm.preserve.access.index !26
%9 = bitcast %union.anon* %8 to %struct.anon.0*, !dbg !53
%10 = call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.anon.0s(
%struct.anon.0* %9, i32 1, i32 1), !dbg !53, !llvm.preserve.access.index !34
%11 = call i32 %4(i8* %3, i32 1, i8* %10), !dbg !52
%12 = load i8, i8* %3, align 1, !dbg !54, !tbaa !55
%13 = sext i8 %12 to i32, !dbg !54
call void @llvm.lifetime.end.p0i8(i64 1, i8* %3) #4, !dbg !56
ret i32 %13, !dbg !57
}
!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "sk_buff", file: !3, line: 1, size: 704, elements: !20)
!26 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !19, file: !3, line: 5, size: 64, elements: !27)
!34 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !26, file: !3, line: 10, size: 16, elements: !35)
Note that @llvm.preserve.{struct,union}.access.index calls have metadata llvm.preserve.access.index
attached to instructions to provide struct/union debuginfo type information.
For &ctx->u[5].dev.dev_id,
. The "%6 = ..." represents struct member "u" with index 2 for IR layout and index 3 for DI layout.
. The "%7 = ..." represents array subscript "5".
. The "%8 = ..." represents union member "dev" with index 1 for DI layout.
. The "%10 = ..." represents struct member "dev_id" with index 1 for both IR and DI layout.
Basically, traversing the use-def chain recursively for the 3rd argument of bpf_probe_read() and
examining all preserve_*_access_index calls, the debuginfo struct/union/array access index
can be achieved.
The intrinsics also contain enough information to regenerate codes for IR layout.
For array and structure intrinsics, the proper GEP can be constructed.
For union intrinsics, replacing all uses of "addr" with "base" should be enough.
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D61809
llvm-svn: 365438
2019-07-09 04:21:50 +00:00
|
|
|
#include "clang/Basic/Builtins.h"
|
2018-12-11 03:18:39 +00:00
|
|
|
#include "clang/Basic/CodeGenOptions.h"
|
2020-02-27 11:01:58 -08:00
|
|
|
#include "clang/Basic/SourceManager.h"
|
2012-12-04 09:13:33 +00:00
|
|
|
#include "llvm/ADT/Hashing.h"
|
2014-10-09 08:45:04 +00:00
|
|
|
#include "llvm/ADT/StringExtras.h"
|
2013-01-02 11:45:17 +00:00
|
|
|
#include "llvm/IR/DataLayout.h"
|
|
|
|
|
#include "llvm/IR/Intrinsics.h"
|
|
|
|
|
#include "llvm/IR/LLVMContext.h"
|
|
|
|
|
#include "llvm/IR/MDBuilder.h"
|
2013-01-30 12:06:08 +00:00
|
|
|
#include "llvm/Support/ConvertUTF.h"
|
2015-05-11 21:39:14 +00:00
|
|
|
#include "llvm/Support/MathExtras.h"
|
2016-05-12 16:51:36 +00:00
|
|
|
#include "llvm/Support/Path.h"
|
2016-01-16 00:31:22 +00:00
|
|
|
#include "llvm/Transforms/Utils/SanitizerStats.h"
|
2013-01-30 12:06:08 +00:00
|
|
|
|
2016-12-12 16:43:40 +00:00
|
|
|
#include <string>
|
|
|
|
|
|
2007-06-01 18:02:12 +00:00
|
|
|
using namespace clang;
|
|
|
|
|
using namespace CodeGen;
|
|
|
|
|
|
2007-06-02 19:33:17 +00:00
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
// Miscellaneous Helper Methods
|
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
|
2011-02-08 08:22:06 +00:00
|
|
|
llvm::Value *CodeGenFunction::EmitCastToVoidPtr(llvm::Value *value) {
|
|
|
|
|
unsigned addressSpace =
|
2017-08-04 18:16:31 +00:00
|
|
|
cast<llvm::PointerType>(value->getType())->getAddressSpace();
|
2011-02-08 08:22:06 +00:00
|
|
|
|
2011-07-18 04:24:23 +00:00
|
|
|
llvm::PointerType *destType = Int8PtrTy;
|
2011-02-08 08:22:06 +00:00
|
|
|
if (addressSpace)
|
|
|
|
|
destType = llvm::Type::getInt8PtrTy(getLLVMContext(), addressSpace);
|
|
|
|
|
|
|
|
|
|
if (value->getType() == destType) return value;
|
|
|
|
|
return Builder.CreateBitCast(value, destType);
|
|
|
|
|
}
|
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
/// CreateTempAlloca - This creates a alloca and inserts it into the entry
|
|
|
|
|
/// block.
|
2018-06-15 15:33:22 +00:00
|
|
|
Address CodeGenFunction::CreateTempAllocaWithoutCast(llvm::Type *Ty,
|
|
|
|
|
CharUnits Align,
|
|
|
|
|
const Twine &Name,
|
|
|
|
|
llvm::Value *ArraySize) {
|
|
|
|
|
auto Alloca = CreateTempAlloca(Ty, Name, ArraySize);
|
2019-10-03 13:00:29 +00:00
|
|
|
Alloca->setAlignment(Align.getAsAlign());
|
2018-06-15 15:33:22 +00:00
|
|
|
return Address(Alloca, Align);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// CreateTempAlloca - This creates a alloca and inserts it into the entry
|
|
|
|
|
/// block. The alloca is casted to default address space if necessary.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Address CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, CharUnits Align,
|
2017-06-19 17:03:41 +00:00
|
|
|
const Twine &Name,
|
|
|
|
|
llvm::Value *ArraySize,
|
2018-06-15 15:33:22 +00:00
|
|
|
Address *AllocaAddr) {
|
|
|
|
|
auto Alloca = CreateTempAllocaWithoutCast(Ty, Align, Name, ArraySize);
|
2018-05-17 11:16:35 +00:00
|
|
|
if (AllocaAddr)
|
2018-06-15 15:33:22 +00:00
|
|
|
*AllocaAddr = Alloca;
|
|
|
|
|
llvm::Value *V = Alloca.getPointer();
|
2017-06-19 17:03:41 +00:00
|
|
|
// Alloca always returns a pointer in alloca address space, which may
|
|
|
|
|
// be different from the type defined by the language. For example,
|
|
|
|
|
// in C++ the auto variables are in the default address space. Therefore
|
|
|
|
|
// cast alloca to the default address space when necessary.
|
2018-06-15 15:33:22 +00:00
|
|
|
if (getASTAllocaAddressSpace() != LangAS::Default) {
|
2017-06-19 17:03:41 +00:00
|
|
|
auto DestAddrSpace = getContext().getTargetAddressSpace(LangAS::Default);
|
2017-10-24 19:14:43 +00:00
|
|
|
llvm::IRBuilderBase::InsertPointGuard IPG(Builder);
|
2017-10-30 14:38:30 +00:00
|
|
|
// When ArraySize is nullptr, alloca is inserted at AllocaInsertPt,
|
|
|
|
|
// otherwise alloca is inserted at the current insertion point of the
|
|
|
|
|
// builder.
|
|
|
|
|
if (!ArraySize)
|
|
|
|
|
Builder.SetInsertPoint(AllocaInsertPt);
|
2017-06-19 17:03:41 +00:00
|
|
|
V = getTargetHooks().performAddrSpaceCast(
|
|
|
|
|
*this, V, getASTAllocaAddressSpace(), LangAS::Default,
|
|
|
|
|
Ty->getPointerTo(DestAddrSpace), /*non-null*/ true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Address(V, Align);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
}
|
|
|
|
|
|
2017-06-19 17:03:41 +00:00
|
|
|
/// CreateTempAlloca - This creates an alloca and inserts it into the entry
|
|
|
|
|
/// block if \p ArraySize is nullptr, otherwise inserts it at the current
|
|
|
|
|
/// insertion point of the builder.
|
2011-07-18 04:24:23 +00:00
|
|
|
llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(llvm::Type *Ty,
|
2017-06-19 17:03:41 +00:00
|
|
|
const Twine &Name,
|
|
|
|
|
llvm::Value *ArraySize) {
|
|
|
|
|
if (ArraySize)
|
|
|
|
|
return Builder.CreateAlloca(Ty, ArraySize, Name);
|
2017-04-10 22:28:02 +00:00
|
|
|
return new llvm::AllocaInst(Ty, CGM.getDataLayout().getAllocaAddrSpace(),
|
2017-06-19 17:03:41 +00:00
|
|
|
ArraySize, Name, AllocaInsertPt);
|
2007-06-22 21:44:33 +00:00
|
|
|
}
|
2007-06-05 20:53:16 +00: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 08:05:57 +00:00
|
|
|
/// CreateDefaultAlignTempAlloca - This creates an alloca with the
|
|
|
|
|
/// default alignment of the corresponding LLVM type, which is *not*
|
|
|
|
|
/// guaranteed to be related in any way to the expected alignment of
|
|
|
|
|
/// an AST type that might have been lowered to Ty.
|
|
|
|
|
Address CodeGenFunction::CreateDefaultAlignTempAlloca(llvm::Type *Ty,
|
|
|
|
|
const Twine &Name) {
|
|
|
|
|
CharUnits Align =
|
|
|
|
|
CharUnits::fromQuantity(CGM.getDataLayout().getABITypeAlignment(Ty));
|
|
|
|
|
return CreateTempAlloca(Ty, Align, Name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CodeGenFunction::InitTempAlloca(Address Var, llvm::Value *Init) {
|
2020-08-03 05:29:48 +00:00
|
|
|
auto *Alloca = Var.getPointer();
|
|
|
|
|
assert(isa<llvm::AllocaInst>(Alloca) ||
|
|
|
|
|
(isa<llvm::AddrSpaceCastInst>(Alloca) &&
|
|
|
|
|
isa<llvm::AllocaInst>(
|
|
|
|
|
cast<llvm::AddrSpaceCastInst>(Alloca)->getPointerOperand())));
|
|
|
|
|
|
|
|
|
|
auto *Store = new llvm::StoreInst(Init, Alloca, /*volatile*/ false,
|
2020-05-14 14:48:10 -07:00
|
|
|
Var.getAlignment().getAsAlign());
|
2010-04-22 01:10:34 +00:00
|
|
|
llvm::BasicBlock *Block = AllocaInsertPt->getParent();
|
2015-11-06 23:00:41 +00:00
|
|
|
Block->getInstList().insertAfter(AllocaInsertPt->getIterator(), Store);
|
2010-04-22 01:10:34 +00: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 08:05:57 +00:00
|
|
|
Address CodeGenFunction::CreateIRTemp(QualType Ty, const Twine &Name) {
|
2010-02-16 19:44:13 +00:00
|
|
|
CharUnits Align = getContext().getTypeAlignInChars(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 08:05:57 +00:00
|
|
|
return CreateTempAlloca(ConvertType(Ty), Align, Name);
|
2010-02-16 19:44:13 +00:00
|
|
|
}
|
|
|
|
|
|
2017-06-19 17:03:41 +00:00
|
|
|
Address CodeGenFunction::CreateMemTemp(QualType Ty, const Twine &Name,
|
2018-06-15 15:33:22 +00:00
|
|
|
Address *Alloca) {
|
2010-02-09 02:48:28 +00:00
|
|
|
// FIXME: Should we prefer the preferred type alignment here?
|
2018-06-15 15:33:22 +00:00
|
|
|
return CreateMemTemp(Ty, getContext().getTypeAlignInChars(Ty), Name, Alloca);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Address CodeGenFunction::CreateMemTemp(QualType Ty, CharUnits Align,
|
2018-06-15 15:33:22 +00:00
|
|
|
const Twine &Name, Address *Alloca) {
|
2020-05-11 17:45:51 +01:00
|
|
|
Address Result = CreateTempAlloca(ConvertTypeForMem(Ty), Align, Name,
|
|
|
|
|
/*ArraySize=*/nullptr, Alloca);
|
|
|
|
|
|
|
|
|
|
if (Ty->isConstantMatrixType()) {
|
|
|
|
|
auto *ArrayTy = cast<llvm::ArrayType>(Result.getType()->getElementType());
|
2020-06-01 09:55:24 -07:00
|
|
|
auto *VectorTy = llvm::FixedVectorType::get(ArrayTy->getElementType(),
|
|
|
|
|
ArrayTy->getNumElements());
|
2020-05-11 17:45:51 +01:00
|
|
|
|
|
|
|
|
Result = Address(
|
|
|
|
|
Builder.CreateBitCast(Result.getPointer(), VectorTy->getPointerTo()),
|
|
|
|
|
Result.getAlignment());
|
|
|
|
|
}
|
|
|
|
|
return Result;
|
2018-06-15 15:33:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Address CodeGenFunction::CreateMemTempWithoutCast(QualType Ty, CharUnits Align,
|
|
|
|
|
const Twine &Name) {
|
|
|
|
|
return CreateTempAllocaWithoutCast(ConvertTypeForMem(Ty), Align, Name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Address CodeGenFunction::CreateMemTempWithoutCast(QualType Ty,
|
|
|
|
|
const Twine &Name) {
|
|
|
|
|
return CreateMemTempWithoutCast(Ty, getContext().getTypeAlignInChars(Ty),
|
|
|
|
|
Name);
|
2010-02-09 02:48:28 +00:00
|
|
|
}
|
|
|
|
|
|
2007-06-05 20:53:16 +00:00
|
|
|
/// EvaluateExprAsBool - Perform the usual unary conversions on the specified
|
|
|
|
|
/// expression and compare the result against zero, returning an Int1Ty value.
|
2007-06-15 23:05:46 +00:00
|
|
|
llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) {
|
Change PGO instrumentation to compute counts in a separate AST traversal.
Previously, we made one traversal of the AST prior to codegen to assign
counters to the ASTs and then propagated the count values during codegen. This
patch now adds a separate AST traversal prior to codegen for the
-fprofile-instr-use option to propagate the count values. The counts are then
saved in a map from which they can be retrieved during codegen.
This new approach has several advantages:
1. It gets rid of a lot of extra PGO-related code that had previously been
added to codegen.
2. It fixes a serious bug. My original implementation (which was mailed to the
list but never committed) used 3 counters for every loop. Justin improved it to
move 2 of those counters into the less-frequently executed breaks and continues,
but that turned out to produce wrong count values in some cases. The solution
requires visiting a loop body before the condition so that the count for the
condition properly includes the break and continue counts. Changing codegen to
visit a loop body first would be a fairly invasive change, but with a separate
AST traversal, it is easy to control the order of traversal. I've added a
testcase (provided by Justin) to make sure this works correctly.
3. It improves the instrumentation overhead, reducing the number of counters for
a loop from 3 to 1. We no longer need dedicated counters for breaks and
continues, since we can just use the propagated count values when visiting
breaks and continues.
To make this work, I needed to make a change to the way we count case
statements, going back to my original approach of not including the fall-through
in the counter values. This was necessary because there isn't always an AST node
that can be used to record the fall-through count. Now case statements are
handled the same as default statements, with the fall-through paths branching
over the counter increments. While I was at it, I also went back to using this
approach for do-loops -- omitting the fall-through count into the loop body
simplifies some of the calculations and make them behave the same as other
loops. Whenever we start using this instrumentation for coverage, we'll need
to add the fall-through counts into the counter values.
llvm-svn: 201528
2014-02-17 19:21:09 +00:00
|
|
|
PGO.setCurrentStmt(E);
|
2010-08-23 01:21:21 +00:00
|
|
|
if (const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>()) {
|
2010-08-22 10:59:02 +00:00
|
|
|
llvm::Value *MemPtr = EmitScalarExpr(E);
|
2011-02-08 08:22:06 +00:00
|
|
|
return CGM.getCXXABI().EmitMemberPointerIsNotNull(*this, MemPtr, MPT);
|
2009-12-11 09:26:29 +00:00
|
|
|
}
|
2010-08-23 01:21:21 +00:00
|
|
|
|
|
|
|
|
QualType BoolTy = getContext().BoolTy;
|
2015-08-11 04:19:28 +00:00
|
|
|
SourceLocation Loc = E->getExprLoc();
|
2020-11-06 10:44:13 -05:00
|
|
|
CGFPOptionsRAII FPOptsRAII(*this, E);
|
2008-04-04 16:54:41 +00:00
|
|
|
if (!E->getType()->isAnyComplexType())
|
2015-08-11 04:19:28 +00:00
|
|
|
return EmitScalarConversion(EmitScalarExpr(E), E->getType(), BoolTy, Loc);
|
2007-06-05 20:53:16 +00:00
|
|
|
|
2015-08-11 04:19:28 +00:00
|
|
|
return EmitComplexToScalarConversion(EmitComplexExpr(E), E->getType(), BoolTy,
|
|
|
|
|
Loc);
|
2007-06-02 19:33:17 +00:00
|
|
|
}
|
|
|
|
|
|
2010-12-05 02:00:02 +00:00
|
|
|
/// EmitIgnoredExpr - Emit code to compute the specified expression,
|
|
|
|
|
/// ignoring the result.
|
|
|
|
|
void CodeGenFunction::EmitIgnoredExpr(const Expr *E) {
|
|
|
|
|
if (E->isRValue())
|
|
|
|
|
return (void) EmitAnyExpr(E, AggValueSlot::ignored(), true);
|
|
|
|
|
|
|
|
|
|
// Just emit it as an l-value and drop the result.
|
|
|
|
|
EmitLValue(E);
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-15 10:14:12 +00:00
|
|
|
/// EmitAnyExpr - Emit code to compute the specified expression which
|
|
|
|
|
/// can have any type. The result is returned as an RValue struct.
|
|
|
|
|
/// If this is an aggregate expression, AggSlot indicates where the
|
2009-09-09 13:00:44 +00:00
|
|
|
/// result should be returned.
|
2012-07-02 23:58:38 +00:00
|
|
|
RValue CodeGenFunction::EmitAnyExpr(const Expr *E,
|
|
|
|
|
AggValueSlot aggSlot,
|
|
|
|
|
bool ignoreResult) {
|
2013-03-07 21:37:08 +00:00
|
|
|
switch (getEvaluationKind(E->getType())) {
|
|
|
|
|
case TEK_Scalar:
|
2012-07-02 23:58:38 +00:00
|
|
|
return RValue::get(EmitScalarExpr(E, ignoreResult));
|
2013-03-07 21:37:08 +00:00
|
|
|
case TEK_Complex:
|
2012-07-02 23:58:38 +00:00
|
|
|
return RValue::getComplex(EmitComplexExpr(E, ignoreResult, ignoreResult));
|
2013-03-07 21:37:08 +00:00
|
|
|
case TEK_Aggregate:
|
|
|
|
|
if (!ignoreResult && aggSlot.isIgnored())
|
|
|
|
|
aggSlot = CreateAggTemp(E->getType(), "agg-temp");
|
|
|
|
|
EmitAggExpr(E, aggSlot);
|
|
|
|
|
return aggSlot.asRValue();
|
|
|
|
|
}
|
|
|
|
|
llvm_unreachable("bad evaluation kind");
|
2007-08-31 22:49:20 +00:00
|
|
|
}
|
|
|
|
|
|
2018-03-08 00:22:04 +00:00
|
|
|
/// EmitAnyExprToTemp - Similar to EmitAnyExpr(), however, the result will
|
2009-09-09 13:00:44 +00:00
|
|
|
/// always be accessible even if no aggregate location is provided.
|
2010-09-15 10:14:12 +00:00
|
|
|
RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E) {
|
|
|
|
|
AggValueSlot AggSlot = AggValueSlot::ignored();
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2013-03-07 21:37:08 +00:00
|
|
|
if (hasAggregateEvaluationKind(E->getType()))
|
2010-09-15 10:14:12 +00:00
|
|
|
AggSlot = CreateAggTemp(E->getType(), "agg.tmp");
|
|
|
|
|
return EmitAnyExpr(E, AggSlot);
|
2008-09-09 01:06:48 +00:00
|
|
|
}
|
|
|
|
|
|
2010-04-21 10:05:39 +00:00
|
|
|
/// EmitAnyExprToMem - Evaluate an expression into a given memory
|
|
|
|
|
/// location.
|
|
|
|
|
void CodeGenFunction::EmitAnyExprToMem(const Expr *E,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Address Location,
|
2012-03-29 17:37:10 +00:00
|
|
|
Qualifiers Quals,
|
|
|
|
|
bool IsInit) {
|
2011-12-03 00:54:26 +00:00
|
|
|
// FIXME: This function should take an LValue as an argument.
|
2013-03-07 21:37:08 +00:00
|
|
|
switch (getEvaluationKind(E->getType())) {
|
|
|
|
|
case TEK_Complex:
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
EmitComplexExprIntoLValue(E, MakeAddrLValue(Location, E->getType()),
|
2013-03-07 21:37:08 +00:00
|
|
|
/*isInit*/ false);
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case TEK_Aggregate: {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
EmitAggExpr(E, AggValueSlot::forAddr(Location, Quals,
|
2012-03-29 17:37:10 +00:00
|
|
|
AggValueSlot::IsDestructed_t(IsInit),
|
2011-08-26 05:38:08 +00:00
|
|
|
AggValueSlot::DoesNotNeedGCBarriers,
|
2018-04-05 20:52:58 +00:00
|
|
|
AggValueSlot::IsAliased_t(!IsInit),
|
|
|
|
|
AggValueSlot::MayOverlap));
|
2013-03-07 21:37:08 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case TEK_Scalar: {
|
2010-04-21 10:05:39 +00:00
|
|
|
RValue RV = RValue::get(EmitScalarExpr(E, /*Ignore*/ false));
|
2010-08-21 03:08:16 +00:00
|
|
|
LValue LV = MakeAddrLValue(Location, E->getType());
|
2011-06-25 02:11:03 +00:00
|
|
|
EmitStoreThroughLValue(RV, LV);
|
2013-03-07 21:37:08 +00:00
|
|
|
return;
|
2010-04-21 10:05:39 +00:00
|
|
|
}
|
2013-03-07 21:37:08 +00:00
|
|
|
}
|
|
|
|
|
llvm_unreachable("bad evaluation kind");
|
2010-04-21 10:05:39 +00:00
|
|
|
}
|
|
|
|
|
|
2014-10-10 04:05:00 +00:00
|
|
|
static void
|
|
|
|
|
pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
const Expr *E, Address ReferenceTemporary) {
|
2013-06-12 20:42:33 +00:00
|
|
|
// Objective-C++ ARC:
|
|
|
|
|
// If we are binding a reference to a temporary that has ownership, we
|
|
|
|
|
// need to perform retain/release operations on the temporary.
|
|
|
|
|
//
|
|
|
|
|
// FIXME: This should be looking at E, not M.
|
Define weak and __weak to mean ARC-style weak references, even in MRC.
Previously, __weak was silently accepted and ignored in MRC mode.
That makes this a potentially source-breaking change that we have to
roll out cautiously. Accordingly, for the time being, actual support
for __weak references in MRC is experimental, and the compiler will
reject attempts to actually form such references. The intent is to
eventually enable the feature by default in all non-GC modes.
(It is, of course, incompatible with ObjC GC's interpretation of
__weak.)
If you like, you can enable this feature with
-Xclang -fobjc-weak
but like any -Xclang option, this option may be removed at any point,
e.g. if/when it is eventually enabled by default.
This patch also enables the use of the ARC __unsafe_unretained qualifier
in MRC. Unlike __weak, this is being enabled immediately. Since
variables are essentially __unsafe_unretained by default in MRC,
the only practical uses are (1) communication and (2) changing the
default behavior of by-value block capture.
As an implementation matter, this means that the ObjC ownership
qualifiers may appear in any ObjC language mode, and so this patch
removes a number of checks for getLangOpts().ObjCAutoRefCount
that were guarding the processing of these qualifiers. I don't
expect this to be a significant drain on performance; it may even
be faster to just check for these qualifiers directly on a type
(since it's probably in a register anyway) than to do N dependent
loads to grab the LangOptions.
rdar://9674298
llvm-svn: 251041
2015-10-22 18:38:17 +00:00
|
|
|
if (auto Lifetime = M->getType().getObjCLifetime()) {
|
|
|
|
|
switch (Lifetime) {
|
2013-06-12 20:42:33 +00:00
|
|
|
case Qualifiers::OCL_None:
|
|
|
|
|
case Qualifiers::OCL_ExplicitNone:
|
|
|
|
|
// Carry on to normal cleanup handling.
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Qualifiers::OCL_Autoreleasing:
|
|
|
|
|
// Nothing to do; cleaned up by an autorelease pool.
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case Qualifiers::OCL_Strong:
|
|
|
|
|
case Qualifiers::OCL_Weak:
|
|
|
|
|
switch (StorageDuration Duration = M->getStorageDuration()) {
|
|
|
|
|
case SD_Static:
|
|
|
|
|
// Note: we intentionally do not register a cleanup to release
|
|
|
|
|
// the object on program termination.
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case SD_Thread:
|
|
|
|
|
// FIXME: We should probably register a cleanup in this case.
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case SD_Automatic:
|
|
|
|
|
case SD_FullExpression:
|
|
|
|
|
CodeGenFunction::Destroyer *Destroy;
|
|
|
|
|
CleanupKind CleanupKind;
|
|
|
|
|
if (Lifetime == Qualifiers::OCL_Strong) {
|
|
|
|
|
const ValueDecl *VD = M->getExtendingDecl();
|
|
|
|
|
bool Precise =
|
|
|
|
|
VD && isa<VarDecl>(VD) && VD->hasAttr<ObjCPreciseLifetimeAttr>();
|
|
|
|
|
CleanupKind = CGF.getARCCleanupKind();
|
|
|
|
|
Destroy = Precise ? &CodeGenFunction::destroyARCStrongPrecise
|
|
|
|
|
: &CodeGenFunction::destroyARCStrongImprecise;
|
|
|
|
|
} else {
|
|
|
|
|
// __weak objects always get EH cleanups; otherwise, exceptions
|
|
|
|
|
// could cause really nasty crashes instead of mere leaks.
|
|
|
|
|
CleanupKind = NormalAndEHCleanup;
|
|
|
|
|
Destroy = &CodeGenFunction::destroyARCWeak;
|
|
|
|
|
}
|
|
|
|
|
if (Duration == SD_FullExpression)
|
|
|
|
|
CGF.pushDestroy(CleanupKind, ReferenceTemporary,
|
Define weak and __weak to mean ARC-style weak references, even in MRC.
Previously, __weak was silently accepted and ignored in MRC mode.
That makes this a potentially source-breaking change that we have to
roll out cautiously. Accordingly, for the time being, actual support
for __weak references in MRC is experimental, and the compiler will
reject attempts to actually form such references. The intent is to
eventually enable the feature by default in all non-GC modes.
(It is, of course, incompatible with ObjC GC's interpretation of
__weak.)
If you like, you can enable this feature with
-Xclang -fobjc-weak
but like any -Xclang option, this option may be removed at any point,
e.g. if/when it is eventually enabled by default.
This patch also enables the use of the ARC __unsafe_unretained qualifier
in MRC. Unlike __weak, this is being enabled immediately. Since
variables are essentially __unsafe_unretained by default in MRC,
the only practical uses are (1) communication and (2) changing the
default behavior of by-value block capture.
As an implementation matter, this means that the ObjC ownership
qualifiers may appear in any ObjC language mode, and so this patch
removes a number of checks for getLangOpts().ObjCAutoRefCount
that were guarding the processing of these qualifiers. I don't
expect this to be a significant drain on performance; it may even
be faster to just check for these qualifiers directly on a type
(since it's probably in a register anyway) than to do N dependent
loads to grab the LangOptions.
rdar://9674298
llvm-svn: 251041
2015-10-22 18:38:17 +00:00
|
|
|
M->getType(), *Destroy,
|
2013-06-12 20:42:33 +00:00
|
|
|
CleanupKind & EHCleanup);
|
|
|
|
|
else
|
|
|
|
|
CGF.pushLifetimeExtendedDestroy(CleanupKind, ReferenceTemporary,
|
Define weak and __weak to mean ARC-style weak references, even in MRC.
Previously, __weak was silently accepted and ignored in MRC mode.
That makes this a potentially source-breaking change that we have to
roll out cautiously. Accordingly, for the time being, actual support
for __weak references in MRC is experimental, and the compiler will
reject attempts to actually form such references. The intent is to
eventually enable the feature by default in all non-GC modes.
(It is, of course, incompatible with ObjC GC's interpretation of
__weak.)
If you like, you can enable this feature with
-Xclang -fobjc-weak
but like any -Xclang option, this option may be removed at any point,
e.g. if/when it is eventually enabled by default.
This patch also enables the use of the ARC __unsafe_unretained qualifier
in MRC. Unlike __weak, this is being enabled immediately. Since
variables are essentially __unsafe_unretained by default in MRC,
the only practical uses are (1) communication and (2) changing the
default behavior of by-value block capture.
As an implementation matter, this means that the ObjC ownership
qualifiers may appear in any ObjC language mode, and so this patch
removes a number of checks for getLangOpts().ObjCAutoRefCount
that were guarding the processing of these qualifiers. I don't
expect this to be a significant drain on performance; it may even
be faster to just check for these qualifiers directly on a type
(since it's probably in a register anyway) than to do N dependent
loads to grab the LangOptions.
rdar://9674298
llvm-svn: 251041
2015-10-22 18:38:17 +00:00
|
|
|
M->getType(),
|
2013-06-12 20:42:33 +00:00
|
|
|
*Destroy, CleanupKind & EHCleanup);
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case SD_Dynamic:
|
|
|
|
|
llvm_unreachable("temporary cannot have dynamic storage duration");
|
|
|
|
|
}
|
|
|
|
|
llvm_unreachable("unknown storage duration");
|
2013-06-11 02:41:00 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-21 05:09:00 +00:00
|
|
|
CXXDestructorDecl *ReferenceTemporaryDtor = nullptr;
|
2013-06-12 20:42:33 +00:00
|
|
|
if (const RecordType *RT =
|
|
|
|
|
E->getType()->getBaseElementTypeUnsafe()->getAs<RecordType>()) {
|
|
|
|
|
// Get the destructor for the reference temporary.
|
2014-05-09 00:08:36 +00:00
|
|
|
auto *ClassDecl = cast<CXXRecordDecl>(RT->getDecl());
|
2013-06-12 20:42:33 +00:00
|
|
|
if (!ClassDecl->hasTrivialDestructor())
|
|
|
|
|
ReferenceTemporaryDtor = ClassDecl->getDestructor();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ReferenceTemporaryDtor)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// Call the destructor for the temporary.
|
|
|
|
|
switch (M->getStorageDuration()) {
|
|
|
|
|
case SD_Static:
|
|
|
|
|
case SD_Thread: {
|
2019-02-07 01:14:17 +00:00
|
|
|
llvm::FunctionCallee CleanupFn;
|
2013-06-12 20:42:33 +00:00
|
|
|
llvm::Constant *CleanupArg;
|
|
|
|
|
if (E->getType()->isArrayType()) {
|
|
|
|
|
CleanupFn = CodeGenFunction(CGF.CGM).generateDestroyHelper(
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
ReferenceTemporary, E->getType(),
|
2013-08-27 23:57:18 +00:00
|
|
|
CodeGenFunction::destroyCXXObject, CGF.getLangOpts().Exceptions,
|
|
|
|
|
dyn_cast_or_null<VarDecl>(M->getExtendingDecl()));
|
2013-06-12 20:42:33 +00:00
|
|
|
CleanupArg = llvm::Constant::getNullValue(CGF.Int8PtrTy);
|
|
|
|
|
} else {
|
2019-03-22 23:05:10 +00:00
|
|
|
CleanupFn = CGF.CGM.getAddrAndTypeOfCXXStructor(
|
|
|
|
|
GlobalDecl(ReferenceTemporaryDtor, Dtor_Complete));
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
CleanupArg = cast<llvm::Constant>(ReferenceTemporary.getPointer());
|
2013-06-12 20:42:33 +00:00
|
|
|
}
|
|
|
|
|
CGF.CGM.getCXXABI().registerGlobalDtor(
|
|
|
|
|
CGF, *cast<VarDecl>(M->getExtendingDecl()), CleanupFn, CleanupArg);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case SD_FullExpression:
|
|
|
|
|
CGF.pushDestroy(NormalAndEHCleanup, ReferenceTemporary, E->getType(),
|
|
|
|
|
CodeGenFunction::destroyCXXObject,
|
|
|
|
|
CGF.getLangOpts().Exceptions);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SD_Automatic:
|
|
|
|
|
CGF.pushLifetimeExtendedDestroy(NormalAndEHCleanup,
|
|
|
|
|
ReferenceTemporary, E->getType(),
|
|
|
|
|
CodeGenFunction::destroyCXXObject,
|
|
|
|
|
CGF.getLangOpts().Exceptions);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SD_Dynamic:
|
|
|
|
|
llvm_unreachable("temporary cannot have dynamic storage duration");
|
|
|
|
|
}
|
2013-06-11 02:41:00 +00:00
|
|
|
}
|
2011-11-27 16:50:07 +00:00
|
|
|
|
2017-07-08 13:24:52 +00:00
|
|
|
static Address createReferenceTemporary(CodeGenFunction &CGF,
|
|
|
|
|
const MaterializeTemporaryExpr *M,
|
2018-05-17 11:16:35 +00:00
|
|
|
const Expr *Inner,
|
|
|
|
|
Address *Alloca = nullptr) {
|
2017-07-08 13:24:52 +00:00
|
|
|
auto &TCG = CGF.getTargetHooks();
|
2013-06-12 20:42:33 +00:00
|
|
|
switch (M->getStorageDuration()) {
|
|
|
|
|
case SD_FullExpression:
|
2015-04-09 22:50:07 +00:00
|
|
|
case SD_Automatic: {
|
2015-03-07 13:37:13 +00:00
|
|
|
// If we have a constant temporary array or record try to promote it into a
|
|
|
|
|
// constant global under the same rules a normal constant would've been
|
|
|
|
|
// promoted. This is easier on the optimizer and generally emits fewer
|
|
|
|
|
// instructions.
|
2015-04-09 22:50:07 +00:00
|
|
|
QualType Ty = Inner->getType();
|
2015-03-07 13:37:13 +00:00
|
|
|
if (CGF.CGM.getCodeGenOpts().MergeAllConstants &&
|
2015-04-09 22:50:07 +00:00
|
|
|
(Ty->isArrayType() || Ty->isRecordType()) &&
|
|
|
|
|
CGF.CGM.isTypeConstant(Ty, true))
|
2017-08-15 21:42:52 +00:00
|
|
|
if (auto Init = ConstantEmitter(CGF).tryEmitAbstract(Inner, Ty)) {
|
2017-07-08 13:24:52 +00:00
|
|
|
if (auto AddrSpace = CGF.getTarget().getConstantAddressSpace()) {
|
|
|
|
|
auto AS = AddrSpace.getValue();
|
|
|
|
|
auto *GV = new llvm::GlobalVariable(
|
|
|
|
|
CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,
|
|
|
|
|
llvm::GlobalValue::PrivateLinkage, Init, ".ref.tmp", nullptr,
|
|
|
|
|
llvm::GlobalValue::NotThreadLocal,
|
|
|
|
|
CGF.getContext().getTargetAddressSpace(AS));
|
|
|
|
|
CharUnits alignment = CGF.getContext().getTypeAlignInChars(Ty);
|
2019-10-03 13:00:29 +00:00
|
|
|
GV->setAlignment(alignment.getAsAlign());
|
2017-07-08 13:24:52 +00:00
|
|
|
llvm::Constant *C = GV;
|
|
|
|
|
if (AS != LangAS::Default)
|
|
|
|
|
C = TCG.performAddrSpaceCast(
|
|
|
|
|
CGF.CGM, GV, AS, LangAS::Default,
|
|
|
|
|
GV->getValueType()->getPointerTo(
|
|
|
|
|
CGF.getContext().getTargetAddressSpace(LangAS::Default)));
|
|
|
|
|
// FIXME: Should we put the new global into a COMDAT?
|
|
|
|
|
return Address(C, alignment);
|
|
|
|
|
}
|
2015-03-07 13:37:13 +00:00
|
|
|
}
|
2018-05-17 11:16:35 +00:00
|
|
|
return CGF.CreateMemTemp(Ty, "ref.tmp", Alloca);
|
2015-04-09 22:50:07 +00:00
|
|
|
}
|
2013-06-12 20:42:33 +00:00
|
|
|
case SD_Thread:
|
|
|
|
|
case SD_Static:
|
2015-03-17 16:38:58 +00:00
|
|
|
return CGF.CGM.GetAddrOfGlobalTemporary(M, Inner);
|
2013-06-12 20:42:33 +00:00
|
|
|
|
|
|
|
|
case SD_Dynamic:
|
|
|
|
|
llvm_unreachable("temporary can't have dynamic storage duration");
|
|
|
|
|
}
|
|
|
|
|
llvm_unreachable("unknown storage duration");
|
|
|
|
|
}
|
2013-06-11 19:14:25 +00:00
|
|
|
|
[ARM] Follow AACPS for preserving number of loads/stores of volatile bit-fields
Summary:
Following the AAPCS, every store to a volatile bit-field requires to generate one load of that field, even if all the bits are going to be replaced.
This patch allows the user to opt-in in following such rule, whenever the a.
AAPCS Release 2019Q1.1 (https://static.docs.arm.com/ihi0042/g/aapcs32.pdf)
section 8.1 Data Types, page 35, paragraph: Volatile bit-fields – preserving number and width of container accesses
```
When a volatile bit-field is written, and its container does not overlap with any non-bit-field member, its
container must be read exactly once and written exactly once using the access width appropriate to the
type of the container. The two accesses are not atomic.
```
Reviewers: lebedev.ri, ostannard, jfb, eli.friedman
Reviewed By: jfb
Subscribers: rsmith, rjmccall, dexonsmith, kristof.beyls, jfb, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D67399
2020-02-07 10:03:59 +00:00
|
|
|
/// Helper method to check if the underlying ABI is AAPCS
|
|
|
|
|
static bool isAAPCS(const TargetInfo &TargetInfo) {
|
|
|
|
|
return TargetInfo.getABI().startswith("aapcs");
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-24 19:54:32 +00:00
|
|
|
LValue CodeGenFunction::
|
|
|
|
|
EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) {
|
2019-11-17 11:41:55 +01:00
|
|
|
const Expr *E = M->getSubExpr();
|
2013-06-12 20:42:33 +00:00
|
|
|
|
[ObjCARC] Add an new attribute, objc_externally_retained
This attribute, called "objc_externally_retained", exposes clang's
notion of pseudo-__strong variables in ARC. Pseudo-strong variables
"borrow" their initializer, meaning that they don't retain/release
it, instead assuming that someone else is keeping their value alive.
If a function is annotated with this attribute, implicitly strong
parameters of that function aren't implicitly retained/released in
the function body, and are implicitly const. This is useful to expose
for performance reasons, most functions don't need the extra safety
of the retain/release, so programmers can opt out as needed.
This attribute can also apply to declarations of local variables,
with similar effect.
Differential revision: https://reviews.llvm.org/D55865
llvm-svn: 350422
2019-01-04 18:33:06 +00:00
|
|
|
assert((!M->getExtendingDecl() || !isa<VarDecl>(M->getExtendingDecl()) ||
|
|
|
|
|
!cast<VarDecl>(M->getExtendingDecl())->isARCPseudoStrong()) &&
|
|
|
|
|
"Reference should never be pseudo-strong!");
|
|
|
|
|
|
|
|
|
|
// FIXME: ideally this would use EmitAnyExprToMem, however, we cannot do so
|
|
|
|
|
// as that will cause the lifetime adjustment to be lost for ARC
|
Define weak and __weak to mean ARC-style weak references, even in MRC.
Previously, __weak was silently accepted and ignored in MRC mode.
That makes this a potentially source-breaking change that we have to
roll out cautiously. Accordingly, for the time being, actual support
for __weak references in MRC is experimental, and the compiler will
reject attempts to actually form such references. The intent is to
eventually enable the feature by default in all non-GC modes.
(It is, of course, incompatible with ObjC GC's interpretation of
__weak.)
If you like, you can enable this feature with
-Xclang -fobjc-weak
but like any -Xclang option, this option may be removed at any point,
e.g. if/when it is eventually enabled by default.
This patch also enables the use of the ARC __unsafe_unretained qualifier
in MRC. Unlike __weak, this is being enabled immediately. Since
variables are essentially __unsafe_unretained by default in MRC,
the only practical uses are (1) communication and (2) changing the
default behavior of by-value block capture.
As an implementation matter, this means that the ObjC ownership
qualifiers may appear in any ObjC language mode, and so this patch
removes a number of checks for getLangOpts().ObjCAutoRefCount
that were guarding the processing of these qualifiers. I don't
expect this to be a significant drain on performance; it may even
be faster to just check for these qualifiers directly on a type
(since it's probably in a register anyway) than to do N dependent
loads to grab the LangOptions.
rdar://9674298
llvm-svn: 251041
2015-10-22 18:38:17 +00:00
|
|
|
auto ownership = M->getType().getObjCLifetime();
|
|
|
|
|
if (ownership != Qualifiers::OCL_None &&
|
|
|
|
|
ownership != Qualifiers::OCL_ExplicitNone) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Address Object = createReferenceTemporary(*this, M, E);
|
|
|
|
|
if (auto *Var = dyn_cast<llvm::GlobalVariable>(Object.getPointer())) {
|
|
|
|
|
Object = Address(llvm::ConstantExpr::getBitCast(Var,
|
|
|
|
|
ConvertTypeForMem(E->getType())
|
|
|
|
|
->getPointerTo(Object.getAddressSpace())),
|
|
|
|
|
Object.getAlignment());
|
2016-05-13 01:21:23 +00:00
|
|
|
|
|
|
|
|
// createReferenceTemporary will promote the temporary to a global with a
|
|
|
|
|
// constant initializer if it can. It can only do this to a value of
|
|
|
|
|
// ARC-manageable type if the value is global and therefore "immune" to
|
|
|
|
|
// ref-counting operations. Therefore we have no need to emit either a
|
|
|
|
|
// dynamic initialization or a cleanup and we can just return the address
|
|
|
|
|
// of the temporary.
|
|
|
|
|
if (Var->hasInitializer())
|
2017-10-10 09:39:32 +00:00
|
|
|
return MakeAddrLValue(Object, M->getType(), AlignmentSource::Decl);
|
2016-05-13 01:21:23 +00:00
|
|
|
|
2013-06-14 03:07:01 +00:00
|
|
|
Var->setInitializer(CGM.EmitNullConstant(E->getType()));
|
|
|
|
|
}
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
LValue RefTempDst = MakeAddrLValue(Object, M->getType(),
|
2017-10-10 09:39:32 +00:00
|
|
|
AlignmentSource::Decl);
|
2013-06-14 03:07:01 +00:00
|
|
|
|
2014-10-24 20:23:43 +00:00
|
|
|
switch (getEvaluationKind(E->getType())) {
|
|
|
|
|
default: llvm_unreachable("expected scalar or aggregate expression");
|
|
|
|
|
case TEK_Scalar:
|
|
|
|
|
EmitScalarInit(E, M->getExtendingDecl(), RefTempDst, false);
|
|
|
|
|
break;
|
|
|
|
|
case TEK_Aggregate: {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
EmitAggExpr(E, AggValueSlot::forAddr(Object,
|
2014-10-24 20:23:43 +00:00
|
|
|
E->getType().getQualifiers(),
|
|
|
|
|
AggValueSlot::IsDestructed,
|
|
|
|
|
AggValueSlot::DoesNotNeedGCBarriers,
|
2018-04-05 20:52:58 +00:00
|
|
|
AggValueSlot::IsNotAliased,
|
|
|
|
|
AggValueSlot::DoesNotOverlap));
|
2014-10-24 20:23:43 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-06-12 20:42:33 +00:00
|
|
|
|
2014-10-10 04:05:00 +00:00
|
|
|
pushTemporaryCleanup(*this, M, E, Object);
|
2013-06-12 23:38:09 +00:00
|
|
|
return RefTempDst;
|
2013-04-11 00:58:58 +00:00
|
|
|
}
|
|
|
|
|
|
2013-06-03 00:17:11 +00:00
|
|
|
SmallVector<const Expr *, 2> CommaLHSs;
|
2013-04-11 00:58:58 +00:00
|
|
|
SmallVector<SubobjectAdjustment, 2> Adjustments;
|
2013-06-03 00:17:11 +00:00
|
|
|
E = E->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
|
|
|
|
|
|
2014-10-24 19:54:32 +00:00
|
|
|
for (const auto &Ignored : CommaLHSs)
|
|
|
|
|
EmitIgnoredExpr(Ignored);
|
2013-06-03 00:17:11 +00:00
|
|
|
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *opaque = dyn_cast<OpaqueValueExpr>(E)) {
|
2013-06-12 20:42:33 +00:00
|
|
|
if (opaque->getType()->isRecordType()) {
|
|
|
|
|
assert(Adjustments.empty());
|
2013-06-12 23:38:09 +00:00
|
|
|
return EmitOpaqueValueLValue(opaque);
|
2013-04-11 00:58:58 +00:00
|
|
|
}
|
|
|
|
|
}
|
2010-06-27 16:56:04 +00:00
|
|
|
|
2014-10-10 04:05:00 +00:00
|
|
|
// Create and initialize the reference temporary.
|
2018-05-17 11:16:35 +00:00
|
|
|
Address Alloca = Address::invalid();
|
|
|
|
|
Address Object = createReferenceTemporary(*this, M, E, &Alloca);
|
2017-07-08 13:24:52 +00:00
|
|
|
if (auto *Var = dyn_cast<llvm::GlobalVariable>(
|
|
|
|
|
Object.getPointer()->stripPointerCasts())) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Object = Address(llvm::ConstantExpr::getBitCast(
|
2017-07-08 13:24:52 +00:00
|
|
|
cast<llvm::Constant>(Object.getPointer()),
|
|
|
|
|
ConvertTypeForMem(E->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 08:05:57 +00:00
|
|
|
Object.getAlignment());
|
2015-03-07 13:37:13 +00:00
|
|
|
// If the temporary is a global and has a constant initializer or is a
|
|
|
|
|
// constant temporary that we promoted to a global, we may have already
|
|
|
|
|
// initialized it.
|
2013-06-14 03:07:01 +00:00
|
|
|
if (!Var->hasInitializer()) {
|
|
|
|
|
Var->setInitializer(CGM.EmitNullConstant(E->getType()));
|
|
|
|
|
EmitAnyExprToMem(E, Object, Qualifiers(), /*IsInit*/true);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2016-07-01 21:08:47 +00:00
|
|
|
switch (M->getStorageDuration()) {
|
|
|
|
|
case SD_Automatic:
|
|
|
|
|
if (auto *Size = EmitLifetimeStart(
|
2018-05-17 11:16:35 +00:00
|
|
|
CGM.getDataLayout().getTypeAllocSize(Alloca.getElementType()),
|
|
|
|
|
Alloca.getPointer())) {
|
2018-08-04 01:25:06 +00:00
|
|
|
pushCleanupAfterFullExpr<CallLifetimeEnd>(NormalEHLifetimeMarker,
|
|
|
|
|
Alloca, Size);
|
2016-07-01 21:08:47 +00:00
|
|
|
}
|
|
|
|
|
break;
|
2018-08-04 01:25:06 +00:00
|
|
|
|
|
|
|
|
case SD_FullExpression: {
|
|
|
|
|
if (!ShouldEmitLifetimeMarkers)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// Avoid creating a conditional cleanup just to hold an llvm.lifetime.end
|
|
|
|
|
// marker. Instead, start the lifetime of a conditional temporary earlier
|
2019-08-26 22:15:50 +00:00
|
|
|
// so that it's unconditional. Don't do this with sanitizers which need
|
|
|
|
|
// more precise lifetime marks.
|
2018-08-04 01:25:06 +00:00
|
|
|
ConditionalEvaluation *OldConditional = nullptr;
|
|
|
|
|
CGBuilderTy::InsertPoint OldIP;
|
|
|
|
|
if (isInConditionalBranch() && !E->getType().isDestructedType() &&
|
2019-08-26 22:16:05 +00:00
|
|
|
!SanOpts.has(SanitizerKind::HWAddress) &&
|
2019-08-26 22:15:50 +00:00
|
|
|
!SanOpts.has(SanitizerKind::Memory) &&
|
2018-08-04 01:25:06 +00:00
|
|
|
!CGM.getCodeGenOpts().SanitizeAddressUseAfterScope) {
|
|
|
|
|
OldConditional = OutermostConditional;
|
|
|
|
|
OutermostConditional = nullptr;
|
|
|
|
|
|
|
|
|
|
OldIP = Builder.saveIP();
|
|
|
|
|
llvm::BasicBlock *Block = OldConditional->getStartingBlock();
|
|
|
|
|
Builder.restoreIP(CGBuilderTy::InsertPoint(
|
|
|
|
|
Block, llvm::BasicBlock::iterator(Block->back())));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (auto *Size = EmitLifetimeStart(
|
|
|
|
|
CGM.getDataLayout().getTypeAllocSize(Alloca.getElementType()),
|
|
|
|
|
Alloca.getPointer())) {
|
|
|
|
|
pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, Alloca,
|
|
|
|
|
Size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (OldConditional) {
|
|
|
|
|
OutermostConditional = OldConditional;
|
|
|
|
|
Builder.restoreIP(OldIP);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-01 21:08:47 +00:00
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2013-06-14 03:07:01 +00:00
|
|
|
EmitAnyExprToMem(E, Object, Qualifiers(), /*IsInit*/true);
|
|
|
|
|
}
|
2014-10-10 04:05:00 +00:00
|
|
|
pushTemporaryCleanup(*this, M, E, Object);
|
2013-06-12 20:42:33 +00:00
|
|
|
|
|
|
|
|
// Perform derived-to-base casts and/or field accesses, to get from the
|
|
|
|
|
// temporary object we created (and, potentially, for which we extended
|
|
|
|
|
// the lifetime) to the subobject we're binding the reference to.
|
|
|
|
|
for (unsigned I = Adjustments.size(); I != 0; --I) {
|
|
|
|
|
SubobjectAdjustment &Adjustment = Adjustments[I-1];
|
|
|
|
|
switch (Adjustment.Kind) {
|
|
|
|
|
case SubobjectAdjustment::DerivedToBaseAdjustment:
|
|
|
|
|
Object =
|
2013-06-12 23:38:09 +00:00
|
|
|
GetAddressOfBaseClass(Object, Adjustment.DerivedToBase.DerivedClass,
|
|
|
|
|
Adjustment.DerivedToBase.BasePath->path_begin(),
|
|
|
|
|
Adjustment.DerivedToBase.BasePath->path_end(),
|
2014-10-13 23:59:00 +00:00
|
|
|
/*NullCheckValue=*/ false, E->getExprLoc());
|
2013-06-12 20:42:33 +00:00
|
|
|
break;
|
2011-03-16 22:34:09 +00:00
|
|
|
|
2013-06-12 20:42:33 +00:00
|
|
|
case SubobjectAdjustment::FieldAdjustment: {
|
2017-10-10 09:39:32 +00:00
|
|
|
LValue LV = MakeAddrLValue(Object, E->getType(), AlignmentSource::Decl);
|
2013-06-12 23:38:09 +00:00
|
|
|
LV = EmitLValueForField(LV, Adjustment.Field);
|
2013-06-12 20:42:33 +00:00
|
|
|
assert(LV.isSimple() &&
|
|
|
|
|
"materialized temporary field is not a simple lvalue");
|
2019-12-03 15:17:01 -08:00
|
|
|
Object = LV.getAddress(*this);
|
2013-06-12 20:42:33 +00:00
|
|
|
break;
|
2009-10-15 00:51:46 +00:00
|
|
|
}
|
2013-04-11 00:58:58 +00:00
|
|
|
|
2013-06-12 20:42:33 +00:00
|
|
|
case SubobjectAdjustment::MemberPointerAdjustment: {
|
2013-06-12 23:38:09 +00:00
|
|
|
llvm::Value *Ptr = EmitScalarExpr(Adjustment.Ptr.RHS);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Object = EmitCXXMemberDataPointerAddress(E, Object, Ptr,
|
|
|
|
|
Adjustment.Ptr.MPT);
|
2013-06-12 20:42:33 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-05-20 00:36:58 +00:00
|
|
|
}
|
2009-05-20 02:31:19 +00:00
|
|
|
|
2017-10-10 09:39:32 +00:00
|
|
|
return MakeAddrLValue(Object, M->getType(), AlignmentSource::Decl);
|
2010-06-27 16:56:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RValue
|
2013-06-12 23:38:09 +00:00
|
|
|
CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E) {
|
|
|
|
|
// Emit the expression as an lvalue.
|
|
|
|
|
LValue LV = EmitLValue(E);
|
|
|
|
|
assert(LV.isSimple());
|
2019-12-03 15:17:01 -08:00
|
|
|
llvm::Value *Value = LV.getPointer(*this);
|
2013-06-12 20:42:33 +00:00
|
|
|
|
2014-07-07 23:59:57 +00:00
|
|
|
if (sanitizePerformTypeCheck() && !E->getType()->isFunctionType()) {
|
2012-08-24 00:54:33 +00:00
|
|
|
// C++11 [dcl.ref]p5 (as amended by core issue 453):
|
|
|
|
|
// If a glvalue to which a reference is directly bound designates neither
|
|
|
|
|
// an existing object or function of an appropriate type nor a region of
|
|
|
|
|
// storage of suitable size and alignment to contain an object of the
|
|
|
|
|
// reference's type, the behavior is undefined.
|
|
|
|
|
QualType Ty = E->getType();
|
2012-10-09 19:52:38 +00:00
|
|
|
EmitTypeCheck(TCK_ReferenceBinding, E->getExprLoc(), Value, Ty);
|
2012-08-24 00:54:33 +00:00
|
|
|
}
|
2010-07-21 06:29:51 +00:00
|
|
|
|
2010-06-27 16:56:04 +00:00
|
|
|
return RValue::get(Value);
|
2009-05-20 00:24:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-09-09 13:00:44 +00:00
|
|
|
/// getAccessedFieldNo - Given an encoded value and a result number, return the
|
|
|
|
|
/// input field number being accessed.
|
|
|
|
|
unsigned CodeGenFunction::getAccessedFieldNo(unsigned Idx,
|
2008-05-22 00:50:06 +00:00
|
|
|
const llvm::Constant *Elts) {
|
2012-01-30 06:20:36 +00:00
|
|
|
return cast<llvm::ConstantInt>(Elts->getAggregateElement(Idx))
|
|
|
|
|
->getZExtValue();
|
2008-05-22 00:50:06 +00:00
|
|
|
}
|
|
|
|
|
|
2012-10-25 02:14:12 +00:00
|
|
|
/// Emit the hash_16_bytes function from include/llvm/ADT/Hashing.h.
|
|
|
|
|
static llvm::Value *emitHash16Bytes(CGBuilderTy &Builder, llvm::Value *Low,
|
|
|
|
|
llvm::Value *High) {
|
|
|
|
|
llvm::Value *KMul = Builder.getInt64(0x9ddfea08eb382d69ULL);
|
|
|
|
|
llvm::Value *K47 = Builder.getInt64(47);
|
|
|
|
|
llvm::Value *A0 = Builder.CreateMul(Builder.CreateXor(Low, High), KMul);
|
|
|
|
|
llvm::Value *A1 = Builder.CreateXor(Builder.CreateLShr(A0, K47), A0);
|
|
|
|
|
llvm::Value *B0 = Builder.CreateMul(Builder.CreateXor(High, A1), KMul);
|
|
|
|
|
llvm::Value *B1 = Builder.CreateXor(Builder.CreateLShr(B0, K47), B0);
|
|
|
|
|
return Builder.CreateMul(B1, KMul);
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-03 01:27:25 +00:00
|
|
|
bool CodeGenFunction::isNullPointerAllowed(TypeCheckKind TCK) {
|
|
|
|
|
return TCK == TCK_DowncastPointer || TCK == TCK_Upcast ||
|
2017-12-28 12:45:41 +00:00
|
|
|
TCK == TCK_UpcastToVirtualBase || TCK == TCK_DynamicOperation;
|
2017-10-03 01:27:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CodeGenFunction::isVptrCheckRequired(TypeCheckKind TCK, QualType Ty) {
|
|
|
|
|
CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
|
|
|
|
|
return (RD && RD->hasDefinition() && RD->isDynamicClass()) &&
|
|
|
|
|
(TCK == TCK_MemberAccess || TCK == TCK_MemberCall ||
|
|
|
|
|
TCK == TCK_DowncastPointer || TCK == TCK_DowncastReference ||
|
2017-12-28 12:45:41 +00:00
|
|
|
TCK == TCK_UpcastToVirtualBase || TCK == TCK_DynamicOperation);
|
2017-10-03 01:27:25 +00:00
|
|
|
}
|
|
|
|
|
|
2014-07-07 23:59:57 +00:00
|
|
|
bool CodeGenFunction::sanitizePerformTypeCheck() const {
|
2014-11-07 22:29:38 +00:00
|
|
|
return SanOpts.has(SanitizerKind::Null) |
|
|
|
|
|
SanOpts.has(SanitizerKind::Alignment) |
|
|
|
|
|
SanOpts.has(SanitizerKind::ObjectSize) |
|
|
|
|
|
SanOpts.has(SanitizerKind::Vptr);
|
2014-07-07 23:59:57 +00:00
|
|
|
}
|
|
|
|
|
|
2012-10-09 19:52:38 +00:00
|
|
|
void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
llvm::Value *Ptr, QualType Ty,
|
2017-02-17 23:22:55 +00:00
|
|
|
CharUnits Alignment,
|
2019-01-23 03:37:29 +00:00
|
|
|
SanitizerSet SkippedChecks,
|
|
|
|
|
llvm::Value *ArraySize) {
|
2014-07-07 23:59:57 +00:00
|
|
|
if (!sanitizePerformTypeCheck())
|
2009-12-16 02:57:00 +00:00
|
|
|
return;
|
|
|
|
|
|
2012-11-01 07:22:08 +00:00
|
|
|
// Don't check pointers outside the default address space. The null check
|
|
|
|
|
// isn't correct, the object-size check isn't supported by LLVM, and we can't
|
|
|
|
|
// communicate the addresses to the runtime handler for the vptr check.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
if (Ptr->getType()->getPointerAddressSpace())
|
2012-11-01 07:22:08 +00:00
|
|
|
return;
|
|
|
|
|
|
2017-06-16 03:27:36 +00:00
|
|
|
// Don't check pointers to volatile data. The behavior here is implementation-
|
|
|
|
|
// defined.
|
|
|
|
|
if (Ty.isVolatileQualified())
|
|
|
|
|
return;
|
|
|
|
|
|
2014-07-17 18:46:27 +00:00
|
|
|
SanitizerScope SanScope(this);
|
|
|
|
|
|
2015-05-11 21:39:14 +00:00
|
|
|
SmallVector<std::pair<llvm::Value *, SanitizerMask>, 3> Checks;
|
2014-05-21 05:09:00 +00:00
|
|
|
llvm::BasicBlock *Done = nullptr;
|
2012-08-24 00:54:33 +00:00
|
|
|
|
2017-04-26 02:17:21 +00:00
|
|
|
// Quickly determine whether we have a pointer to an alloca. It's possible
|
|
|
|
|
// to skip null checks, and some alignment checks, for these pointers. This
|
|
|
|
|
// can reduce compile-time significantly.
|
2019-08-22 19:56:14 +00:00
|
|
|
auto PtrToAlloca = dyn_cast<llvm::AllocaInst>(Ptr->stripPointerCasts());
|
2017-04-26 02:17:21 +00:00
|
|
|
|
2017-10-03 01:27:26 +00:00
|
|
|
llvm::Value *True = llvm::ConstantInt::getTrue(getLLVMContext());
|
2017-07-25 19:34:23 +00:00
|
|
|
llvm::Value *IsNonNull = nullptr;
|
|
|
|
|
bool IsGuaranteedNonNull =
|
|
|
|
|
SkippedChecks.has(SanitizerKind::Null) || PtrToAlloca;
|
2017-10-03 01:27:25 +00:00
|
|
|
bool AllowNullPointers = isNullPointerAllowed(TCK);
|
2014-11-07 22:29:38 +00:00
|
|
|
if ((SanOpts.has(SanitizerKind::Null) || AllowNullPointers) &&
|
2017-07-25 19:34:23 +00:00
|
|
|
!IsGuaranteedNonNull) {
|
2012-11-05 22:21:05 +00:00
|
|
|
// The glvalue must not be an empty glvalue.
|
2017-07-25 19:34:23 +00:00
|
|
|
IsNonNull = Builder.CreateIsNotNull(Ptr);
|
2013-02-13 21:18:23 +00:00
|
|
|
|
2017-04-17 22:26:10 +00:00
|
|
|
// The IR builder can constant-fold the null check if the pointer points to
|
|
|
|
|
// a constant.
|
2017-10-03 01:27:26 +00:00
|
|
|
IsGuaranteedNonNull = IsNonNull == True;
|
2017-04-17 22:26:10 +00:00
|
|
|
|
|
|
|
|
// Skip the null check if the pointer is known to be non-null.
|
2017-07-25 19:34:23 +00:00
|
|
|
if (!IsGuaranteedNonNull) {
|
2017-04-17 22:26:10 +00:00
|
|
|
if (AllowNullPointers) {
|
|
|
|
|
// When performing pointer casts, it's OK if the value is null.
|
|
|
|
|
// Skip the remaining checks in that case.
|
|
|
|
|
Done = createBasicBlock("null");
|
|
|
|
|
llvm::BasicBlock *Rest = createBasicBlock("not.null");
|
|
|
|
|
Builder.CreateCondBr(IsNonNull, Rest, Done);
|
|
|
|
|
EmitBlock(Rest);
|
|
|
|
|
} else {
|
|
|
|
|
Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::Null));
|
|
|
|
|
}
|
2013-02-13 21:18:23 +00:00
|
|
|
}
|
2012-11-05 22:21:05 +00:00
|
|
|
}
|
2012-10-09 19:52:38 +00:00
|
|
|
|
2017-02-17 23:22:55 +00:00
|
|
|
if (SanOpts.has(SanitizerKind::ObjectSize) &&
|
|
|
|
|
!SkippedChecks.has(SanitizerKind::ObjectSize) &&
|
|
|
|
|
!Ty->isIncompleteType()) {
|
2020-01-31 19:06:21 -08:00
|
|
|
uint64_t TySize = CGM.getMinimumObjectSize(Ty).getQuantity();
|
2019-01-23 03:37:29 +00:00
|
|
|
llvm::Value *Size = llvm::ConstantInt::get(IntPtrTy, TySize);
|
|
|
|
|
if (ArraySize)
|
|
|
|
|
Size = Builder.CreateMul(Size, ArraySize);
|
|
|
|
|
|
|
|
|
|
// Degenerate case: new X[0] does not need an objectsize check.
|
|
|
|
|
llvm::Constant *ConstantSize = dyn_cast<llvm::Constant>(Size);
|
|
|
|
|
if (!ConstantSize || !ConstantSize->isNullValue()) {
|
|
|
|
|
// The glvalue must refer to a large enough storage region.
|
|
|
|
|
// FIXME: If Address Sanitizer is enabled, insert dynamic instrumentation
|
|
|
|
|
// to check this.
|
|
|
|
|
// FIXME: Get object address space
|
|
|
|
|
llvm::Type *Tys[2] = { IntPtrTy, Int8PtrTy };
|
2019-02-03 21:53:49 +00:00
|
|
|
llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, Tys);
|
2019-01-23 03:37:29 +00:00
|
|
|
llvm::Value *Min = Builder.getFalse();
|
|
|
|
|
llvm::Value *NullIsUnknown = Builder.getFalse();
|
2019-01-30 20:34:35 +00:00
|
|
|
llvm::Value *Dynamic = Builder.getFalse();
|
2019-01-23 03:37:29 +00:00
|
|
|
llvm::Value *CastAddr = Builder.CreateBitCast(Ptr, Int8PtrTy);
|
|
|
|
|
llvm::Value *LargeEnough = Builder.CreateICmpUGE(
|
2019-01-30 20:34:35 +00:00
|
|
|
Builder.CreateCall(F, {CastAddr, Min, NullIsUnknown, Dynamic}), Size);
|
2019-01-23 03:37:29 +00:00
|
|
|
Checks.push_back(std::make_pair(LargeEnough, SanitizerKind::ObjectSize));
|
|
|
|
|
}
|
2012-10-09 19:52:38 +00:00
|
|
|
}
|
2012-08-24 00:54:33 +00:00
|
|
|
|
2012-11-05 22:21:05 +00:00
|
|
|
uint64_t AlignVal = 0;
|
2017-10-03 01:27:24 +00:00
|
|
|
llvm::Value *PtrAsInt = nullptr;
|
2012-11-05 22:21:05 +00:00
|
|
|
|
2017-02-17 23:22:55 +00:00
|
|
|
if (SanOpts.has(SanitizerKind::Alignment) &&
|
|
|
|
|
!SkippedChecks.has(SanitizerKind::Alignment)) {
|
2012-11-05 22:21:05 +00:00
|
|
|
AlignVal = Alignment.getQuantity();
|
|
|
|
|
if (!Ty->isIncompleteType() && !AlignVal)
|
2020-05-18 11:29:11 -07:00
|
|
|
AlignVal = CGM.getNaturalTypeAlignment(Ty, nullptr, nullptr,
|
|
|
|
|
/*ForPointeeType=*/true)
|
|
|
|
|
.getQuantity();
|
2012-11-05 22:21:05 +00:00
|
|
|
|
2012-08-24 00:54:33 +00:00
|
|
|
// The glvalue must be suitably aligned.
|
2017-04-26 02:17:21 +00:00
|
|
|
if (AlignVal > 1 &&
|
|
|
|
|
(!PtrToAlloca || PtrToAlloca->getAlignment() < AlignVal)) {
|
2017-10-03 01:27:24 +00:00
|
|
|
PtrAsInt = Builder.CreatePtrToInt(Ptr, IntPtrTy);
|
|
|
|
|
llvm::Value *Align = Builder.CreateAnd(
|
|
|
|
|
PtrAsInt, llvm::ConstantInt::get(IntPtrTy, AlignVal - 1));
|
2012-11-05 22:21:05 +00:00
|
|
|
llvm::Value *Aligned =
|
2017-10-03 01:27:24 +00:00
|
|
|
Builder.CreateICmpEQ(Align, llvm::ConstantInt::get(IntPtrTy, 0));
|
2017-10-03 01:27:26 +00:00
|
|
|
if (Aligned != True)
|
|
|
|
|
Checks.push_back(std::make_pair(Aligned, SanitizerKind::Alignment));
|
2012-11-05 22:21:05 +00:00
|
|
|
}
|
2012-08-24 00:54:33 +00:00
|
|
|
}
|
2010-04-10 18:34:14 +00:00
|
|
|
|
2014-11-11 22:03:54 +00:00
|
|
|
if (Checks.size() > 0) {
|
2017-01-06 14:40:12 +00:00
|
|
|
// Make sure we're not losing information. Alignment needs to be a power of
|
|
|
|
|
// 2
|
|
|
|
|
assert(!AlignVal || (uint64_t)1 << llvm::Log2_64(AlignVal) == AlignVal);
|
2012-10-09 19:52:38 +00:00
|
|
|
llvm::Constant *StaticData[] = {
|
2017-01-06 14:40:12 +00:00
|
|
|
EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(Ty),
|
|
|
|
|
llvm::ConstantInt::get(Int8Ty, AlignVal ? llvm::Log2_64(AlignVal) : 1),
|
|
|
|
|
llvm::ConstantInt::get(Int8Ty, TCK)};
|
2017-10-03 01:27:24 +00:00
|
|
|
EmitCheck(Checks, SanitizerHandler::TypeMismatch, StaticData,
|
|
|
|
|
PtrAsInt ? PtrAsInt : Ptr);
|
2012-10-09 19:52:38 +00:00
|
|
|
}
|
2012-10-25 02:14:12 +00:00
|
|
|
|
2012-11-05 22:21:05 +00:00
|
|
|
// If possible, check that the vptr indicates that there is a subobject of
|
|
|
|
|
// type Ty at offset zero within this object.
|
2012-12-18 00:22:45 +00:00
|
|
|
//
|
|
|
|
|
// C++11 [basic.life]p5,6:
|
|
|
|
|
// [For storage which does not refer to an object within its lifetime]
|
|
|
|
|
// The program has undefined behavior if:
|
|
|
|
|
// -- the [pointer or glvalue] is used to access a non-static data member
|
2012-12-18 03:04:38 +00:00
|
|
|
// or call a non-static member function
|
2014-11-07 22:29:38 +00:00
|
|
|
if (SanOpts.has(SanitizerKind::Vptr) &&
|
2017-10-03 01:27:25 +00:00
|
|
|
!SkippedChecks.has(SanitizerKind::Vptr) && isVptrCheckRequired(TCK, Ty)) {
|
2017-07-25 19:34:23 +00:00
|
|
|
// Ensure that the pointer is non-null before loading it. If there is no
|
2017-08-02 18:10:31 +00:00
|
|
|
// compile-time guarantee, reuse the run-time null check or emit a new one.
|
2017-07-25 19:34:23 +00:00
|
|
|
if (!IsGuaranteedNonNull) {
|
2017-08-02 18:10:31 +00:00
|
|
|
if (!IsNonNull)
|
|
|
|
|
IsNonNull = Builder.CreateIsNotNull(Ptr);
|
2017-07-25 19:34:23 +00:00
|
|
|
if (!Done)
|
|
|
|
|
Done = createBasicBlock("vptr.null");
|
|
|
|
|
llvm::BasicBlock *VptrNotNull = createBasicBlock("vptr.not.null");
|
|
|
|
|
Builder.CreateCondBr(IsNonNull, VptrNotNull, Done);
|
|
|
|
|
EmitBlock(VptrNotNull);
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-25 02:14:12 +00:00
|
|
|
// Compute a hash of the mangled name of the type.
|
|
|
|
|
//
|
|
|
|
|
// FIXME: This is not guaranteed to be deterministic! Move to a
|
|
|
|
|
// fingerprinting mechanism once LLVM provides one. For the time
|
|
|
|
|
// being the implementation happens to be deterministic.
|
2013-01-12 19:30:44 +00:00
|
|
|
SmallString<64> MangledName;
|
2012-10-25 02:14:12 +00:00
|
|
|
llvm::raw_svector_ostream Out(MangledName);
|
|
|
|
|
CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty.getUnqualifiedType(),
|
|
|
|
|
Out);
|
2014-07-10 22:34:19 +00:00
|
|
|
|
|
|
|
|
// Blacklist based on the mangled type.
|
SanitizerBlacklist: blacklist functions by their source location.
This commit changes the way we blacklist functions in ASan, TSan,
MSan and UBSan. We used to treat function as "blacklisted"
and turned off instrumentation in it in two cases:
1) Function is explicitly blacklisted by its mangled name.
This part is not changed.
2) Function is located in llvm::Module, whose identifier is
contained in the list of blacklisted sources. This is completely
wrong, as llvm::Module may not correspond to the actual source
file function is defined in. Also, function can be defined in
a header, in which case user had to blacklist the .cpp file
this header was #include'd into, not the header itself.
Such functions could cause other problems - for instance, if the
header was included in multiple source files, compiled
separately and linked into a single executable, we could end up
with both instrumented and non-instrumented version of the same
function participating in the same link.
After this change we will make blacklisting decision based on
the SourceLocation of a function definition. If a function is
not explicitly defined in the source file, (for example, the
function is compiler-generated and responsible for
initialization/destruction of a global variable), then it will
be blacklisted if the corresponding global variable is defined
in blacklisted source file, and will be instrumented otherwise.
After this commit, the active users of blacklist files may have
to revisit them. This is a backwards-incompatible change, but
I don't think it's possible or makes sense to support the
old incorrect behavior.
I plan to make similar change for blacklisting GlobalVariables
(which is ASan-specific).
llvm-svn: 219997
2014-10-17 00:20:19 +00:00
|
|
|
if (!CGM.getContext().getSanitizerBlacklist().isBlacklistedType(
|
2017-09-25 22:11:12 +00:00
|
|
|
SanitizerKind::Vptr, Out.str())) {
|
2014-07-10 22:34:19 +00:00
|
|
|
llvm::hash_code TypeHash = hash_value(Out.str());
|
|
|
|
|
|
|
|
|
|
// Load the vptr, and compute hash_16_bytes(TypeHash, vptr).
|
|
|
|
|
llvm::Value *Low = llvm::ConstantInt::get(Int64Ty, TypeHash);
|
|
|
|
|
llvm::Type *VPtrTy = llvm::PointerType::get(IntPtrTy, 0);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Address VPtrAddr(Builder.CreateBitCast(Ptr, VPtrTy), getPointerAlign());
|
2014-07-10 22:34:19 +00:00
|
|
|
llvm::Value *VPtrVal = Builder.CreateLoad(VPtrAddr);
|
|
|
|
|
llvm::Value *High = Builder.CreateZExt(VPtrVal, Int64Ty);
|
|
|
|
|
|
|
|
|
|
llvm::Value *Hash = emitHash16Bytes(Builder, Low, High);
|
|
|
|
|
Hash = Builder.CreateTrunc(Hash, IntPtrTy);
|
|
|
|
|
|
|
|
|
|
// Look the hash up in our cache.
|
|
|
|
|
const int CacheSize = 128;
|
|
|
|
|
llvm::Type *HashTable = llvm::ArrayType::get(IntPtrTy, CacheSize);
|
|
|
|
|
llvm::Value *Cache = CGM.CreateRuntimeVariable(HashTable,
|
|
|
|
|
"__ubsan_vptr_type_cache");
|
|
|
|
|
llvm::Value *Slot = Builder.CreateAnd(Hash,
|
|
|
|
|
llvm::ConstantInt::get(IntPtrTy,
|
|
|
|
|
CacheSize-1));
|
|
|
|
|
llvm::Value *Indices[] = { Builder.getInt32(0), Slot };
|
|
|
|
|
llvm::Value *CacheVal =
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Builder.CreateAlignedLoad(Builder.CreateInBoundsGEP(Cache, Indices),
|
|
|
|
|
getPointerAlign());
|
2014-07-10 22:34:19 +00:00
|
|
|
|
|
|
|
|
// If the hash isn't in the cache, call a runtime handler to perform the
|
|
|
|
|
// hard work of checking whether the vptr is for an object of the right
|
|
|
|
|
// type. This will either fill in the cache and return, or produce a
|
|
|
|
|
// diagnostic.
|
2014-11-11 22:03:54 +00:00
|
|
|
llvm::Value *EqualHash = Builder.CreateICmpEQ(CacheVal, Hash);
|
2014-07-10 22:34:19 +00:00
|
|
|
llvm::Constant *StaticData[] = {
|
|
|
|
|
EmitCheckSourceLocation(Loc),
|
|
|
|
|
EmitCheckTypeDescriptor(Ty),
|
|
|
|
|
CGM.GetAddrOfRTTIDescriptor(Ty.getUnqualifiedType()),
|
|
|
|
|
llvm::ConstantInt::get(Int8Ty, TCK)
|
|
|
|
|
};
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
llvm::Value *DynamicData[] = { Ptr, Hash };
|
2014-11-11 22:03:54 +00:00
|
|
|
EmitCheck(std::make_pair(EqualHash, SanitizerKind::Vptr),
|
2016-12-12 16:18:40 +00:00
|
|
|
SanitizerHandler::DynamicTypeCacheMiss, StaticData,
|
|
|
|
|
DynamicData);
|
2014-07-10 22:34:19 +00:00
|
|
|
}
|
2012-10-25 02:14:12 +00:00
|
|
|
}
|
2013-02-13 21:18:23 +00:00
|
|
|
|
|
|
|
|
if (Done) {
|
|
|
|
|
Builder.CreateBr(Done);
|
|
|
|
|
EmitBlock(Done);
|
|
|
|
|
}
|
2009-12-16 02:57:00 +00:00
|
|
|
}
|
2007-08-31 22:49:20 +00:00
|
|
|
|
2013-02-23 02:53:19 +00:00
|
|
|
/// Determine whether this expression refers to a flexible array member in a
|
|
|
|
|
/// struct. We disable array bounds checks for such members.
|
|
|
|
|
static bool isFlexibleArrayMemberExpr(const Expr *E) {
|
|
|
|
|
// For compatibility with existing code, we treat arrays of length 0 or
|
|
|
|
|
// 1 as flexible array members.
|
2020-03-18 15:46:31 -07:00
|
|
|
// FIXME: This is inconsistent with the warning code in SemaChecking. Unify
|
|
|
|
|
// the two mechanisms.
|
2013-02-23 02:53:19 +00:00
|
|
|
const ArrayType *AT = E->getType()->castAsArrayTypeUnsafe();
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
|
2020-03-18 15:46:31 -07:00
|
|
|
// FIXME: Sema doesn't treat [1] as a flexible array member if the bound
|
|
|
|
|
// was produced by macro expansion.
|
2013-02-23 02:53:19 +00:00
|
|
|
if (CAT->getSize().ugt(1))
|
|
|
|
|
return false;
|
|
|
|
|
} else if (!isa<IncompleteArrayType>(AT))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
E = E->IgnoreParens();
|
|
|
|
|
|
|
|
|
|
// A flexible array member must be the last member in the class.
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *ME = dyn_cast<MemberExpr>(E)) {
|
2013-02-23 02:53:19 +00:00
|
|
|
// FIXME: If the base type of the member expr is not FD->getParent(),
|
|
|
|
|
// this should not be treated as a flexible array member access.
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
|
2020-03-18 15:46:31 -07:00
|
|
|
// FIXME: Sema doesn't treat a T[1] union member as a flexible array
|
|
|
|
|
// member, only a T[0] or T[] member gets that treatment.
|
|
|
|
|
if (FD->getParent()->isUnion())
|
|
|
|
|
return true;
|
2013-02-23 02:53:19 +00:00
|
|
|
RecordDecl::field_iterator FI(
|
|
|
|
|
DeclContext::decl_iterator(const_cast<FieldDecl *>(FD)));
|
|
|
|
|
return ++FI == FD->getParent()->field_end();
|
|
|
|
|
}
|
2016-10-04 20:36:04 +00:00
|
|
|
} else if (const auto *IRE = dyn_cast<ObjCIvarRefExpr>(E)) {
|
|
|
|
|
return IRE->getDecl()->getNextIvar() == nullptr;
|
2013-02-23 02:53:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-08 01:51:47 +00:00
|
|
|
llvm::Value *CodeGenFunction::LoadPassedObjectSize(const Expr *E,
|
|
|
|
|
QualType EltTy) {
|
|
|
|
|
ASTContext &C = getContext();
|
|
|
|
|
uint64_t EltSize = C.getTypeSizeInChars(EltTy).getQuantity();
|
|
|
|
|
if (!EltSize)
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
|
|
auto *ArrayDeclRef = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts());
|
|
|
|
|
if (!ArrayDeclRef)
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
|
|
auto *ParamDecl = dyn_cast<ParmVarDecl>(ArrayDeclRef->getDecl());
|
|
|
|
|
if (!ParamDecl)
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
|
|
auto *POSAttr = ParamDecl->getAttr<PassObjectSizeAttr>();
|
|
|
|
|
if (!POSAttr)
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
|
|
// Don't load the size if it's a lower bound.
|
|
|
|
|
int POSType = POSAttr->getType();
|
|
|
|
|
if (POSType != 0 && POSType != 1)
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
|
|
// Find the implicit size parameter.
|
|
|
|
|
auto PassedSizeIt = SizeArguments.find(ParamDecl);
|
|
|
|
|
if (PassedSizeIt == SizeArguments.end())
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
|
|
const ImplicitParamDecl *PassedSizeDecl = PassedSizeIt->second;
|
|
|
|
|
assert(LocalDeclMap.count(PassedSizeDecl) && "Passed size not loadable");
|
|
|
|
|
Address AddrOfSize = LocalDeclMap.find(PassedSizeDecl)->second;
|
|
|
|
|
llvm::Value *SizeInBytes = EmitLoadOfScalar(AddrOfSize, /*Volatile=*/false,
|
|
|
|
|
C.getSizeType(), E->getExprLoc());
|
|
|
|
|
llvm::Value *SizeOfElement =
|
|
|
|
|
llvm::ConstantInt::get(SizeInBytes->getType(), EltSize);
|
|
|
|
|
return Builder.CreateUDiv(SizeInBytes, SizeOfElement);
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-23 02:53:19 +00:00
|
|
|
/// If Base is known to point to the start of an array, return the length of
|
|
|
|
|
/// that array. Return 0 if the length cannot be determined.
|
2013-03-09 15:15:22 +00:00
|
|
|
static llvm::Value *getArrayIndexingBound(
|
|
|
|
|
CodeGenFunction &CGF, const Expr *Base, QualType &IndexedType) {
|
2013-02-23 02:53:19 +00:00
|
|
|
// For the vector indexing extension, the bound is the number of elements.
|
|
|
|
|
if (const VectorType *VT = Base->getType()->getAs<VectorType>()) {
|
|
|
|
|
IndexedType = Base->getType();
|
|
|
|
|
return CGF.Builder.getInt32(VT->getNumElements());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Base = Base->IgnoreParens();
|
|
|
|
|
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *CE = dyn_cast<CastExpr>(Base)) {
|
2013-02-23 02:53:19 +00:00
|
|
|
if (CE->getCastKind() == CK_ArrayToPointerDecay &&
|
|
|
|
|
!isFlexibleArrayMemberExpr(CE->getSubExpr())) {
|
|
|
|
|
IndexedType = CE->getSubExpr()->getType();
|
|
|
|
|
const ArrayType *AT = IndexedType->castAsArrayTypeUnsafe();
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
|
2013-02-23 02:53:19 +00:00
|
|
|
return CGF.Builder.getInt(CAT->getSize());
|
2014-05-09 00:08:36 +00:00
|
|
|
else if (const auto *VAT = dyn_cast<VariableArrayType>(AT))
|
2018-02-03 13:55:59 +00:00
|
|
|
return CGF.getVLASize(VAT).NumElts;
|
2017-12-08 01:51:47 +00:00
|
|
|
// Ignore pass_object_size here. It's not applicable on decayed pointers.
|
2013-02-23 02:53:19 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-08 01:51:47 +00:00
|
|
|
QualType EltTy{Base->getType()->getPointeeOrArrayElementType(), 0};
|
|
|
|
|
if (llvm::Value *POS = CGF.LoadPassedObjectSize(Base, EltTy)) {
|
|
|
|
|
IndexedType = Base->getType();
|
|
|
|
|
return POS;
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-21 05:09:00 +00:00
|
|
|
return nullptr;
|
2013-02-23 02:53:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CodeGenFunction::EmitBoundsCheck(const Expr *E, const Expr *Base,
|
|
|
|
|
llvm::Value *Index, QualType IndexType,
|
|
|
|
|
bool Accessed) {
|
2014-11-07 22:29:38 +00:00
|
|
|
assert(SanOpts.has(SanitizerKind::ArrayBounds) &&
|
2013-10-22 22:51:04 +00:00
|
|
|
"should not be called unless adding bounds checks");
|
2014-07-17 18:46:27 +00:00
|
|
|
SanitizerScope SanScope(this);
|
2013-02-24 01:56:24 +00:00
|
|
|
|
2013-02-23 02:53:19 +00:00
|
|
|
QualType IndexedType;
|
|
|
|
|
llvm::Value *Bound = getArrayIndexingBound(*this, Base, IndexedType);
|
|
|
|
|
if (!Bound)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
bool IndexSigned = IndexType->isSignedIntegerOrEnumerationType();
|
|
|
|
|
llvm::Value *IndexVal = Builder.CreateIntCast(Index, SizeTy, IndexSigned);
|
|
|
|
|
llvm::Value *BoundVal = Builder.CreateIntCast(Bound, SizeTy, false);
|
|
|
|
|
|
|
|
|
|
llvm::Constant *StaticData[] = {
|
|
|
|
|
EmitCheckSourceLocation(E->getExprLoc()),
|
|
|
|
|
EmitCheckTypeDescriptor(IndexedType),
|
|
|
|
|
EmitCheckTypeDescriptor(IndexType)
|
|
|
|
|
};
|
|
|
|
|
llvm::Value *Check = Accessed ? Builder.CreateICmpULT(IndexVal, BoundVal)
|
|
|
|
|
: Builder.CreateICmpULE(IndexVal, BoundVal);
|
2016-12-12 16:18:40 +00:00
|
|
|
EmitCheck(std::make_pair(Check, SanitizerKind::ArrayBounds),
|
|
|
|
|
SanitizerHandler::OutOfBounds, StaticData, Index);
|
2013-02-23 02:53:19 +00:00
|
|
|
}
|
|
|
|
|
|
2010-01-09 21:40:03 +00:00
|
|
|
|
|
|
|
|
CodeGenFunction::ComplexPairTy CodeGenFunction::
|
|
|
|
|
EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV,
|
|
|
|
|
bool isInc, bool isPre) {
|
2013-10-02 02:29:49 +00:00
|
|
|
ComplexPairTy InVal = EmitLoadOfComplex(LV, E->getExprLoc());
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2010-01-09 21:40:03 +00:00
|
|
|
llvm::Value *NextVal;
|
|
|
|
|
if (isa<llvm::IntegerType>(InVal.first->getType())) {
|
|
|
|
|
uint64_t AmountVal = isInc ? 1 : -1;
|
|
|
|
|
NextVal = llvm::ConstantInt::get(InVal.first->getType(), AmountVal, true);
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2010-01-09 21:40:03 +00:00
|
|
|
// Add the inc/dec to the real part.
|
|
|
|
|
NextVal = Builder.CreateAdd(InVal.first, NextVal, isInc ? "inc" : "dec");
|
|
|
|
|
} else {
|
2019-10-07 16:42:25 +00:00
|
|
|
QualType ElemTy = E->getType()->castAs<ComplexType>()->getElementType();
|
2010-01-09 21:40:03 +00:00
|
|
|
llvm::APFloat FVal(getContext().getFloatTypeSemantics(ElemTy), 1);
|
|
|
|
|
if (!isInc)
|
|
|
|
|
FVal.changeSign();
|
|
|
|
|
NextVal = llvm::ConstantFP::get(getLLVMContext(), FVal);
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2010-01-09 21:40:03 +00:00
|
|
|
// Add the inc/dec to the real part.
|
|
|
|
|
NextVal = Builder.CreateFAdd(InVal.first, NextVal, isInc ? "inc" : "dec");
|
|
|
|
|
}
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2010-01-09 21:40:03 +00:00
|
|
|
ComplexPairTy IncVal(NextVal, InVal.second);
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2010-01-09 21:40:03 +00:00
|
|
|
// Store the updated result through the lvalue.
|
2013-03-07 21:37:08 +00:00
|
|
|
EmitStoreOfComplex(IncVal, LV, /*init*/ false);
|
2020-01-06 16:14:34 -05:00
|
|
|
if (getLangOpts().OpenMP)
|
|
|
|
|
CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*this,
|
|
|
|
|
E->getSubExpr());
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2010-01-09 21:40:03 +00:00
|
|
|
// If this is a postinc, return the value read from memory, otherwise use the
|
|
|
|
|
// updated value.
|
|
|
|
|
return isPre ? IncVal : InVal;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-20 04:24:12 +00:00
|
|
|
void CodeGenModule::EmitExplicitCastExprType(const ExplicitCastExpr *E,
|
|
|
|
|
CodeGenFunction *CGF) {
|
|
|
|
|
// Bind VLAs in the cast type.
|
|
|
|
|
if (CGF && E->getType()->isVariablyModifiedType())
|
|
|
|
|
CGF->EmitVariablyModifiedType(E->getType());
|
|
|
|
|
|
|
|
|
|
if (CGDebugInfo *DI = getModuleDebugInfo())
|
|
|
|
|
DI->EmitExplicitCastType(E->getType());
|
|
|
|
|
}
|
|
|
|
|
|
2007-06-02 19:47:04 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
2007-06-02 05:24:33 +00:00
|
|
|
// LValue Expression Emission
|
2007-06-02 19:47:04 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
2007-06-02 05:24:33 +00: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 08:05:57 +00:00
|
|
|
/// EmitPointerWithAlignment - Given an expression of pointer type, try to
|
|
|
|
|
/// derive a more accurate bound on the alignment of the pointer.
|
|
|
|
|
Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E,
|
2017-10-17 09:12:13 +00:00
|
|
|
LValueBaseInfo *BaseInfo,
|
|
|
|
|
TBAAAccessInfo *TBAAInfo) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
// We allow this with ObjC object pointers because of fragile ABIs.
|
|
|
|
|
assert(E->getType()->isPointerType() ||
|
|
|
|
|
E->getType()->isObjCObjectPointerType());
|
|
|
|
|
E = E->IgnoreParens();
|
|
|
|
|
|
|
|
|
|
// Casts:
|
|
|
|
|
if (const CastExpr *CE = dyn_cast<CastExpr>(E)) {
|
2015-10-20 04:24:12 +00:00
|
|
|
if (const auto *ECE = dyn_cast<ExplicitCastExpr>(CE))
|
|
|
|
|
CGM.EmitExplicitCastExprType(ECE, this);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
|
|
|
|
|
switch (CE->getCastKind()) {
|
|
|
|
|
// Non-converting casts (but not C's implicit conversion from void*).
|
|
|
|
|
case CK_BitCast:
|
|
|
|
|
case CK_NoOp:
|
2017-09-27 14:37:00 +00:00
|
|
|
case CK_AddressSpaceConversion:
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
if (auto PtrTy = CE->getSubExpr()->getType()->getAs<PointerType>()) {
|
|
|
|
|
if (PtrTy->getPointeeType()->isVoidType())
|
|
|
|
|
break;
|
|
|
|
|
|
2017-10-17 09:12:13 +00:00
|
|
|
LValueBaseInfo InnerBaseInfo;
|
|
|
|
|
TBAAAccessInfo InnerTBAAInfo;
|
|
|
|
|
Address Addr = EmitPointerWithAlignment(CE->getSubExpr(),
|
|
|
|
|
&InnerBaseInfo,
|
|
|
|
|
&InnerTBAAInfo);
|
|
|
|
|
if (BaseInfo) *BaseInfo = InnerBaseInfo;
|
|
|
|
|
if (TBAAInfo) *TBAAInfo = InnerTBAAInfo;
|
|
|
|
|
|
|
|
|
|
if (isa<ExplicitCastExpr>(CE)) {
|
|
|
|
|
LValueBaseInfo TargetTypeBaseInfo;
|
|
|
|
|
TBAAAccessInfo TargetTypeTBAAInfo;
|
2020-05-18 11:29:11 -07:00
|
|
|
CharUnits Align = CGM.getNaturalPointeeTypeAlignment(
|
|
|
|
|
E->getType(), &TargetTypeBaseInfo, &TargetTypeTBAAInfo);
|
2017-10-17 09:12:13 +00:00
|
|
|
if (TBAAInfo)
|
|
|
|
|
*TBAAInfo = CGM.mergeTBAAInfoForCast(*TBAAInfo,
|
|
|
|
|
TargetTypeTBAAInfo);
|
|
|
|
|
// If the source l-value is opaque, honor the alignment of the
|
|
|
|
|
// casted-to type.
|
|
|
|
|
if (InnerBaseInfo.getAlignmentSource() != AlignmentSource::Decl) {
|
|
|
|
|
if (BaseInfo)
|
|
|
|
|
BaseInfo->mergeForCast(TargetTypeBaseInfo);
|
|
|
|
|
Addr = Address(Addr.getPointer(), Align);
|
|
|
|
|
}
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
}
|
|
|
|
|
|
2016-01-14 02:49:48 +00:00
|
|
|
if (SanOpts.has(SanitizerKind::CFIUnrelatedCast) &&
|
|
|
|
|
CE->getCastKind() == CK_BitCast) {
|
2015-09-09 00:01:31 +00:00
|
|
|
if (auto PT = E->getType()->getAs<PointerType>())
|
|
|
|
|
EmitVTablePtrCheckForCast(PT->getPointeeType(), Addr.getPointer(),
|
|
|
|
|
/*MayBeNull=*/true,
|
|
|
|
|
CodeGenFunction::CFITCK_UnrelatedCast,
|
2018-08-09 21:08:08 +00:00
|
|
|
CE->getBeginLoc());
|
2015-09-09 00:01:31 +00:00
|
|
|
}
|
2017-09-27 14:37:00 +00:00
|
|
|
return CE->getCastKind() != CK_AddressSpaceConversion
|
|
|
|
|
? Builder.CreateBitCast(Addr, ConvertType(E->getType()))
|
|
|
|
|
: Builder.CreateAddrSpaceCast(Addr,
|
|
|
|
|
ConvertType(E->getType()));
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// Array-to-pointer decay.
|
|
|
|
|
case CK_ArrayToPointerDecay:
|
2017-10-17 09:12:13 +00:00
|
|
|
return EmitArrayToPointerDecay(CE->getSubExpr(), BaseInfo, TBAAInfo);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
|
|
|
|
|
// Derived-to-base conversions.
|
|
|
|
|
case CK_UncheckedDerivedToBase:
|
|
|
|
|
case CK_DerivedToBase: {
|
2018-01-08 15:36:06 +00:00
|
|
|
// TODO: Support accesses to members of base classes in TBAA. For now, we
|
|
|
|
|
// conservatively pretend that the complete object is of the base class
|
|
|
|
|
// type.
|
|
|
|
|
if (TBAAInfo)
|
|
|
|
|
*TBAAInfo = CGM.getTBAAAccessInfo(E->getType());
|
|
|
|
|
Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
auto Derived = CE->getSubExpr()->getType()->getPointeeCXXRecordDecl();
|
|
|
|
|
return GetAddressOfBaseClass(Addr, Derived,
|
|
|
|
|
CE->path_begin(), CE->path_end(),
|
|
|
|
|
ShouldNullCheckClassCastValue(CE),
|
|
|
|
|
CE->getExprLoc());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: Is there any reason to treat base-to-derived conversions
|
|
|
|
|
// specially?
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Unary &.
|
|
|
|
|
if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
|
|
|
|
|
if (UO->getOpcode() == UO_AddrOf) {
|
|
|
|
|
LValue LV = EmitLValue(UO->getSubExpr());
|
2017-05-18 17:07:11 +00:00
|
|
|
if (BaseInfo) *BaseInfo = LV.getBaseInfo();
|
2017-10-17 09:12:13 +00:00
|
|
|
if (TBAAInfo) *TBAAInfo = LV.getTBAAInfo();
|
2019-12-03 15:17:01 -08:00
|
|
|
return LV.getAddress(*this);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: conditional operators, comma.
|
|
|
|
|
|
|
|
|
|
// Otherwise, use the alignment of the type.
|
2020-05-18 11:29:11 -07:00
|
|
|
CharUnits Align =
|
|
|
|
|
CGM.getNaturalPointeeTypeAlignment(E->getType(), BaseInfo, TBAAInfo);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
return Address(EmitScalarExpr(E), Align);
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-25 13:09:47 -07:00
|
|
|
llvm::Value *CodeGenFunction::EmitNonNullRValueCheck(RValue RV, QualType T) {
|
|
|
|
|
llvm::Value *V = RV.getScalarVal();
|
|
|
|
|
if (auto MPT = T->getAs<MemberPointerType>())
|
|
|
|
|
return CGM.getCXXABI().EmitMemberPointerIsNotNull(*this, V, MPT);
|
|
|
|
|
return Builder.CreateICmpNE(V, llvm::Constant::getNullValue(V->getType()));
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-05 07:09:07 +00:00
|
|
|
RValue CodeGenFunction::GetUndefRValue(QualType Ty) {
|
2009-10-28 17:39:19 +00:00
|
|
|
if (Ty->isVoidType())
|
2014-05-21 05:09:00 +00:00
|
|
|
return RValue::get(nullptr);
|
2013-03-07 21:37:08 +00:00
|
|
|
|
|
|
|
|
switch (getEvaluationKind(Ty)) {
|
|
|
|
|
case TEK_Complex: {
|
|
|
|
|
llvm::Type *EltTy =
|
|
|
|
|
ConvertType(Ty->castAs<ComplexType>()->getElementType());
|
2009-07-30 23:11:26 +00:00
|
|
|
llvm::Value *U = llvm::UndefValue::get(EltTy);
|
2009-01-09 20:09:28 +00:00
|
|
|
return RValue::getComplex(std::make_pair(U, U));
|
2009-10-28 17:39:19 +00:00
|
|
|
}
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2010-08-23 05:26:13 +00:00
|
|
|
// If this is a use of an undefined aggregate type, the aggregate must have an
|
|
|
|
|
// identifiable address. Just because the contents of the value are undefined
|
|
|
|
|
// doesn't mean that the address can't be taken and compared.
|
2013-03-07 21:37:08 +00:00
|
|
|
case TEK_Aggregate: {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Address DestPtr = CreateMemTemp(Ty, "undef.agg.tmp");
|
2010-08-23 05:26:13 +00:00
|
|
|
return RValue::getAggregate(DestPtr);
|
2009-01-09 20:09:28 +00:00
|
|
|
}
|
2013-03-07 21:37:08 +00:00
|
|
|
|
|
|
|
|
case TEK_Scalar:
|
|
|
|
|
return RValue::get(llvm::UndefValue::get(ConvertType(Ty)));
|
|
|
|
|
}
|
|
|
|
|
llvm_unreachable("bad evaluation kind");
|
2009-01-09 16:50:52 +00:00
|
|
|
}
|
|
|
|
|
|
2009-02-05 07:09:07 +00:00
|
|
|
RValue CodeGenFunction::EmitUnsupportedRValue(const Expr *E,
|
|
|
|
|
const char *Name) {
|
|
|
|
|
ErrorUnsupported(E, Name);
|
|
|
|
|
return GetUndefRValue(E->getType());
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-25 20:45:57 +00:00
|
|
|
LValue CodeGenFunction::EmitUnsupportedLValue(const Expr *E,
|
|
|
|
|
const char *Name) {
|
|
|
|
|
ErrorUnsupported(E, Name);
|
2009-07-29 22:16:19 +00:00
|
|
|
llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType()));
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
return MakeAddrLValue(Address(llvm::UndefValue::get(Ty), CharUnits::One()),
|
|
|
|
|
E->getType());
|
2008-08-25 20:45:57 +00:00
|
|
|
}
|
|
|
|
|
|
2017-04-14 22:03:34 +00:00
|
|
|
bool CodeGenFunction::IsWrappedCXXThis(const Expr *Obj) {
|
Retry^2: [ubsan] Reduce null checking of C++ object pointers (PR27581)
This patch teaches ubsan to insert exactly one null check for the 'this'
pointer per method/lambda.
Previously, given a load of a member variable from an instance method
('this->x'), ubsan would insert a null check for 'this', and another
null check for '&this->x', before allowing the load to occur.
Similarly, given a call to a method from another method bound to the
same instance ('this->foo()'), ubsan would a redundant null check for
'this'. There is also a redundant null check in the case where the
object pointer is a reference ('Ref.foo()').
This patch teaches ubsan to remove the redundant null checks identified
above.
Testing: check-clang, check-ubsan, and a stage2 ubsan build.
I also compiled X86FastISel.cpp with -fsanitize=null using
patched/unpatched clangs based on r293572. Here are the number of null
checks emitted:
-------------------------------------
| Setup | # of null checks |
-------------------------------------
| unpatched, -O0 | 21767 |
| patched, -O0 | 10758 |
-------------------------------------
Changes since the initial commit:
- Don't introduce any unintentional object-size or alignment checks.
- Don't rely on IRGen of C labels in the test.
Differential Revision: https://reviews.llvm.org/D29530
llvm-svn: 295515
2017-02-17 23:22:59 +00:00
|
|
|
const Expr *Base = Obj;
|
|
|
|
|
while (!isa<CXXThisExpr>(Base)) {
|
|
|
|
|
// The result of a dynamic_cast can be null.
|
|
|
|
|
if (isa<CXXDynamicCastExpr>(Base))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (const auto *CE = dyn_cast<CastExpr>(Base)) {
|
|
|
|
|
Base = CE->getSubExpr();
|
|
|
|
|
} else if (const auto *PE = dyn_cast<ParenExpr>(Base)) {
|
|
|
|
|
Base = PE->getSubExpr();
|
|
|
|
|
} else if (const auto *UO = dyn_cast<UnaryOperator>(Base)) {
|
|
|
|
|
if (UO->getOpcode() == UO_Extension)
|
|
|
|
|
Base = UO->getSubExpr();
|
|
|
|
|
else
|
|
|
|
|
return false;
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-08 02:08:36 +00:00
|
|
|
LValue CodeGenFunction::EmitCheckedLValue(const Expr *E, TypeCheckKind TCK) {
|
2013-02-23 02:53:19 +00:00
|
|
|
LValue LV;
|
2014-11-07 22:29:38 +00:00
|
|
|
if (SanOpts.has(SanitizerKind::ArrayBounds) && isa<ArraySubscriptExpr>(E))
|
2013-02-23 02:53:19 +00:00
|
|
|
LV = EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E), /*Accessed*/true);
|
|
|
|
|
else
|
|
|
|
|
LV = EmitLValue(E);
|
Retry^2: [ubsan] Reduce null checking of C++ object pointers (PR27581)
This patch teaches ubsan to insert exactly one null check for the 'this'
pointer per method/lambda.
Previously, given a load of a member variable from an instance method
('this->x'), ubsan would insert a null check for 'this', and another
null check for '&this->x', before allowing the load to occur.
Similarly, given a call to a method from another method bound to the
same instance ('this->foo()'), ubsan would a redundant null check for
'this'. There is also a redundant null check in the case where the
object pointer is a reference ('Ref.foo()').
This patch teaches ubsan to remove the redundant null checks identified
above.
Testing: check-clang, check-ubsan, and a stage2 ubsan build.
I also compiled X86FastISel.cpp with -fsanitize=null using
patched/unpatched clangs based on r293572. Here are the number of null
checks emitted:
-------------------------------------
| Setup | # of null checks |
-------------------------------------
| unpatched, -O0 | 21767 |
| patched, -O0 | 10758 |
-------------------------------------
Changes since the initial commit:
- Don't introduce any unintentional object-size or alignment checks.
- Don't rely on IRGen of C labels in the test.
Differential Revision: https://reviews.llvm.org/D29530
llvm-svn: 295515
2017-02-17 23:22:59 +00:00
|
|
|
if (!isa<DeclRefExpr>(E) && !LV.isBitField() && LV.isSimple()) {
|
|
|
|
|
SanitizerSet SkippedChecks;
|
2017-04-14 22:03:34 +00:00
|
|
|
if (const auto *ME = dyn_cast<MemberExpr>(E)) {
|
|
|
|
|
bool IsBaseCXXThis = IsWrappedCXXThis(ME->getBase());
|
|
|
|
|
if (IsBaseCXXThis)
|
|
|
|
|
SkippedChecks.set(SanitizerKind::Alignment, true);
|
|
|
|
|
if (IsBaseCXXThis || isa<DeclRefExpr>(ME->getBase()))
|
Retry^2: [ubsan] Reduce null checking of C++ object pointers (PR27581)
This patch teaches ubsan to insert exactly one null check for the 'this'
pointer per method/lambda.
Previously, given a load of a member variable from an instance method
('this->x'), ubsan would insert a null check for 'this', and another
null check for '&this->x', before allowing the load to occur.
Similarly, given a call to a method from another method bound to the
same instance ('this->foo()'), ubsan would a redundant null check for
'this'. There is also a redundant null check in the case where the
object pointer is a reference ('Ref.foo()').
This patch teaches ubsan to remove the redundant null checks identified
above.
Testing: check-clang, check-ubsan, and a stage2 ubsan build.
I also compiled X86FastISel.cpp with -fsanitize=null using
patched/unpatched clangs based on r293572. Here are the number of null
checks emitted:
-------------------------------------
| Setup | # of null checks |
-------------------------------------
| unpatched, -O0 | 21767 |
| patched, -O0 | 10758 |
-------------------------------------
Changes since the initial commit:
- Don't introduce any unintentional object-size or alignment checks.
- Don't rely on IRGen of C labels in the test.
Differential Revision: https://reviews.llvm.org/D29530
llvm-svn: 295515
2017-02-17 23:22:59 +00:00
|
|
|
SkippedChecks.set(SanitizerKind::Null, true);
|
2017-04-14 22:03:34 +00:00
|
|
|
}
|
2019-12-03 15:17:01 -08:00
|
|
|
EmitTypeCheck(TCK, E->getExprLoc(), LV.getPointer(*this), E->getType(),
|
|
|
|
|
LV.getAlignment(), SkippedChecks);
|
Retry^2: [ubsan] Reduce null checking of C++ object pointers (PR27581)
This patch teaches ubsan to insert exactly one null check for the 'this'
pointer per method/lambda.
Previously, given a load of a member variable from an instance method
('this->x'), ubsan would insert a null check for 'this', and another
null check for '&this->x', before allowing the load to occur.
Similarly, given a call to a method from another method bound to the
same instance ('this->foo()'), ubsan would a redundant null check for
'this'. There is also a redundant null check in the case where the
object pointer is a reference ('Ref.foo()').
This patch teaches ubsan to remove the redundant null checks identified
above.
Testing: check-clang, check-ubsan, and a stage2 ubsan build.
I also compiled X86FastISel.cpp with -fsanitize=null using
patched/unpatched clangs based on r293572. Here are the number of null
checks emitted:
-------------------------------------
| Setup | # of null checks |
-------------------------------------
| unpatched, -O0 | 21767 |
| patched, -O0 | 10758 |
-------------------------------------
Changes since the initial commit:
- Don't introduce any unintentional object-size or alignment checks.
- Don't rely on IRGen of C labels in the test.
Differential Revision: https://reviews.llvm.org/D29530
llvm-svn: 295515
2017-02-17 23:22:59 +00:00
|
|
|
}
|
2009-12-16 02:57:00 +00:00
|
|
|
return LV;
|
|
|
|
|
}
|
|
|
|
|
|
2007-06-05 20:53:16 +00:00
|
|
|
/// EmitLValue - Emit code to compute a designator that specifies the location
|
|
|
|
|
/// of the expression.
|
|
|
|
|
///
|
2009-09-09 13:00:44 +00:00
|
|
|
/// This can return one of two things: a simple address or a bitfield reference.
|
|
|
|
|
/// In either case, the LLVM Value* in the LValue structure is guaranteed to be
|
|
|
|
|
/// an LLVM pointer type.
|
2007-06-05 20:53:16 +00:00
|
|
|
///
|
2009-09-09 13:00:44 +00:00
|
|
|
/// If this returns a bitfield reference, nothing about the pointee type of the
|
|
|
|
|
/// LLVM value is known: For example, it may not be a pointer to an integer.
|
2007-06-05 20:53:16 +00:00
|
|
|
///
|
2009-09-09 13:00:44 +00:00
|
|
|
/// If this returns a normal address, and if the lvalue's C type is fixed size,
|
|
|
|
|
/// this method guarantees that the returned pointer type will point to an LLVM
|
|
|
|
|
/// type of the same size of the lvalue's type. If the lvalue has a variable
|
|
|
|
|
/// length type, this is not possible.
|
2007-06-05 20:53:16 +00:00
|
|
|
///
|
2007-06-02 05:24:33 +00:00
|
|
|
LValue CodeGenFunction::EmitLValue(const Expr *E) {
|
DebugInfo: Use the preferred location rather than the start location for expression line info
This causes things like assignment to refer to the '=' rather than the
LHS when attributing the store instruction, for example.
There were essentially 3 options for this:
* The beginning of an expression (this was the behavior prior to this
commit). This meant that stepping through subexpressions would bounce
around from subexpressions back to the start of the outer expression,
etc. (eg: x + y + z would go x, y, x, z, x (the repeated 'x's would be
where the actual addition occurred)).
* The end of an expression. This seems to be what GCC does /mostly/, and
certainly this for function calls. This has the advantage that
progress is always 'forwards' (never jumping backwards - except for
independent subexpressions if they're evaluated in interesting orders,
etc). "x + y + z" would go "x y z" with the additions occurring at y
and z after the respective loads.
The problem with this is that the user would still have to think
fairly hard about precedence to realize which subexpression is being
evaluated or which operator overload is being called in, say, an asan
backtrace.
* The preferred location or 'exprloc'. In this case you get sort of what
you'd expect, though it's a bit confusing in its own way due to going
'backwards'. In this case the locations would be: "x y + z +" in
lovely postfix arithmetic order. But this does mean that if the op+
were an operator overload, say, and in a backtrace, the backtrace will
point to the exact '+' that's being called, not to the end of one of
its operands.
(actually the operator overload case doesn't work yet for other reasons,
but that's being fixed - but this at least gets scalar/complex
assignments and other plain operators right)
llvm-svn: 227027
2015-01-25 01:19:10 +00:00
|
|
|
ApplyDebugLocation DL(*this, E);
|
2007-06-02 05:24:33 +00:00
|
|
|
switch (E->getStmtClass()) {
|
2008-08-25 20:45:57 +00:00
|
|
|
default: return EmitUnsupportedLValue(E, "l-value expression");
|
2007-06-02 05:24:33 +00:00
|
|
|
|
2011-11-07 03:59:57 +00:00
|
|
|
case Expr::ObjCPropertyRefExprClass:
|
|
|
|
|
llvm_unreachable("cannot emit a property reference directly");
|
|
|
|
|
|
2010-06-17 19:56:20 +00:00
|
|
|
case Expr::ObjCSelectorExprClass:
|
2012-10-11 10:13:44 +00:00
|
|
|
return EmitObjCSelectorLValue(cast<ObjCSelectorExpr>(E));
|
2009-12-09 23:35:29 +00:00
|
|
|
case Expr::ObjCIsaExprClass:
|
|
|
|
|
return EmitObjCIsaExpr(cast<ObjCIsaExpr>(E));
|
2009-09-09 13:00:44 +00:00
|
|
|
case Expr::BinaryOperatorClass:
|
2008-09-04 03:20:13 +00:00
|
|
|
return EmitBinaryOperatorLValue(cast<BinaryOperator>(E));
|
2015-02-14 01:48:17 +00:00
|
|
|
case Expr::CompoundAssignOperatorClass: {
|
|
|
|
|
QualType Ty = E->getType();
|
|
|
|
|
if (const AtomicType *AT = Ty->getAs<AtomicType>())
|
|
|
|
|
Ty = AT->getValueType();
|
|
|
|
|
if (!Ty->isAnyComplexType())
|
2010-12-05 02:00:02 +00:00
|
|
|
return EmitCompoundAssignmentLValue(cast<CompoundAssignOperator>(E));
|
|
|
|
|
return EmitComplexCompoundAssignmentLValue(cast<CompoundAssignOperator>(E));
|
2015-02-14 01:48:17 +00:00
|
|
|
}
|
2009-09-09 13:00:44 +00:00
|
|
|
case Expr::CallExprClass:
|
2009-09-01 21:18:52 +00:00
|
|
|
case Expr::CXXMemberCallExprClass:
|
2008-11-14 16:09:21 +00:00
|
|
|
case Expr::CXXOperatorCallExprClass:
|
2012-03-07 08:35:16 +00:00
|
|
|
case Expr::UserDefinedLiteralClass:
|
2008-11-14 16:09:21 +00:00
|
|
|
return EmitCallExprLValue(cast<CallExpr>(E));
|
2019-10-19 00:04:38 +00:00
|
|
|
case Expr::CXXRewrittenBinaryOperatorClass:
|
|
|
|
|
return EmitLValue(cast<CXXRewrittenBinaryOperator>(E)->getSemanticForm());
|
2009-02-11 20:59:32 +00:00
|
|
|
case Expr::VAArgExprClass:
|
|
|
|
|
return EmitVAArgExprLValue(cast<VAArgExpr>(E));
|
2009-09-09 13:00:44 +00:00
|
|
|
case Expr::DeclRefExprClass:
|
2009-01-06 05:10:23 +00:00
|
|
|
return EmitDeclRefLValue(cast<DeclRefExpr>(E));
|
2020-06-14 14:39:14 +02:00
|
|
|
case Expr::ConstantExprClass: {
|
|
|
|
|
const ConstantExpr *CE = cast<ConstantExpr>(E);
|
|
|
|
|
if (llvm::Value *Result = ConstantEmitter(*this).tryEmitConstantExpr(CE)) {
|
|
|
|
|
QualType RetType = cast<CallExpr>(CE->getSubExpr()->IgnoreImplicit())
|
|
|
|
|
->getCallReturnType(getContext());
|
|
|
|
|
return MakeNaturalAlignAddrLValue(Result, RetType);
|
|
|
|
|
}
|
2018-11-09 00:41:36 +00:00
|
|
|
return EmitLValue(cast<ConstantExpr>(E)->getSubExpr());
|
2020-06-14 14:39:14 +02:00
|
|
|
}
|
2011-09-08 17:15:04 +00:00
|
|
|
case Expr::ParenExprClass:
|
|
|
|
|
return EmitLValue(cast<ParenExpr>(E)->getSubExpr());
|
2011-04-15 00:35:48 +00:00
|
|
|
case Expr::GenericSelectionExprClass:
|
|
|
|
|
return EmitLValue(cast<GenericSelectionExpr>(E)->getResultExpr());
|
2008-08-10 01:53:14 +00:00
|
|
|
case Expr::PredefinedExprClass:
|
|
|
|
|
return EmitPredefinedLValue(cast<PredefinedExpr>(E));
|
2007-06-06 04:54:52 +00:00
|
|
|
case Expr::StringLiteralClass:
|
|
|
|
|
return EmitStringLiteralLValue(cast<StringLiteral>(E));
|
2009-02-24 22:18:39 +00:00
|
|
|
case Expr::ObjCEncodeExprClass:
|
|
|
|
|
return EmitObjCEncodeExprLValue(cast<ObjCEncodeExpr>(E));
|
2011-11-06 09:01:30 +00:00
|
|
|
case Expr::PseudoObjectExprClass:
|
|
|
|
|
return EmitPseudoObjectLValue(cast<PseudoObjectExpr>(E));
|
2011-11-27 16:50:07 +00:00
|
|
|
case Expr::InitListExprClass:
|
2012-05-14 21:57:21 +00:00
|
|
|
return EmitInitListLValue(cast<InitListExpr>(E));
|
2009-05-30 23:23:33 +00:00
|
|
|
case Expr::CXXTemporaryObjectExprClass:
|
|
|
|
|
case Expr::CXXConstructExprClass:
|
2009-05-30 23:30:54 +00:00
|
|
|
return EmitCXXConstructLValue(cast<CXXConstructExpr>(E));
|
|
|
|
|
case Expr::CXXBindTemporaryExprClass:
|
|
|
|
|
return EmitCXXBindTemporaryLValue(cast<CXXBindTemporaryExpr>(E));
|
2012-10-11 10:13:44 +00:00
|
|
|
case Expr::CXXUuidofExprClass:
|
|
|
|
|
return EmitCXXUuidofLValue(cast<CXXUuidofExpr>(E));
|
2019-04-02 19:48:07 +00:00
|
|
|
case Expr::LambdaExprClass:
|
|
|
|
|
return EmitAggExprToLValue(E);
|
2011-11-10 08:15:53 +00:00
|
|
|
|
|
|
|
|
case Expr::ExprWithCleanupsClass: {
|
2014-05-09 00:08:36 +00:00
|
|
|
const auto *cleanups = cast<ExprWithCleanups>(E);
|
2011-11-10 08:15:53 +00:00
|
|
|
RunCleanupsScope Scope(*this);
|
2017-03-06 22:18:34 +00:00
|
|
|
LValue LV = EmitLValue(cleanups->getSubExpr());
|
|
|
|
|
if (LV.isSimple()) {
|
|
|
|
|
// Defend against branches out of gnu statement expressions surrounded by
|
|
|
|
|
// cleanups.
|
2019-12-03 15:17:01 -08:00
|
|
|
llvm::Value *V = LV.getPointer(*this);
|
2017-03-06 22:18:34 +00:00
|
|
|
Scope.ForceCleanup({&V});
|
|
|
|
|
return LValue::MakeAddr(Address(V, LV.getAlignment()), LV.getType(),
|
2017-10-06 08:17:48 +00:00
|
|
|
getContext(), LV.getBaseInfo(), LV.getTBAAInfo());
|
2017-03-06 22:18:34 +00:00
|
|
|
}
|
|
|
|
|
// FIXME: Is it possible to create an ExprWithCleanups that produces a
|
|
|
|
|
// bitfield lvalue or some other non-simple lvalue?
|
|
|
|
|
return LV;
|
2011-11-10 08:15:53 +00:00
|
|
|
}
|
|
|
|
|
|
Implement __builtin_LINE() et. al. to support source location capture.
Summary:
This patch implements the source location builtins `__builtin_LINE(), `__builtin_FUNCTION()`, `__builtin_FILE()` and `__builtin_COLUMN()`. These builtins are needed to implement [`std::experimental::source_location`](https://rawgit.com/cplusplus/fundamentals-ts/v2/main.html#reflection.src_loc.creation).
With the exception of `__builtin_COLUMN`, GCC also implements these builtins, and Clangs behavior is intended to match as closely as possible.
Reviewers: rsmith, joerg, aaron.ballman, bogner, majnemer, shafik, martong
Reviewed By: rsmith
Subscribers: rnkovacs, loskutov, riccibruno, mgorny, kunitoki, alexr, majnemer, hfinkel, cfe-commits
Differential Revision: https://reviews.llvm.org/D37035
llvm-svn: 360937
2019-05-16 21:04:15 +00:00
|
|
|
case Expr::CXXDefaultArgExprClass: {
|
|
|
|
|
auto *DAE = cast<CXXDefaultArgExpr>(E);
|
|
|
|
|
CXXDefaultArgExprScope Scope(*this, DAE);
|
|
|
|
|
return EmitLValue(DAE->getExpr());
|
|
|
|
|
}
|
2013-04-20 22:23:05 +00:00
|
|
|
case Expr::CXXDefaultInitExprClass: {
|
Implement __builtin_LINE() et. al. to support source location capture.
Summary:
This patch implements the source location builtins `__builtin_LINE(), `__builtin_FUNCTION()`, `__builtin_FILE()` and `__builtin_COLUMN()`. These builtins are needed to implement [`std::experimental::source_location`](https://rawgit.com/cplusplus/fundamentals-ts/v2/main.html#reflection.src_loc.creation).
With the exception of `__builtin_COLUMN`, GCC also implements these builtins, and Clangs behavior is intended to match as closely as possible.
Reviewers: rsmith, joerg, aaron.ballman, bogner, majnemer, shafik, martong
Reviewed By: rsmith
Subscribers: rnkovacs, loskutov, riccibruno, mgorny, kunitoki, alexr, majnemer, hfinkel, cfe-commits
Differential Revision: https://reviews.llvm.org/D37035
llvm-svn: 360937
2019-05-16 21:04:15 +00:00
|
|
|
auto *DIE = cast<CXXDefaultInitExpr>(E);
|
|
|
|
|
CXXDefaultInitExprScope Scope(*this, DIE);
|
|
|
|
|
return EmitLValue(DIE->getExpr());
|
2013-04-20 22:23:05 +00:00
|
|
|
}
|
2009-11-15 08:09:41 +00:00
|
|
|
case Expr::CXXTypeidExprClass:
|
|
|
|
|
return EmitCXXTypeidLValue(cast<CXXTypeidExpr>(E));
|
2009-05-30 23:30:54 +00:00
|
|
|
|
2008-08-23 10:51:21 +00:00
|
|
|
case Expr::ObjCMessageExprClass:
|
|
|
|
|
return EmitObjCMessageExprLValue(cast<ObjCMessageExpr>(E));
|
2009-09-09 13:00:44 +00:00
|
|
|
case Expr::ObjCIvarRefExprClass:
|
2008-03-30 23:03:07 +00:00
|
|
|
return EmitObjCIvarRefLValue(cast<ObjCIvarRefExpr>(E));
|
2009-04-25 19:35:26 +00:00
|
|
|
case Expr::StmtExprClass:
|
|
|
|
|
return EmitStmtExprLValue(cast<StmtExpr>(E));
|
2009-09-09 13:00:44 +00:00
|
|
|
case Expr::UnaryOperatorClass:
|
2007-06-05 20:53:16 +00:00
|
|
|
return EmitUnaryOpLValue(cast<UnaryOperator>(E));
|
2007-06-08 23:31:14 +00:00
|
|
|
case Expr::ArraySubscriptExprClass:
|
|
|
|
|
return EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E));
|
[Matrix] Implement matrix index expressions ([][]).
This patch implements matrix index expressions
(matrix[RowIdx][ColumnIdx]).
It does so by introducing a new MatrixSubscriptExpr(Base, RowIdx, ColumnIdx).
MatrixSubscriptExprs are built in 2 steps in ActOnMatrixSubscriptExpr. First,
if the base of a subscript is of matrix type, we create a incomplete
MatrixSubscriptExpr(base, idx, nullptr). Second, if the base is an incomplete
MatrixSubscriptExpr, we create a complete
MatrixSubscriptExpr(base->getBase(), base->getRowIdx(), idx)
Similar to vector elements, it is not possible to take the address of
a MatrixSubscriptExpr.
For CodeGen, a new MatrixElt type is added to LValue, which is very
similar to VectorElt. The only difference is that we may need to cast
the type of the base from an array to a vector type when accessing it.
Reviewers: rjmccall, anemet, Bigcheese, rsmith, martong
Reviewed By: rjmccall
Differential Revision: https://reviews.llvm.org/D76791
2020-06-01 19:42:03 +01:00
|
|
|
case Expr::MatrixSubscriptExprClass:
|
|
|
|
|
return EmitMatrixSubscriptExpr(cast<MatrixSubscriptExpr>(E));
|
2015-08-31 07:32:19 +00:00
|
|
|
case Expr::OMPArraySectionExprClass:
|
|
|
|
|
return EmitOMPArraySectionExpr(cast<OMPArraySectionExpr>(E));
|
2008-04-18 23:10:10 +00:00
|
|
|
case Expr::ExtVectorElementExprClass:
|
|
|
|
|
return EmitExtVectorElementExpr(cast<ExtVectorElementExpr>(E));
|
2009-09-09 13:00:44 +00:00
|
|
|
case Expr::MemberExprClass:
|
When a member reference expression includes a qualifier on the member
name, e.g.,
x->Base::f()
retain the qualifier (and its source range information) in a new
subclass of MemberExpr called CXXQualifiedMemberExpr. Provide
construction, transformation, profiling, printing, etc., for this new
expression type.
When a virtual function is called via a qualified name, don't emit a
virtual call. Instead, call that function directly. Mike, could you
add a CodeGen test for this, too?
llvm-svn: 80167
2009-08-26 22:36:53 +00:00
|
|
|
return EmitMemberExpr(cast<MemberExpr>(E));
|
2008-05-13 23:18:27 +00:00
|
|
|
case Expr::CompoundLiteralExprClass:
|
|
|
|
|
return EmitCompoundLiteralLValue(cast<CompoundLiteralExpr>(E));
|
2009-03-24 02:38:23 +00:00
|
|
|
case Expr::ConditionalOperatorClass:
|
2009-09-15 16:35:24 +00:00
|
|
|
return EmitConditionalOperatorLValue(cast<ConditionalOperator>(E));
|
2011-02-17 10:25:35 +00:00
|
|
|
case Expr::BinaryConditionalOperatorClass:
|
|
|
|
|
return EmitConditionalOperatorLValue(cast<BinaryConditionalOperator>(E));
|
2008-12-12 05:35:08 +00:00
|
|
|
case Expr::ChooseExprClass:
|
2013-07-20 00:40:58 +00:00
|
|
|
return EmitLValue(cast<ChooseExpr>(E)->getChosenSubExpr());
|
2011-02-16 08:02:54 +00:00
|
|
|
case Expr::OpaqueValueExprClass:
|
|
|
|
|
return EmitOpaqueValueLValue(cast<OpaqueValueExpr>(E));
|
2011-07-15 05:09:51 +00:00
|
|
|
case Expr::SubstNonTypeTemplateParmExprClass:
|
|
|
|
|
return EmitLValue(cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement());
|
2009-03-18 04:02:57 +00:00
|
|
|
case Expr::ImplicitCastExprClass:
|
|
|
|
|
case Expr::CStyleCastExprClass:
|
|
|
|
|
case Expr::CXXFunctionalCastExprClass:
|
|
|
|
|
case Expr::CXXStaticCastExprClass:
|
|
|
|
|
case Expr::CXXDynamicCastExprClass:
|
|
|
|
|
case Expr::CXXReinterpretCastExprClass:
|
|
|
|
|
case Expr::CXXConstCastExprClass:
|
2020-05-18 11:02:01 +01:00
|
|
|
case Expr::CXXAddrspaceCastExprClass:
|
2011-06-15 23:02:42 +00:00
|
|
|
case Expr::ObjCBridgedCastExprClass:
|
2009-03-18 18:28:57 +00:00
|
|
|
return EmitCastLValue(cast<CastExpr>(E));
|
2011-11-27 16:50:07 +00:00
|
|
|
|
2011-06-21 17:03:29 +00:00
|
|
|
case Expr::MaterializeTemporaryExprClass:
|
|
|
|
|
return EmitMaterializeTemporaryExpr(cast<MaterializeTemporaryExpr>(E));
|
2017-06-15 19:43:36 +00:00
|
|
|
|
|
|
|
|
case Expr::CoawaitExprClass:
|
|
|
|
|
return EmitCoawaitLValue(cast<CoawaitExpr>(E));
|
|
|
|
|
case Expr::CoyieldExprClass:
|
|
|
|
|
return EmitCoyieldLValue(cast<CoyieldExpr>(E));
|
2007-06-02 05:24:33 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-10 03:05:10 +00:00
|
|
|
/// Given an object of the given canonical type, can we safely copy a
|
|
|
|
|
/// value out of it based on its initializer?
|
|
|
|
|
static bool isConstantEmittableObjectType(QualType type) {
|
|
|
|
|
assert(type.isCanonical());
|
|
|
|
|
assert(!type->isReferenceType());
|
|
|
|
|
|
|
|
|
|
// Must be const-qualified but non-volatile.
|
|
|
|
|
Qualifiers qs = type.getLocalQualifiers();
|
|
|
|
|
if (!qs.hasConst() || qs.hasVolatile()) return false;
|
|
|
|
|
|
|
|
|
|
// Otherwise, all object types satisfy this except C++ classes with
|
|
|
|
|
// mutable subobjects or non-trivial copy/destroy behavior.
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *RT = dyn_cast<RecordType>(type))
|
|
|
|
|
if (const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
|
2012-03-10 03:05:10 +00:00
|
|
|
if (RD->hasMutableFields() || !RD->isTrivial())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Can we constant-emit a load of a reference to a variable of the
|
|
|
|
|
/// given type? This is different from predicates like
|
2019-06-11 17:50:32 +00:00
|
|
|
/// Decl::mightBeUsableInConstantExpressions because we do want it to apply
|
2012-03-10 03:05:10 +00:00
|
|
|
/// in situations that don't necessarily satisfy the language's rules
|
|
|
|
|
/// for this (e.g. C++'s ODR-use rules). For example, we want to able
|
|
|
|
|
/// to do this with const float variables even if those variables
|
|
|
|
|
/// aren't marked 'constexpr'.
|
|
|
|
|
enum ConstantEmissionKind {
|
|
|
|
|
CEK_None,
|
|
|
|
|
CEK_AsReferenceOnly,
|
|
|
|
|
CEK_AsValueOrReference,
|
|
|
|
|
CEK_AsValueOnly
|
|
|
|
|
};
|
|
|
|
|
static ConstantEmissionKind checkVarTypeForConstantEmission(QualType type) {
|
|
|
|
|
type = type.getCanonicalType();
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *ref = dyn_cast<ReferenceType>(type)) {
|
2012-03-10 03:05:10 +00:00
|
|
|
if (isConstantEmittableObjectType(ref->getPointeeType()))
|
|
|
|
|
return CEK_AsValueOrReference;
|
|
|
|
|
return CEK_AsReferenceOnly;
|
|
|
|
|
}
|
|
|
|
|
if (isConstantEmittableObjectType(type))
|
|
|
|
|
return CEK_AsValueOnly;
|
|
|
|
|
return CEK_None;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Try to emit a reference to the given value without producing it as
|
2019-06-14 17:46:37 +00:00
|
|
|
/// an l-value. This is just an optimization, but it avoids us needing
|
|
|
|
|
/// to emit global copies of variables if they're named without triggering
|
|
|
|
|
/// a formal use in a context where we can't emit a direct reference to them,
|
|
|
|
|
/// for instance if a block or lambda or a member of a local class uses a
|
|
|
|
|
/// const int variable or constexpr variable from an enclosing function.
|
2012-03-10 03:05:10 +00:00
|
|
|
CodeGenFunction::ConstantEmission
|
2012-03-10 09:33:50 +00:00
|
|
|
CodeGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {
|
|
|
|
|
ValueDecl *value = refExpr->getDecl();
|
|
|
|
|
|
2012-03-10 03:05:10 +00:00
|
|
|
// The value needs to be an enum constant or a constant variable.
|
|
|
|
|
ConstantEmissionKind CEK;
|
|
|
|
|
if (isa<ParmVarDecl>(value)) {
|
|
|
|
|
CEK = CEK_None;
|
2014-05-09 00:08:36 +00:00
|
|
|
} else if (auto *var = dyn_cast<VarDecl>(value)) {
|
2012-03-10 03:05:10 +00:00
|
|
|
CEK = checkVarTypeForConstantEmission(var->getType());
|
|
|
|
|
} else if (isa<EnumConstantDecl>(value)) {
|
|
|
|
|
CEK = CEK_AsValueOnly;
|
|
|
|
|
} else {
|
|
|
|
|
CEK = CEK_None;
|
|
|
|
|
}
|
|
|
|
|
if (CEK == CEK_None) return ConstantEmission();
|
|
|
|
|
|
|
|
|
|
Expr::EvalResult result;
|
|
|
|
|
bool resultIsReference;
|
|
|
|
|
QualType resultType;
|
|
|
|
|
|
|
|
|
|
// It's best to evaluate all the way as an r-value if that's permitted.
|
|
|
|
|
if (CEK != CEK_AsReferenceOnly &&
|
2012-03-10 09:33:50 +00:00
|
|
|
refExpr->EvaluateAsRValue(result, getContext())) {
|
2012-03-10 03:05:10 +00:00
|
|
|
resultIsReference = false;
|
|
|
|
|
resultType = refExpr->getType();
|
|
|
|
|
|
|
|
|
|
// Otherwise, try to evaluate as an l-value.
|
|
|
|
|
} else if (CEK != CEK_AsValueOnly &&
|
2012-03-10 09:33:50 +00:00
|
|
|
refExpr->EvaluateAsLValue(result, getContext())) {
|
2012-03-10 03:05:10 +00:00
|
|
|
resultIsReference = true;
|
|
|
|
|
resultType = value->getType();
|
|
|
|
|
|
|
|
|
|
// Failure.
|
|
|
|
|
} else {
|
|
|
|
|
return ConstantEmission();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// In any case, if the initializer has side-effects, abandon ship.
|
|
|
|
|
if (result.HasSideEffects)
|
|
|
|
|
return ConstantEmission();
|
|
|
|
|
|
2020-11-03 15:24:41 -05:00
|
|
|
// In CUDA/HIP device compilation, a lambda may capture a reference variable
|
|
|
|
|
// referencing a global host variable by copy. In this case the lambda should
|
|
|
|
|
// make a copy of the value of the global host variable. The DRE of the
|
|
|
|
|
// captured reference variable cannot be emitted as load from the host
|
|
|
|
|
// global variable as compile time constant, since the host variable is not
|
|
|
|
|
// accessible on device. The DRE of the captured reference variable has to be
|
|
|
|
|
// loaded from captures.
|
2020-12-02 18:35:52 -05:00
|
|
|
if (CGM.getLangOpts().CUDAIsDevice && result.Val.isLValue() &&
|
2020-11-03 15:24:41 -05:00
|
|
|
refExpr->refersToEnclosingVariableOrCapture()) {
|
|
|
|
|
auto *MD = dyn_cast_or_null<CXXMethodDecl>(CurCodeDecl);
|
|
|
|
|
if (MD && MD->getParent()->isLambda() &&
|
|
|
|
|
MD->getOverloadedOperator() == OO_Call) {
|
|
|
|
|
const APValue::LValueBase &base = result.Val.getLValueBase();
|
|
|
|
|
if (const ValueDecl *D = base.dyn_cast<const ValueDecl *>()) {
|
|
|
|
|
if (const VarDecl *VD = dyn_cast<const VarDecl>(D)) {
|
|
|
|
|
if (!VD->hasAttr<CUDADeviceAttr>()) {
|
|
|
|
|
return ConstantEmission();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-10 03:05:10 +00:00
|
|
|
// Emit as a constant.
|
2017-08-15 21:42:52 +00:00
|
|
|
auto C = ConstantEmitter(*this).emitAbstract(refExpr->getLocation(),
|
|
|
|
|
result.Val, resultType);
|
2012-03-10 03:05:10 +00:00
|
|
|
|
2013-08-30 08:53:09 +00:00
|
|
|
// Make sure we emit a debug reference to the global variable.
|
|
|
|
|
// This should probably fire even for
|
|
|
|
|
if (isa<VarDecl>(value)) {
|
|
|
|
|
if (!getContext().DeclMustBeEmitted(cast<VarDecl>(value)))
|
2016-09-13 01:13:19 +00:00
|
|
|
EmitDeclRefExprDbgValue(refExpr, result.Val);
|
2013-08-30 08:53:09 +00:00
|
|
|
} else {
|
|
|
|
|
assert(isa<EnumConstantDecl>(value));
|
2016-09-13 01:13:19 +00:00
|
|
|
EmitDeclRefExprDbgValue(refExpr, result.Val);
|
2013-08-30 08:53:09 +00:00
|
|
|
}
|
2012-03-10 03:05:10 +00:00
|
|
|
|
|
|
|
|
// If we emitted a reference constant, we need to dereference that.
|
|
|
|
|
if (resultIsReference)
|
|
|
|
|
return ConstantEmission::forReference(C);
|
|
|
|
|
|
|
|
|
|
return ConstantEmission::forValue(C);
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-25 10:07:00 +00:00
|
|
|
static DeclRefExpr *tryToConvertMemberExprToDeclRefExpr(CodeGenFunction &CGF,
|
|
|
|
|
const MemberExpr *ME) {
|
|
|
|
|
if (auto *VD = dyn_cast<VarDecl>(ME->getMemberDecl())) {
|
|
|
|
|
// Try to emit static variable member expressions as DREs.
|
|
|
|
|
return DeclRefExpr::Create(
|
|
|
|
|
CGF.getContext(), NestedNameSpecifierLoc(), SourceLocation(), VD,
|
|
|
|
|
/*RefersToEnclosingVariableOrCapture=*/false, ME->getExprLoc(),
|
2019-06-11 17:50:36 +00:00
|
|
|
ME->getType(), ME->getValueKind(), nullptr, nullptr, ME->isNonOdrUse());
|
2017-08-25 10:07:00 +00:00
|
|
|
}
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CodeGenFunction::ConstantEmission
|
|
|
|
|
CodeGenFunction::tryEmitAsConstant(const MemberExpr *ME) {
|
|
|
|
|
if (DeclRefExpr *DRE = tryToConvertMemberExprToDeclRefExpr(*this, ME))
|
|
|
|
|
return tryEmitAsConstant(DRE);
|
|
|
|
|
return ConstantEmission();
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-01 21:57:05 +00:00
|
|
|
llvm::Value *CodeGenFunction::emitScalarConstant(
|
|
|
|
|
const CodeGenFunction::ConstantEmission &Constant, Expr *E) {
|
|
|
|
|
assert(Constant && "not a constant");
|
|
|
|
|
if (Constant.isReference())
|
|
|
|
|
return EmitLoadOfLValue(Constant.getReferenceLValue(*this, E),
|
|
|
|
|
E->getExprLoc())
|
|
|
|
|
.getScalarVal();
|
|
|
|
|
return Constant.getValue();
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-02 02:29:49 +00:00
|
|
|
llvm::Value *CodeGenFunction::EmitLoadOfScalar(LValue lvalue,
|
|
|
|
|
SourceLocation Loc) {
|
2019-12-03 15:17:01 -08:00
|
|
|
return EmitLoadOfScalar(lvalue.getAddress(*this), lvalue.isVolatile(),
|
2017-05-18 17:07:11 +00:00
|
|
|
lvalue.getType(), Loc, lvalue.getBaseInfo(),
|
2017-10-03 10:52:39 +00:00
|
|
|
lvalue.getTBAAInfo(), lvalue.isNontemporal());
|
2011-06-16 04:16:24 +00:00
|
|
|
}
|
|
|
|
|
|
2012-03-24 16:50:34 +00:00
|
|
|
static bool hasBooleanRepresentation(QualType Ty) {
|
|
|
|
|
if (Ty->isBooleanType())
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (const EnumType *ET = Ty->getAs<EnumType>())
|
|
|
|
|
return ET->getDecl()->getIntegerType()->isBooleanType();
|
|
|
|
|
|
2012-04-12 20:42:30 +00:00
|
|
|
if (const AtomicType *AT = Ty->getAs<AtomicType>())
|
|
|
|
|
return hasBooleanRepresentation(AT->getValueType());
|
|
|
|
|
|
2012-03-24 16:50:34 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-13 07:11:50 +00:00
|
|
|
static bool getRangeForType(CodeGenFunction &CGF, QualType Ty,
|
|
|
|
|
llvm::APInt &Min, llvm::APInt &End,
|
2016-12-09 23:48:18 +00:00
|
|
|
bool StrictEnums, bool IsBool) {
|
2012-03-24 16:50:34 +00:00
|
|
|
const EnumType *ET = Ty->getAs<EnumType>();
|
2012-12-13 07:11:50 +00:00
|
|
|
bool IsRegularCPlusPlusEnum = CGF.getLangOpts().CPlusPlus && StrictEnums &&
|
|
|
|
|
ET && !ET->getDecl()->isFixed();
|
2012-03-24 16:50:34 +00:00
|
|
|
if (!IsBool && !IsRegularCPlusPlusEnum)
|
2012-12-13 07:11:50 +00:00
|
|
|
return false;
|
2012-03-24 16:50:34 +00:00
|
|
|
|
|
|
|
|
if (IsBool) {
|
2012-12-13 07:11:50 +00:00
|
|
|
Min = llvm::APInt(CGF.getContext().getTypeSize(Ty), 0);
|
|
|
|
|
End = llvm::APInt(CGF.getContext().getTypeSize(Ty), 2);
|
2012-03-24 16:50:34 +00:00
|
|
|
} else {
|
|
|
|
|
const EnumDecl *ED = ET->getDecl();
|
2012-12-13 07:11:50 +00:00
|
|
|
llvm::Type *LTy = CGF.ConvertTypeForMem(ED->getIntegerType());
|
2012-03-24 16:50:34 +00:00
|
|
|
unsigned Bitwidth = LTy->getScalarSizeInBits();
|
|
|
|
|
unsigned NumNegativeBits = ED->getNumNegativeBits();
|
|
|
|
|
unsigned NumPositiveBits = ED->getNumPositiveBits();
|
|
|
|
|
|
|
|
|
|
if (NumNegativeBits) {
|
|
|
|
|
unsigned NumBits = std::max(NumNegativeBits, NumPositiveBits + 1);
|
|
|
|
|
assert(NumBits <= Bitwidth);
|
|
|
|
|
End = llvm::APInt(Bitwidth, 1) << (NumBits - 1);
|
|
|
|
|
Min = -End;
|
|
|
|
|
} else {
|
|
|
|
|
assert(NumPositiveBits <= Bitwidth);
|
|
|
|
|
End = llvm::APInt(Bitwidth, 1) << NumPositiveBits;
|
|
|
|
|
Min = llvm::APInt(Bitwidth, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-12-13 07:11:50 +00:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {
|
|
|
|
|
llvm::APInt Min, End;
|
2016-12-09 23:48:18 +00:00
|
|
|
if (!getRangeForType(*this, Ty, Min, End, CGM.getCodeGenOpts().StrictEnums,
|
|
|
|
|
hasBooleanRepresentation(Ty)))
|
2014-05-21 05:09:00 +00:00
|
|
|
return nullptr;
|
2012-03-24 16:50:34 +00:00
|
|
|
|
2012-04-15 18:04:54 +00:00
|
|
|
llvm::MDBuilder MDHelper(getLLVMContext());
|
2012-04-16 16:29:47 +00:00
|
|
|
return MDHelper.createRange(Min, End);
|
2012-03-24 16:50:34 +00:00
|
|
|
}
|
|
|
|
|
|
2017-02-27 19:46:19 +00:00
|
|
|
bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
|
|
|
|
|
SourceLocation Loc) {
|
|
|
|
|
bool HasBoolCheck = SanOpts.has(SanitizerKind::Bool);
|
|
|
|
|
bool HasEnumCheck = SanOpts.has(SanitizerKind::Enum);
|
|
|
|
|
if (!HasBoolCheck && !HasEnumCheck)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
bool IsBool = hasBooleanRepresentation(Ty) ||
|
|
|
|
|
NSAPI(CGM.getContext()).isObjCBOOLType(Ty);
|
|
|
|
|
bool NeedsBoolCheck = HasBoolCheck && IsBool;
|
|
|
|
|
bool NeedsEnumCheck = HasEnumCheck && Ty->getAs<EnumType>();
|
|
|
|
|
if (!NeedsBoolCheck && !NeedsEnumCheck)
|
|
|
|
|
return false;
|
|
|
|
|
|
2017-03-09 16:06:27 +00:00
|
|
|
// Single-bit booleans don't need to be checked. Special-case this to avoid
|
|
|
|
|
// a bit width mismatch when handling bitfield values. This is handled by
|
|
|
|
|
// EmitFromMemory for the non-bitfield case.
|
|
|
|
|
if (IsBool &&
|
|
|
|
|
cast<llvm::IntegerType>(Value->getType())->getBitWidth() == 1)
|
|
|
|
|
return false;
|
|
|
|
|
|
2017-02-27 19:46:19 +00:00
|
|
|
llvm::APInt Min, End;
|
|
|
|
|
if (!getRangeForType(*this, Ty, Min, End, /*StrictEnums=*/true, IsBool))
|
|
|
|
|
return true;
|
|
|
|
|
|
2017-10-03 01:27:26 +00:00
|
|
|
auto &Ctx = getLLVMContext();
|
2017-02-27 19:46:19 +00:00
|
|
|
SanitizerScope SanScope(this);
|
|
|
|
|
llvm::Value *Check;
|
|
|
|
|
--End;
|
|
|
|
|
if (!Min) {
|
2017-10-03 01:27:26 +00:00
|
|
|
Check = Builder.CreateICmpULE(Value, llvm::ConstantInt::get(Ctx, End));
|
2017-02-27 19:46:19 +00:00
|
|
|
} else {
|
2017-10-03 01:27:26 +00:00
|
|
|
llvm::Value *Upper =
|
|
|
|
|
Builder.CreateICmpSLE(Value, llvm::ConstantInt::get(Ctx, End));
|
|
|
|
|
llvm::Value *Lower =
|
|
|
|
|
Builder.CreateICmpSGE(Value, llvm::ConstantInt::get(Ctx, Min));
|
2017-02-27 19:46:19 +00:00
|
|
|
Check = Builder.CreateAnd(Upper, Lower);
|
|
|
|
|
}
|
|
|
|
|
llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc),
|
|
|
|
|
EmitCheckTypeDescriptor(Ty)};
|
|
|
|
|
SanitizerMask Kind =
|
|
|
|
|
NeedsEnumCheck ? SanitizerKind::Enum : SanitizerKind::Bool;
|
|
|
|
|
EmitCheck(std::make_pair(Check, Kind), SanitizerHandler::LoadInvalidValue,
|
|
|
|
|
StaticArgs, EmitCheckValue(Value));
|
|
|
|
|
return 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 08:05:57 +00:00
|
|
|
llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
|
|
|
|
|
QualType Ty,
|
2013-10-02 02:29:49 +00:00
|
|
|
SourceLocation Loc,
|
2017-05-18 17:07:11 +00:00
|
|
|
LValueBaseInfo BaseInfo,
|
2017-10-03 10:52:39 +00:00
|
|
|
TBAAAccessInfo TBAAInfo,
|
2015-09-08 23:52:33 +00:00
|
|
|
bool isNontemporal) {
|
2017-04-04 16:40:25 +00:00
|
|
|
if (!CGM.getCodeGenOpts().PreserveVec3Type) {
|
|
|
|
|
// For better performance, handle vector loads differently.
|
|
|
|
|
if (Ty->isVectorType()) {
|
|
|
|
|
const llvm::Type *EltTy = Addr.getElementType();
|
|
|
|
|
|
2020-08-26 10:06:28 -07:00
|
|
|
const auto *VTy = cast<llvm::FixedVectorType>(EltTy);
|
2017-04-04 16:40:25 +00:00
|
|
|
|
|
|
|
|
// Handle vectors of size 3 like size 4 for better performance.
|
|
|
|
|
if (VTy->getNumElements() == 3) {
|
|
|
|
|
|
|
|
|
|
// Bitcast to vec4 type.
|
2020-06-01 09:55:24 -07:00
|
|
|
auto *vec4Ty = llvm::FixedVectorType::get(VTy->getElementType(), 4);
|
2017-04-04 16:40:25 +00:00
|
|
|
Address Cast = Builder.CreateElementBitCast(Addr, vec4Ty, "castToVec4");
|
|
|
|
|
// Now load value.
|
|
|
|
|
llvm::Value *V = Builder.CreateLoad(Cast, Volatile, "loadVec4");
|
|
|
|
|
|
|
|
|
|
// Shuffle vector to get vec3.
|
2020-12-30 07:28:17 +09:00
|
|
|
V = Builder.CreateShuffleVector(V, ArrayRef<int>{0, 1, 2},
|
|
|
|
|
"extractVec");
|
2017-04-04 16:40:25 +00:00
|
|
|
return EmitFromMemory(V, Ty);
|
|
|
|
|
}
|
2012-08-16 00:10:13 +00:00
|
|
|
}
|
|
|
|
|
}
|
2013-03-07 21:37:17 +00:00
|
|
|
|
|
|
|
|
// Atomic operations have to be done on integral types.
|
2016-05-24 16:09:25 +00:00
|
|
|
LValue AtomicLValue =
|
2017-10-06 08:17:48 +00:00
|
|
|
LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo, TBAAInfo);
|
2016-05-24 16:09:25 +00:00
|
|
|
if (Ty->isAtomicType() || LValueIsSuitableForInlineAtomic(AtomicLValue)) {
|
|
|
|
|
return EmitAtomicLoad(AtomicLValue, Loc).getScalarVal();
|
2013-03-07 21:37:17 +00:00
|
|
|
}
|
2013-07-26 05:59:26 +00: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 08:05:57 +00:00
|
|
|
llvm::LoadInst *Load = Builder.CreateLoad(Addr, Volatile);
|
2015-09-08 23:52:33 +00:00
|
|
|
if (isNontemporal) {
|
|
|
|
|
llvm::MDNode *Node = llvm::MDNode::get(
|
|
|
|
|
Load->getContext(), llvm::ConstantAsMetadata::get(Builder.getInt32(1)));
|
|
|
|
|
Load->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node);
|
|
|
|
|
}
|
2017-10-06 08:17:48 +00:00
|
|
|
|
|
|
|
|
CGM.DecorateInstructionWithTBAA(Load, TBAAInfo);
|
2009-02-10 00:57:50 +00:00
|
|
|
|
2017-02-27 19:46:19 +00:00
|
|
|
if (EmitScalarRangeCheck(Load, Ty, Loc)) {
|
|
|
|
|
// In order to prevent the optimizer from throwing away the check, don't
|
|
|
|
|
// attach range metadata to the load.
|
2012-12-13 07:11:50 +00:00
|
|
|
} else if (CGM.getCodeGenOpts().OptimizationLevel > 0)
|
2012-03-24 16:50:34 +00:00
|
|
|
if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty))
|
|
|
|
|
Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo);
|
2010-10-08 23:50:27 +00:00
|
|
|
|
2012-03-24 16:50:34 +00:00
|
|
|
return EmitFromMemory(Load, Ty);
|
2012-03-24 14:43:42 +00:00
|
|
|
}
|
|
|
|
|
|
2010-10-27 20:58:56 +00:00
|
|
|
llvm::Value *CodeGenFunction::EmitToMemory(llvm::Value *Value, QualType Ty) {
|
|
|
|
|
// Bool has a different representation in memory than in registers.
|
2012-03-24 16:50:34 +00:00
|
|
|
if (hasBooleanRepresentation(Ty)) {
|
2010-10-27 20:58:56 +00:00
|
|
|
// This should really always be an i1, but sometimes it's already
|
|
|
|
|
// an i8, and it's awkward to track those cases down.
|
|
|
|
|
if (Value->getType()->isIntegerTy(1))
|
2012-11-13 02:05:15 +00:00
|
|
|
return Builder.CreateZExt(Value, ConvertTypeForMem(Ty), "frombool");
|
|
|
|
|
assert(Value->getType()->isIntegerTy(getContext().getTypeSize(Ty)) &&
|
|
|
|
|
"wrong value rep of bool");
|
2010-10-27 20:58:56 +00:00
|
|
|
}
|
2010-10-27 17:13:49 +00:00
|
|
|
|
2010-10-27 20:58:56 +00:00
|
|
|
return Value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llvm::Value *CodeGenFunction::EmitFromMemory(llvm::Value *Value, QualType Ty) {
|
|
|
|
|
// Bool has a different representation in memory than in registers.
|
2012-03-24 16:50:34 +00:00
|
|
|
if (hasBooleanRepresentation(Ty)) {
|
2012-11-13 02:05:15 +00:00
|
|
|
assert(Value->getType()->isIntegerTy(getContext().getTypeSize(Ty)) &&
|
|
|
|
|
"wrong value rep of bool");
|
2010-10-27 20:58:56 +00:00
|
|
|
return Builder.CreateTrunc(Value, Builder.getInt1Ty(), "tobool");
|
2010-10-27 17:13:49 +00:00
|
|
|
}
|
|
|
|
|
|
2010-10-27 20:58:56 +00:00
|
|
|
return Value;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-11 17:45:51 +01:00
|
|
|
// Convert the pointer of \p Addr to a pointer to a vector (the value type of
|
|
|
|
|
// MatrixType), if it points to a array (the memory type of MatrixType).
|
|
|
|
|
static Address MaybeConvertMatrixAddress(Address Addr, CodeGenFunction &CGF,
|
|
|
|
|
bool IsVector = true) {
|
|
|
|
|
auto *ArrayTy = dyn_cast<llvm::ArrayType>(
|
|
|
|
|
cast<llvm::PointerType>(Addr.getPointer()->getType())->getElementType());
|
|
|
|
|
if (ArrayTy && IsVector) {
|
2020-06-01 09:55:24 -07:00
|
|
|
auto *VectorTy = llvm::FixedVectorType::get(ArrayTy->getElementType(),
|
|
|
|
|
ArrayTy->getNumElements());
|
2020-05-11 17:45:51 +01:00
|
|
|
|
|
|
|
|
return Address(CGF.Builder.CreateElementBitCast(Addr, VectorTy));
|
|
|
|
|
}
|
|
|
|
|
auto *VectorTy = dyn_cast<llvm::VectorType>(
|
|
|
|
|
cast<llvm::PointerType>(Addr.getPointer()->getType())->getElementType());
|
|
|
|
|
if (VectorTy && !IsVector) {
|
2020-08-26 10:06:28 -07:00
|
|
|
auto *ArrayTy = llvm::ArrayType::get(
|
|
|
|
|
VectorTy->getElementType(),
|
|
|
|
|
cast<llvm::FixedVectorType>(VectorTy)->getNumElements());
|
2020-05-11 17:45:51 +01:00
|
|
|
|
|
|
|
|
return Address(CGF.Builder.CreateElementBitCast(Addr, ArrayTy));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Addr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Emit a store of a matrix LValue. This may require casting the original
|
|
|
|
|
// pointer to memory address (ArrayType) to a pointer to the value type
|
|
|
|
|
// (VectorType).
|
|
|
|
|
static void EmitStoreOfMatrixScalar(llvm::Value *value, LValue lvalue,
|
|
|
|
|
bool isInit, CodeGenFunction &CGF) {
|
|
|
|
|
Address Addr = MaybeConvertMatrixAddress(lvalue.getAddress(CGF), CGF,
|
|
|
|
|
value->getType()->isVectorTy());
|
|
|
|
|
CGF.EmitStoreOfScalar(value, Addr, lvalue.isVolatile(), lvalue.getType(),
|
|
|
|
|
lvalue.getBaseInfo(), lvalue.getTBAAInfo(), isInit,
|
|
|
|
|
lvalue.isNontemporal());
|
|
|
|
|
}
|
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
|
|
|
|
|
bool Volatile, QualType Ty,
|
2017-05-18 17:07:11 +00:00
|
|
|
LValueBaseInfo BaseInfo,
|
2017-10-03 10:52:39 +00:00
|
|
|
TBAAAccessInfo TBAAInfo,
|
|
|
|
|
bool isInit, bool isNontemporal) {
|
2017-04-04 16:40:25 +00:00
|
|
|
if (!CGM.getCodeGenOpts().PreserveVec3Type) {
|
|
|
|
|
// Handle vectors differently to get better performance.
|
|
|
|
|
if (Ty->isVectorType()) {
|
|
|
|
|
llvm::Type *SrcTy = Value->getType();
|
2017-06-01 20:13:34 +00:00
|
|
|
auto *VecTy = dyn_cast<llvm::VectorType>(SrcTy);
|
2017-04-04 16:40:25 +00:00
|
|
|
// Handle vec3 special.
|
2020-08-26 10:06:28 -07:00
|
|
|
if (VecTy && cast<llvm::FixedVectorType>(VecTy)->getNumElements() == 3) {
|
2017-04-04 16:40:25 +00:00
|
|
|
// Our source is a vec3, do a shuffle vector to make it a vec4.
|
2020-12-30 07:28:17 +09:00
|
|
|
Value = Builder.CreateShuffleVector(Value, ArrayRef<int>{0, 1, 2, -1},
|
2020-04-15 12:41:54 +02:00
|
|
|
"extractVec");
|
2020-06-01 09:55:24 -07:00
|
|
|
SrcTy = llvm::FixedVectorType::get(VecTy->getElementType(), 4);
|
2017-04-04 16:40:25 +00:00
|
|
|
}
|
|
|
|
|
if (Addr.getElementType() != SrcTy) {
|
|
|
|
|
Addr = Builder.CreateElementBitCast(Addr, SrcTy, "storetmp");
|
|
|
|
|
}
|
2012-08-16 00:10:13 +00:00
|
|
|
}
|
|
|
|
|
}
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2010-10-27 20:58:56 +00:00
|
|
|
Value = EmitToMemory(Value, Ty);
|
2013-03-07 21:37:08 +00:00
|
|
|
|
2016-05-24 16:09:25 +00:00
|
|
|
LValue AtomicLValue =
|
2017-10-06 08:17:48 +00:00
|
|
|
LValue::MakeAddr(Addr, Ty, getContext(), BaseInfo, TBAAInfo);
|
2015-02-14 01:35:12 +00:00
|
|
|
if (Ty->isAtomicType() ||
|
2016-05-24 16:09:25 +00:00
|
|
|
(!isInit && LValueIsSuitableForInlineAtomic(AtomicLValue))) {
|
|
|
|
|
EmitAtomicStore(RValue::get(Value), AtomicLValue, isInit);
|
2013-03-07 21:37:17 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2010-08-21 02:24:36 +00:00
|
|
|
llvm::StoreInst *Store = Builder.CreateStore(Value, Addr, Volatile);
|
2015-09-08 23:52:33 +00:00
|
|
|
if (isNontemporal) {
|
|
|
|
|
llvm::MDNode *Node =
|
|
|
|
|
llvm::MDNode::get(Store->getContext(),
|
|
|
|
|
llvm::ConstantAsMetadata::get(Builder.getInt32(1)));
|
|
|
|
|
Store->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node);
|
|
|
|
|
}
|
2017-10-06 08:17:48 +00:00
|
|
|
|
|
|
|
|
CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
|
2009-02-10 00:57:50 +00:00
|
|
|
}
|
|
|
|
|
|
2012-01-16 17:27:18 +00:00
|
|
|
void CodeGenFunction::EmitStoreOfScalar(llvm::Value *value, LValue lvalue,
|
2013-03-07 21:37:08 +00:00
|
|
|
bool isInit) {
|
2020-05-11 17:45:51 +01:00
|
|
|
if (lvalue.getType()->isConstantMatrixType()) {
|
|
|
|
|
EmitStoreOfMatrixScalar(value, lvalue, isInit, *this);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-03 15:17:01 -08:00
|
|
|
EmitStoreOfScalar(value, lvalue.getAddress(*this), lvalue.isVolatile(),
|
2017-05-18 17:07:11 +00:00
|
|
|
lvalue.getType(), lvalue.getBaseInfo(),
|
2017-10-03 10:52:39 +00:00
|
|
|
lvalue.getTBAAInfo(), isInit, lvalue.isNontemporal());
|
2011-06-16 04:16:24 +00:00
|
|
|
}
|
|
|
|
|
|
2020-05-11 17:45:51 +01:00
|
|
|
// Emit a load of a LValue of matrix type. This may require casting the pointer
|
|
|
|
|
// to memory address (ArrayType) to a pointer to the value type (VectorType).
|
|
|
|
|
static RValue EmitLoadOfMatrixLValue(LValue LV, SourceLocation Loc,
|
|
|
|
|
CodeGenFunction &CGF) {
|
|
|
|
|
assert(LV.getType()->isConstantMatrixType());
|
|
|
|
|
Address Addr = MaybeConvertMatrixAddress(LV.getAddress(CGF), CGF);
|
|
|
|
|
LV.setAddress(Addr);
|
|
|
|
|
return RValue::get(CGF.EmitLoadOfScalar(LV, Loc));
|
|
|
|
|
}
|
|
|
|
|
|
2009-09-09 13:00:44 +00:00
|
|
|
/// EmitLoadOfLValue - Given an expression that represents a value lvalue, this
|
|
|
|
|
/// method emits the address of the lvalue, then loads the result as an rvalue,
|
|
|
|
|
/// returning the rvalue.
|
2013-10-02 02:29:49 +00:00
|
|
|
RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
|
2008-11-19 17:34:06 +00:00
|
|
|
if (LV.isObjCWeak()) {
|
2009-09-09 13:00:44 +00:00
|
|
|
// load of a __weak object.
|
2019-12-03 15:17:01 -08:00
|
|
|
Address AddrWeakObj = LV.getAddress(*this);
|
2009-10-28 17:39:19 +00:00
|
|
|
return RValue::get(CGM.getObjCRuntime().EmitObjCWeakRead(*this,
|
|
|
|
|
AddrWeakObj));
|
2008-11-18 21:45:40 +00:00
|
|
|
}
|
2012-11-27 23:02:53 +00:00
|
|
|
if (LV.getQuals().getObjCLifetime() == Qualifiers::OCL_Weak) {
|
Define weak and __weak to mean ARC-style weak references, even in MRC.
Previously, __weak was silently accepted and ignored in MRC mode.
That makes this a potentially source-breaking change that we have to
roll out cautiously. Accordingly, for the time being, actual support
for __weak references in MRC is experimental, and the compiler will
reject attempts to actually form such references. The intent is to
eventually enable the feature by default in all non-GC modes.
(It is, of course, incompatible with ObjC GC's interpretation of
__weak.)
If you like, you can enable this feature with
-Xclang -fobjc-weak
but like any -Xclang option, this option may be removed at any point,
e.g. if/when it is eventually enabled by default.
This patch also enables the use of the ARC __unsafe_unretained qualifier
in MRC. Unlike __weak, this is being enabled immediately. Since
variables are essentially __unsafe_unretained by default in MRC,
the only practical uses are (1) communication and (2) changing the
default behavior of by-value block capture.
As an implementation matter, this means that the ObjC ownership
qualifiers may appear in any ObjC language mode, and so this patch
removes a number of checks for getLangOpts().ObjCAutoRefCount
that were guarding the processing of these qualifiers. I don't
expect this to be a significant drain on performance; it may even
be faster to just check for these qualifiers directly on a type
(since it's probably in a register anyway) than to do N dependent
loads to grab the LangOptions.
rdar://9674298
llvm-svn: 251041
2015-10-22 18:38:17 +00:00
|
|
|
// In MRC mode, we do a load+autorelease.
|
|
|
|
|
if (!getLangOpts().ObjCAutoRefCount) {
|
2019-12-03 15:17:01 -08:00
|
|
|
return RValue::get(EmitARCLoadWeak(LV.getAddress(*this)));
|
Define weak and __weak to mean ARC-style weak references, even in MRC.
Previously, __weak was silently accepted and ignored in MRC mode.
That makes this a potentially source-breaking change that we have to
roll out cautiously. Accordingly, for the time being, actual support
for __weak references in MRC is experimental, and the compiler will
reject attempts to actually form such references. The intent is to
eventually enable the feature by default in all non-GC modes.
(It is, of course, incompatible with ObjC GC's interpretation of
__weak.)
If you like, you can enable this feature with
-Xclang -fobjc-weak
but like any -Xclang option, this option may be removed at any point,
e.g. if/when it is eventually enabled by default.
This patch also enables the use of the ARC __unsafe_unretained qualifier
in MRC. Unlike __weak, this is being enabled immediately. Since
variables are essentially __unsafe_unretained by default in MRC,
the only practical uses are (1) communication and (2) changing the
default behavior of by-value block capture.
As an implementation matter, this means that the ObjC ownership
qualifiers may appear in any ObjC language mode, and so this patch
removes a number of checks for getLangOpts().ObjCAutoRefCount
that were guarding the processing of these qualifiers. I don't
expect this to be a significant drain on performance; it may even
be faster to just check for these qualifiers directly on a type
(since it's probably in a register anyway) than to do N dependent
loads to grab the LangOptions.
rdar://9674298
llvm-svn: 251041
2015-10-22 18:38:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// In ARC mode, we load retained and then consume the value.
|
2019-12-03 15:17:01 -08:00
|
|
|
llvm::Value *Object = EmitARCLoadWeakRetained(LV.getAddress(*this));
|
2012-11-27 23:02:53 +00:00
|
|
|
Object = EmitObjCConsumeObject(LV.getType(), Object);
|
|
|
|
|
return RValue::get(Object);
|
|
|
|
|
}
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2007-07-10 21:17:59 +00:00
|
|
|
if (LV.isSimple()) {
|
2011-06-27 21:24:11 +00:00
|
|
|
assert(!LV.getType()->isFunctionType());
|
2010-08-22 10:59:02 +00:00
|
|
|
|
2020-05-11 17:45:51 +01:00
|
|
|
if (LV.getType()->isConstantMatrixType())
|
|
|
|
|
return EmitLoadOfMatrixLValue(LV, Loc, *this);
|
|
|
|
|
|
2010-08-22 10:59:02 +00:00
|
|
|
// Everything needs a load.
|
2013-10-02 02:29:49 +00:00
|
|
|
return RValue::get(EmitLoadOfScalar(LV, Loc));
|
2007-07-10 21:17:59 +00:00
|
|
|
}
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2007-07-10 21:17:59 +00:00
|
|
|
if (LV.isVectorElt()) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
llvm::LoadInst *Load = Builder.CreateLoad(LV.getVectorAddress(),
|
2012-03-22 22:36:39 +00:00
|
|
|
LV.isVolatileQualified());
|
|
|
|
|
return RValue::get(Builder.CreateExtractElement(Load, LV.getVectorIdx(),
|
2007-07-10 21:17:59 +00:00
|
|
|
"vecext"));
|
|
|
|
|
}
|
implement lvalue to rvalue conversion for ocuvector components. We can now compile stuff
like this:
typedef __attribute__(( ocu_vector_type(4) )) float float4;
float4 test1(float4 V) {
return V.wzyx+V;
}
to:
_test1:
pshufd $27, %xmm0, %xmm1
addps %xmm0, %xmm1
movaps %xmm1, %xmm0
ret
and:
_test1:
mfspr r2, 256
oris r3, r2, 4096
mtspr 256, r3
li r3, lo16(LCPI1_0)
lis r4, ha16(LCPI1_0)
lvx v3, r4, r3
vperm v3, v2, v2, v3
vaddfp v2, v3, v2
mtspr 256, r2
blr
llvm-svn: 40771
2007-08-03 00:16:29 +00:00
|
|
|
|
|
|
|
|
// If this is a reference to a subset of the elements of a vector, either
|
|
|
|
|
// shuffle the input or extract/insert them as appropriate.
|
[Matrix] Implement matrix index expressions ([][]).
This patch implements matrix index expressions
(matrix[RowIdx][ColumnIdx]).
It does so by introducing a new MatrixSubscriptExpr(Base, RowIdx, ColumnIdx).
MatrixSubscriptExprs are built in 2 steps in ActOnMatrixSubscriptExpr. First,
if the base of a subscript is of matrix type, we create a incomplete
MatrixSubscriptExpr(base, idx, nullptr). Second, if the base is an incomplete
MatrixSubscriptExpr, we create a complete
MatrixSubscriptExpr(base->getBase(), base->getRowIdx(), idx)
Similar to vector elements, it is not possible to take the address of
a MatrixSubscriptExpr.
For CodeGen, a new MatrixElt type is added to LValue, which is very
similar to VectorElt. The only difference is that we may need to cast
the type of the base from an array to a vector type when accessing it.
Reviewers: rjmccall, anemet, Bigcheese, rsmith, martong
Reviewed By: rjmccall
Differential Revision: https://reviews.llvm.org/D76791
2020-06-01 19:42:03 +01:00
|
|
|
if (LV.isExtVectorElt()) {
|
2011-06-25 02:11:03 +00:00
|
|
|
return EmitLoadOfExtVectorElementLValue(LV);
|
[Matrix] Implement matrix index expressions ([][]).
This patch implements matrix index expressions
(matrix[RowIdx][ColumnIdx]).
It does so by introducing a new MatrixSubscriptExpr(Base, RowIdx, ColumnIdx).
MatrixSubscriptExprs are built in 2 steps in ActOnMatrixSubscriptExpr. First,
if the base of a subscript is of matrix type, we create a incomplete
MatrixSubscriptExpr(base, idx, nullptr). Second, if the base is an incomplete
MatrixSubscriptExpr, we create a complete
MatrixSubscriptExpr(base->getBase(), base->getRowIdx(), idx)
Similar to vector elements, it is not possible to take the address of
a MatrixSubscriptExpr.
For CodeGen, a new MatrixElt type is added to LValue, which is very
similar to VectorElt. The only difference is that we may need to cast
the type of the base from an array to a vector type when accessing it.
Reviewers: rjmccall, anemet, Bigcheese, rsmith, martong
Reviewed By: rjmccall
Differential Revision: https://reviews.llvm.org/D76791
2020-06-01 19:42:03 +01:00
|
|
|
}
|
2008-01-22 20:17:04 +00:00
|
|
|
|
2014-05-19 18:15:42 +00:00
|
|
|
// Global Register variables always invoke intrinsics
|
|
|
|
|
if (LV.isGlobalReg())
|
|
|
|
|
return EmitLoadOfGlobalRegLValue(LV);
|
|
|
|
|
|
[Matrix] Implement matrix index expressions ([][]).
This patch implements matrix index expressions
(matrix[RowIdx][ColumnIdx]).
It does so by introducing a new MatrixSubscriptExpr(Base, RowIdx, ColumnIdx).
MatrixSubscriptExprs are built in 2 steps in ActOnMatrixSubscriptExpr. First,
if the base of a subscript is of matrix type, we create a incomplete
MatrixSubscriptExpr(base, idx, nullptr). Second, if the base is an incomplete
MatrixSubscriptExpr, we create a complete
MatrixSubscriptExpr(base->getBase(), base->getRowIdx(), idx)
Similar to vector elements, it is not possible to take the address of
a MatrixSubscriptExpr.
For CodeGen, a new MatrixElt type is added to LValue, which is very
similar to VectorElt. The only difference is that we may need to cast
the type of the base from an array to a vector type when accessing it.
Reviewers: rjmccall, anemet, Bigcheese, rsmith, martong
Reviewed By: rjmccall
Differential Revision: https://reviews.llvm.org/D76791
2020-06-01 19:42:03 +01:00
|
|
|
if (LV.isMatrixElt()) {
|
|
|
|
|
llvm::LoadInst *Load =
|
|
|
|
|
Builder.CreateLoad(LV.getMatrixAddress(), LV.isVolatileQualified());
|
|
|
|
|
return RValue::get(
|
|
|
|
|
Builder.CreateExtractElement(Load, LV.getMatrixIdx(), "matrixext"));
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-07 03:59:57 +00:00
|
|
|
assert(LV.isBitField() && "Unknown LValue type!");
|
2017-03-09 16:06:27 +00:00
|
|
|
return EmitLoadOfBitfieldLValue(LV, Loc);
|
2007-08-03 16:18:34 +00:00
|
|
|
}
|
2007-08-03 15:52:31 +00:00
|
|
|
|
2017-03-09 16:06:27 +00:00
|
|
|
RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,
|
|
|
|
|
SourceLocation Loc) {
|
2010-04-06 01:07:44 +00:00
|
|
|
const CGBitFieldInfo &Info = LV.getBitFieldInfo();
|
2008-01-22 20:17:04 +00:00
|
|
|
|
2010-04-13 23:34:15 +00:00
|
|
|
// Get the output type.
|
2011-07-18 04:24:23 +00:00
|
|
|
llvm::Type *ResLTy = ConvertType(LV.getType());
|
2010-04-13 23:34:15 +00: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 08:05:57 +00:00
|
|
|
Address Ptr = LV.getBitFieldAddress();
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
llvm::Value *Val =
|
|
|
|
|
Builder.CreateLoad(Ptr, LV.isVolatileQualified(), "bf.load");
|
|
|
|
|
|
|
|
|
|
bool UseVolatile = LV.isVolatileQualified() &&
|
|
|
|
|
Info.VolatileStorageSize != 0 && isAAPCS(CGM.getTarget());
|
|
|
|
|
const unsigned Offset = UseVolatile ? Info.VolatileOffset : Info.Offset;
|
|
|
|
|
const unsigned StorageSize =
|
|
|
|
|
UseVolatile ? Info.VolatileStorageSize : Info.StorageSize;
|
2012-12-06 11:14:44 +00:00
|
|
|
if (Info.IsSigned) {
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
assert(static_cast<unsigned>(Offset + Info.Size) <= StorageSize);
|
|
|
|
|
unsigned HighBits = StorageSize - Offset - Info.Size;
|
2012-12-06 11:14:44 +00:00
|
|
|
if (HighBits)
|
|
|
|
|
Val = Builder.CreateShl(Val, HighBits, "bf.shl");
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
if (Offset + HighBits)
|
|
|
|
|
Val = Builder.CreateAShr(Val, Offset + HighBits, "bf.ashr");
|
2012-12-06 11:14:44 +00:00
|
|
|
} else {
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
if (Offset)
|
|
|
|
|
Val = Builder.CreateLShr(Val, Offset, "bf.lshr");
|
|
|
|
|
if (static_cast<unsigned>(Offset) + Info.Size < StorageSize)
|
|
|
|
|
Val = Builder.CreateAnd(
|
|
|
|
|
Val, llvm::APInt::getLowBitsSet(StorageSize, Info.Size), "bf.clear");
|
2010-04-13 23:34:15 +00:00
|
|
|
}
|
2012-12-06 11:14:44 +00:00
|
|
|
Val = Builder.CreateIntCast(Val, ResLTy, Info.IsSigned, "bf.cast");
|
2017-03-09 16:06:27 +00:00
|
|
|
EmitScalarRangeCheck(Val, LV.getType(), Loc);
|
2012-12-06 11:14:44 +00:00
|
|
|
return RValue::get(Val);
|
2008-01-22 20:17:04 +00:00
|
|
|
}
|
|
|
|
|
|
2009-01-18 06:42:49 +00:00
|
|
|
// If this is a reference to a subset of the elements of a vector, create an
|
|
|
|
|
// appropriate shufflevector.
|
2011-06-25 02:11:03 +00:00
|
|
|
RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
llvm::Value *Vec = Builder.CreateLoad(LV.getExtVectorAddress(),
|
|
|
|
|
LV.isVolatileQualified());
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2008-05-09 06:41:27 +00:00
|
|
|
const llvm::Constant *Elts = LV.getExtVectorElts();
|
2009-09-09 13:00:44 +00:00
|
|
|
|
|
|
|
|
// If the result of the expression is a non-vector type, we must be extracting
|
|
|
|
|
// a single element. Just codegen as an extractelement.
|
2011-06-25 02:11:03 +00:00
|
|
|
const VectorType *ExprVT = LV.getType()->getAs<VectorType>();
|
2007-08-10 17:10:08 +00:00
|
|
|
if (!ExprVT) {
|
2008-05-22 00:50:06 +00:00
|
|
|
unsigned InIdx = getAccessedFieldNo(0, Elts);
|
2014-05-31 00:22:12 +00:00
|
|
|
llvm::Value *Elt = llvm::ConstantInt::get(SizeTy, InIdx);
|
2011-09-27 21:06:10 +00:00
|
|
|
return RValue::get(Builder.CreateExtractElement(Vec, Elt));
|
2007-08-03 16:18:34 +00:00
|
|
|
}
|
2009-01-18 06:42:49 +00:00
|
|
|
|
|
|
|
|
// Always use shuffle vector to try to retain the original program structure
|
2007-08-10 17:10:08 +00:00
|
|
|
unsigned NumResultElts = ExprVT->getNumElements();
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2020-04-15 12:41:54 +02:00
|
|
|
SmallVector<int, 4> Mask;
|
2012-01-25 05:34:41 +00:00
|
|
|
for (unsigned i = 0; i != NumResultElts; ++i)
|
2020-04-15 12:41:54 +02:00
|
|
|
Mask.push_back(getAccessedFieldNo(i, Elts));
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2020-12-30 07:28:17 +09:00
|
|
|
Vec = Builder.CreateShuffleVector(Vec, Mask);
|
2009-01-18 06:42:49 +00:00
|
|
|
return RValue::get(Vec);
|
2007-06-05 20:53:16 +00:00
|
|
|
}
|
|
|
|
|
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Generates lvalue for partial ext_vector access.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Address CodeGenFunction::EmitExtVectorElementLValue(LValue LV) {
|
|
|
|
|
Address VectorAddress = LV.getExtVectorAddress();
|
2020-01-11 15:33:25 +00:00
|
|
|
QualType EQT = LV.getType()->castAs<VectorType>()->getElementType();
|
2014-08-19 17:17:40 +00:00
|
|
|
llvm::Type *VectorElementTy = CGM.getTypes().ConvertType(EQT);
|
2018-07-30 19:24:48 +00: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 08:05:57 +00:00
|
|
|
Address CastToPointerElement =
|
|
|
|
|
Builder.CreateElementBitCast(VectorAddress, VectorElementTy,
|
|
|
|
|
"conv.ptr.element");
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2014-08-19 17:17:40 +00:00
|
|
|
const llvm::Constant *Elts = LV.getExtVectorElts();
|
|
|
|
|
unsigned ix = getAccessedFieldNo(0, Elts);
|
2018-07-30 19:24:48 +00: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 08:05:57 +00:00
|
|
|
Address VectorBasePtrPlusIx =
|
|
|
|
|
Builder.CreateConstInBoundsGEP(CastToPointerElement, ix,
|
|
|
|
|
"vector.elt");
|
|
|
|
|
|
2014-08-19 17:17:40 +00:00
|
|
|
return VectorBasePtrPlusIx;
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Load of global gamed gegisters are always calls to intrinsics.
|
2014-05-19 18:15:42 +00:00
|
|
|
RValue CodeGenFunction::EmitLoadOfGlobalRegLValue(LValue LV) {
|
2014-06-05 16:45:22 +00:00
|
|
|
assert((LV.getType()->isIntegerType() || LV.getType()->isPointerType()) &&
|
|
|
|
|
"Bad type for register variable");
|
2014-12-09 18:39:32 +00:00
|
|
|
llvm::MDNode *RegName = cast<llvm::MDNode>(
|
|
|
|
|
cast<llvm::MetadataAsValue>(LV.getGlobalReg())->getMetadata());
|
2014-06-05 16:45:22 +00:00
|
|
|
|
|
|
|
|
// We accept integer and pointer types only
|
|
|
|
|
llvm::Type *OrigTy = CGM.getTypes().ConvertType(LV.getType());
|
|
|
|
|
llvm::Type *Ty = OrigTy;
|
|
|
|
|
if (OrigTy->isPointerTy())
|
|
|
|
|
Ty = CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
|
|
|
|
|
llvm::Type *Types[] = { Ty };
|
|
|
|
|
|
2019-02-03 21:53:49 +00:00
|
|
|
llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
|
2014-12-09 18:39:32 +00:00
|
|
|
llvm::Value *Call = Builder.CreateCall(
|
|
|
|
|
F, llvm::MetadataAsValue::get(Ty->getContext(), RegName));
|
2014-06-05 16:45:22 +00:00
|
|
|
if (OrigTy->isPointerTy())
|
|
|
|
|
Call = Builder.CreateIntToPtr(Call, OrigTy);
|
2014-05-19 18:15:42 +00:00
|
|
|
return RValue::get(Call);
|
|
|
|
|
}
|
2007-08-03 16:18:34 +00:00
|
|
|
|
2007-06-05 20:53:16 +00:00
|
|
|
/// EmitStoreThroughLValue - Store the specified rvalue into the specified
|
|
|
|
|
/// lvalue, where both are guaranteed to the have the same type, and that type
|
|
|
|
|
/// is 'Ty'.
|
2013-10-01 21:51:38 +00:00
|
|
|
void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
|
2015-01-14 07:38:27 +00:00
|
|
|
bool isInit) {
|
2007-08-03 16:28:33 +00:00
|
|
|
if (!Dst.isSimple()) {
|
|
|
|
|
if (Dst.isVectorElt()) {
|
|
|
|
|
// Read/modify/write the vector, inserting the new element.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
llvm::Value *Vec = Builder.CreateLoad(Dst.getVectorAddress(),
|
|
|
|
|
Dst.isVolatileQualified());
|
2007-08-31 22:49:20 +00:00
|
|
|
Vec = Builder.CreateInsertElement(Vec, Src.getScalarVal(),
|
2007-08-03 16:28:33 +00:00
|
|
|
Dst.getVectorIdx(), "vecins");
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Builder.CreateStore(Vec, Dst.getVectorAddress(),
|
|
|
|
|
Dst.isVolatileQualified());
|
2007-08-03 16:28:33 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2008-04-18 23:10:10 +00:00
|
|
|
// If this is an update of extended vector elements, insert them as
|
|
|
|
|
// appropriate.
|
|
|
|
|
if (Dst.isExtVectorElt())
|
2011-06-25 02:11:03 +00:00
|
|
|
return EmitStoreThroughExtVectorComponentLValue(Src, Dst);
|
2008-01-22 22:36:45 +00:00
|
|
|
|
2014-05-19 18:15:42 +00:00
|
|
|
if (Dst.isGlobalReg())
|
|
|
|
|
return EmitStoreThroughGlobalRegLValue(Src, Dst);
|
|
|
|
|
|
[Matrix] Implement matrix index expressions ([][]).
This patch implements matrix index expressions
(matrix[RowIdx][ColumnIdx]).
It does so by introducing a new MatrixSubscriptExpr(Base, RowIdx, ColumnIdx).
MatrixSubscriptExprs are built in 2 steps in ActOnMatrixSubscriptExpr. First,
if the base of a subscript is of matrix type, we create a incomplete
MatrixSubscriptExpr(base, idx, nullptr). Second, if the base is an incomplete
MatrixSubscriptExpr, we create a complete
MatrixSubscriptExpr(base->getBase(), base->getRowIdx(), idx)
Similar to vector elements, it is not possible to take the address of
a MatrixSubscriptExpr.
For CodeGen, a new MatrixElt type is added to LValue, which is very
similar to VectorElt. The only difference is that we may need to cast
the type of the base from an array to a vector type when accessing it.
Reviewers: rjmccall, anemet, Bigcheese, rsmith, martong
Reviewed By: rjmccall
Differential Revision: https://reviews.llvm.org/D76791
2020-06-01 19:42:03 +01:00
|
|
|
if (Dst.isMatrixElt()) {
|
|
|
|
|
llvm::Value *Vec = Builder.CreateLoad(Dst.getMatrixAddress());
|
|
|
|
|
Vec = Builder.CreateInsertElement(Vec, Src.getScalarVal(),
|
|
|
|
|
Dst.getMatrixIdx(), "matins");
|
|
|
|
|
Builder.CreateStore(Vec, Dst.getMatrixAddress(),
|
|
|
|
|
Dst.isVolatileQualified());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-07 03:59:57 +00:00
|
|
|
assert(Dst.isBitField() && "Unknown LValue type");
|
|
|
|
|
return EmitStoreThroughBitfieldLValue(Src, Dst);
|
2007-08-03 16:28:33 +00:00
|
|
|
}
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2011-06-15 23:02:42 +00:00
|
|
|
// There's special magic for assigning into an ARC-qualified l-value.
|
|
|
|
|
if (Qualifiers::ObjCLifetime Lifetime = Dst.getQuals().getObjCLifetime()) {
|
|
|
|
|
switch (Lifetime) {
|
|
|
|
|
case Qualifiers::OCL_None:
|
|
|
|
|
llvm_unreachable("present but none");
|
|
|
|
|
|
|
|
|
|
case Qualifiers::OCL_ExplicitNone:
|
|
|
|
|
// nothing special
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Qualifiers::OCL_Strong:
|
2016-10-18 19:05:41 +00:00
|
|
|
if (isInit) {
|
|
|
|
|
Src = RValue::get(EmitARCRetain(Dst.getType(), Src.getScalarVal()));
|
|
|
|
|
break;
|
|
|
|
|
}
|
2011-06-25 02:11:03 +00:00
|
|
|
EmitARCStoreStrong(Dst, Src.getScalarVal(), /*ignore*/ true);
|
2011-06-15 23:02:42 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case Qualifiers::OCL_Weak:
|
2016-10-18 19:05:41 +00:00
|
|
|
if (isInit)
|
|
|
|
|
// Initialize and then skip the primitive store.
|
2019-12-03 15:17:01 -08:00
|
|
|
EmitARCInitWeak(Dst.getAddress(*this), Src.getScalarVal());
|
2016-10-18 19:05:41 +00:00
|
|
|
else
|
2019-12-03 15:17:01 -08:00
|
|
|
EmitARCStoreWeak(Dst.getAddress(*this), Src.getScalarVal(),
|
|
|
|
|
/*ignore*/ true);
|
2011-06-15 23:02:42 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
case Qualifiers::OCL_Autoreleasing:
|
2011-06-25 02:11:03 +00:00
|
|
|
Src = RValue::get(EmitObjCExtendObjectLifetime(Dst.getType(),
|
|
|
|
|
Src.getScalarVal()));
|
2011-06-15 23:02:42 +00:00
|
|
|
// fall into the normal path
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-21 00:30:43 +00:00
|
|
|
if (Dst.isObjCWeak() && !Dst.isNonGC()) {
|
2009-09-09 13:00:44 +00:00
|
|
|
// load of a __weak object.
|
2019-12-03 15:17:01 -08:00
|
|
|
Address LvalueDst = Dst.getAddress(*this);
|
2008-11-19 17:34:06 +00:00
|
|
|
llvm::Value *src = Src.getScalarVal();
|
2009-04-14 00:57:29 +00:00
|
|
|
CGM.getObjCRuntime().EmitObjCWeakAssign(*this, src, LvalueDst);
|
2008-11-19 17:34:06 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2009-02-21 00:30:43 +00:00
|
|
|
if (Dst.isObjCStrong() && !Dst.isNonGC()) {
|
2009-09-09 13:00:44 +00:00
|
|
|
// load of a __strong object.
|
2019-12-03 15:17:01 -08:00
|
|
|
Address LvalueDst = Dst.getAddress(*this);
|
2008-11-19 17:34:06 +00:00
|
|
|
llvm::Value *src = Src.getScalarVal();
|
2009-09-24 22:25:38 +00:00
|
|
|
if (Dst.isObjCIvar()) {
|
|
|
|
|
assert(Dst.getBaseIvarExp() && "BaseIvarExp is NULL");
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
llvm::Type *ResultType = IntPtrTy;
|
|
|
|
|
Address dst = EmitPointerWithAlignment(Dst.getBaseIvarExp());
|
|
|
|
|
llvm::Value *RHS = dst.getPointer();
|
2009-09-24 22:25:38 +00:00
|
|
|
RHS = Builder.CreatePtrToInt(RHS, ResultType, "sub.ptr.rhs.cast");
|
2013-07-26 05:59:26 +00:00
|
|
|
llvm::Value *LHS =
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Builder.CreatePtrToInt(LvalueDst.getPointer(), ResultType,
|
|
|
|
|
"sub.ptr.lhs.cast");
|
2009-09-24 22:25:38 +00:00
|
|
|
llvm::Value *BytesBetween = Builder.CreateSub(LHS, RHS, "ivar.offset");
|
2009-09-25 00:00:20 +00:00
|
|
|
CGM.getObjCRuntime().EmitObjCIvarAssign(*this, src, dst,
|
2009-09-24 22:25:38 +00:00
|
|
|
BytesBetween);
|
2010-07-20 20:30:03 +00:00
|
|
|
} else if (Dst.isGlobalObjCRef()) {
|
|
|
|
|
CGM.getObjCRuntime().EmitObjCGlobalAssign(*this, src, LvalueDst,
|
|
|
|
|
Dst.isThreadLocalRef());
|
|
|
|
|
}
|
2009-05-04 23:27:20 +00:00
|
|
|
else
|
|
|
|
|
CGM.getObjCRuntime().EmitObjCStrongCastAssign(*this, src, LvalueDst);
|
2008-11-19 17:34:06 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2007-08-11 00:04:45 +00:00
|
|
|
assert(Src.isScalar() && "Can't emit an agg store with this method");
|
2012-01-16 17:27:18 +00:00
|
|
|
EmitStoreOfScalar(Src.getScalarVal(), Dst, isInit);
|
2007-06-05 20:53:16 +00:00
|
|
|
}
|
|
|
|
|
|
2008-01-22 22:36:45 +00:00
|
|
|
void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
|
2008-11-19 09:36:46 +00:00
|
|
|
llvm::Value **Result) {
|
2010-04-06 01:07:44 +00:00
|
|
|
const CGBitFieldInfo &Info = Dst.getBitFieldInfo();
|
2011-07-18 04:24:23 +00:00
|
|
|
llvm::Type *ResLTy = ConvertTypeForMem(Dst.getType());
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Address Ptr = Dst.getBitFieldAddress();
|
2008-01-22 22:36:45 +00:00
|
|
|
|
IRgen: (Reapply 101222, with fixes) Move EmitStoreThroughBitfieldLValue to use new CGBitfieldInfo::AccessInfo decomposition, instead of computing the access policy itself.
- Sadly, this doesn't seem to give any .ll size win so far. It is possible to make this routine significantly smarter & avoid various shifting, masking, and zext/sext, but I'm not really convinced it is worth it. It is tricky, and this is really instcombine's job.
- No intended functionality change; the test case is just to increase coverage & serves as a demo file, it worked before this commit.
The new fixes from r101222 are:
1. The shift to the target position needs to occur after the value is extended to the correct size. This broke Clang bootstrap, among other things no doubt.
2. Swap the order of arguments to OR, to get a tad more constant folding.
llvm-svn: 101339
2010-04-15 03:47:33 +00:00
|
|
|
// Get the source value, truncated to the width of the bit-field.
|
2008-11-19 09:36:46 +00:00
|
|
|
llvm::Value *SrcVal = Src.getScalarVal();
|
2010-04-17 21:52:22 +00:00
|
|
|
|
2012-12-06 11:14:44 +00:00
|
|
|
// Cast the source to the storage type and shift it into place.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
SrcVal = Builder.CreateIntCast(SrcVal, Ptr.getElementType(),
|
2019-07-16 04:46:31 +00:00
|
|
|
/*isSigned=*/false);
|
2012-12-06 11:14:44 +00:00
|
|
|
llvm::Value *MaskedVal = SrcVal;
|
|
|
|
|
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
const bool UseVolatile =
|
|
|
|
|
CGM.getCodeGenOpts().AAPCSBitfieldWidth && Dst.isVolatileQualified() &&
|
|
|
|
|
Info.VolatileStorageSize != 0 && isAAPCS(CGM.getTarget());
|
|
|
|
|
const unsigned StorageSize =
|
|
|
|
|
UseVolatile ? Info.VolatileStorageSize : Info.StorageSize;
|
|
|
|
|
const unsigned Offset = UseVolatile ? Info.VolatileOffset : Info.Offset;
|
2012-12-06 11:14:44 +00:00
|
|
|
// See if there are other bits in the bitfield's storage we'll need to load
|
|
|
|
|
// and mask together with source before storing.
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
if (StorageSize != Info.Size) {
|
|
|
|
|
assert(StorageSize > Info.Size && "Invalid bitfield size.");
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
llvm::Value *Val =
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
Builder.CreateLoad(Ptr, Dst.isVolatileQualified(), "bf.load");
|
2012-12-06 11:14:44 +00:00
|
|
|
|
|
|
|
|
// Mask the source value as needed.
|
|
|
|
|
if (!hasBooleanRepresentation(Dst.getType()))
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
SrcVal = Builder.CreateAnd(
|
|
|
|
|
SrcVal, llvm::APInt::getLowBitsSet(StorageSize, Info.Size),
|
|
|
|
|
"bf.value");
|
2012-12-06 11:14:44 +00:00
|
|
|
MaskedVal = SrcVal;
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
if (Offset)
|
|
|
|
|
SrcVal = Builder.CreateShl(SrcVal, Offset, "bf.shl");
|
2012-12-06 11:14:44 +00:00
|
|
|
|
|
|
|
|
// Mask out the original value.
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
Val = Builder.CreateAnd(
|
|
|
|
|
Val, ~llvm::APInt::getBitsSet(StorageSize, Offset, Offset + Info.Size),
|
|
|
|
|
"bf.clear");
|
2008-11-19 09:36:46 +00:00
|
|
|
|
2012-12-06 11:14:44 +00:00
|
|
|
// Or together the unchanged values and the source value.
|
|
|
|
|
SrcVal = Builder.CreateOr(Val, SrcVal, "bf.set");
|
|
|
|
|
} else {
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
assert(Offset == 0);
|
[ARM] Follow AACPS for preserving number of loads/stores of volatile bit-fields
Summary:
Following the AAPCS, every store to a volatile bit-field requires to generate one load of that field, even if all the bits are going to be replaced.
This patch allows the user to opt-in in following such rule, whenever the a.
AAPCS Release 2019Q1.1 (https://static.docs.arm.com/ihi0042/g/aapcs32.pdf)
section 8.1 Data Types, page 35, paragraph: Volatile bit-fields – preserving number and width of container accesses
```
When a volatile bit-field is written, and its container does not overlap with any non-bit-field member, its
container must be read exactly once and written exactly once using the access width appropriate to the
type of the container. The two accesses are not atomic.
```
Reviewers: lebedev.ri, ostannard, jfb, eli.friedman
Reviewed By: jfb
Subscribers: rsmith, rjmccall, dexonsmith, kristof.beyls, jfb, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D67399
2020-02-07 10:03:59 +00:00
|
|
|
// According to the AACPS:
|
|
|
|
|
// When a volatile bit-field is written, and its container does not overlap
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
// with any non-bit-field member, its container must be read exactly once
|
|
|
|
|
// and written exactly once using the access width appropriate to the type
|
|
|
|
|
// of the container. The two accesses are not atomic.
|
[ARM] Follow AACPS for preserving number of loads/stores of volatile bit-fields
Summary:
Following the AAPCS, every store to a volatile bit-field requires to generate one load of that field, even if all the bits are going to be replaced.
This patch allows the user to opt-in in following such rule, whenever the a.
AAPCS Release 2019Q1.1 (https://static.docs.arm.com/ihi0042/g/aapcs32.pdf)
section 8.1 Data Types, page 35, paragraph: Volatile bit-fields – preserving number and width of container accesses
```
When a volatile bit-field is written, and its container does not overlap with any non-bit-field member, its
container must be read exactly once and written exactly once using the access width appropriate to the
type of the container. The two accesses are not atomic.
```
Reviewers: lebedev.ri, ostannard, jfb, eli.friedman
Reviewed By: jfb
Subscribers: rsmith, rjmccall, dexonsmith, kristof.beyls, jfb, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D67399
2020-02-07 10:03:59 +00:00
|
|
|
if (Dst.isVolatileQualified() && isAAPCS(CGM.getTarget()) &&
|
|
|
|
|
CGM.getCodeGenOpts().ForceAAPCSBitfieldLoad)
|
|
|
|
|
Builder.CreateLoad(Ptr, true, "bf.load");
|
2008-11-19 09:36:46 +00:00
|
|
|
}
|
|
|
|
|
|
2012-12-06 11:14:44 +00:00
|
|
|
// Write the new value back out.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Builder.CreateStore(SrcVal, Ptr, Dst.isVolatileQualified());
|
IRgen: (Reapply 101222, with fixes) Move EmitStoreThroughBitfieldLValue to use new CGBitfieldInfo::AccessInfo decomposition, instead of computing the access policy itself.
- Sadly, this doesn't seem to give any .ll size win so far. It is possible to make this routine significantly smarter & avoid various shifting, masking, and zext/sext, but I'm not really convinced it is worth it. It is tricky, and this is really instcombine's job.
- No intended functionality change; the test case is just to increase coverage & serves as a demo file, it worked before this commit.
The new fixes from r101222 are:
1. The shift to the target position needs to occur after the value is extended to the correct size. This broke Clang bootstrap, among other things no doubt.
2. Swap the order of arguments to OR, to get a tad more constant folding.
llvm-svn: 101339
2010-04-15 03:47:33 +00:00
|
|
|
|
2012-12-06 11:14:44 +00:00
|
|
|
// Return the new value of the bit-field, if requested.
|
|
|
|
|
if (Result) {
|
|
|
|
|
llvm::Value *ResultVal = MaskedVal;
|
|
|
|
|
|
|
|
|
|
// Sign extend the value if needed.
|
|
|
|
|
if (Info.IsSigned) {
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
assert(Info.Size <= StorageSize);
|
|
|
|
|
unsigned HighBits = StorageSize - Info.Size;
|
2012-12-06 11:14:44 +00:00
|
|
|
if (HighBits) {
|
|
|
|
|
ResultVal = Builder.CreateShl(ResultVal, HighBits, "bf.result.shl");
|
|
|
|
|
ResultVal = Builder.CreateAShr(ResultVal, HighBits, "bf.result.ashr");
|
|
|
|
|
}
|
IRgen: (Reapply 101222, with fixes) Move EmitStoreThroughBitfieldLValue to use new CGBitfieldInfo::AccessInfo decomposition, instead of computing the access policy itself.
- Sadly, this doesn't seem to give any .ll size win so far. It is possible to make this routine significantly smarter & avoid various shifting, masking, and zext/sext, but I'm not really convinced it is worth it. It is tricky, and this is really instcombine's job.
- No intended functionality change; the test case is just to increase coverage & serves as a demo file, it worked before this commit.
The new fixes from r101222 are:
1. The shift to the target position needs to occur after the value is extended to the correct size. This broke Clang bootstrap, among other things no doubt.
2. Swap the order of arguments to OR, to get a tad more constant folding.
llvm-svn: 101339
2010-04-15 03:47:33 +00:00
|
|
|
}
|
|
|
|
|
|
2012-12-06 11:14:44 +00:00
|
|
|
ResultVal = Builder.CreateIntCast(ResultVal, ResLTy, Info.IsSigned,
|
|
|
|
|
"bf.result.cast");
|
2012-12-19 00:26:58 +00:00
|
|
|
*Result = EmitFromMemory(ResultVal, Dst.getType());
|
2008-08-06 05:08:45 +00:00
|
|
|
}
|
2008-01-22 22:36:45 +00:00
|
|
|
}
|
|
|
|
|
|
2008-04-18 23:10:10 +00:00
|
|
|
void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
|
2011-06-25 02:11:03 +00:00
|
|
|
LValue Dst) {
|
2007-08-03 16:28:33 +00:00
|
|
|
// This access turns into a read/modify/write of the vector. Load the input
|
|
|
|
|
// value now.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
llvm::Value *Vec = Builder.CreateLoad(Dst.getExtVectorAddress(),
|
|
|
|
|
Dst.isVolatileQualified());
|
2008-05-09 06:41:27 +00:00
|
|
|
const llvm::Constant *Elts = Dst.getExtVectorElts();
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2007-08-31 22:49:20 +00:00
|
|
|
llvm::Value *SrcVal = Src.getScalarVal();
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2011-06-25 02:11:03 +00:00
|
|
|
if (const VectorType *VTy = Dst.getType()->getAs<VectorType>()) {
|
2007-08-03 16:37:04 +00:00
|
|
|
unsigned NumSrcElts = VTy->getNumElements();
|
2020-04-13 12:30:53 -07:00
|
|
|
unsigned NumDstElts =
|
2020-08-26 10:06:28 -07:00
|
|
|
cast<llvm::FixedVectorType>(Vec->getType())->getNumElements();
|
2009-01-18 06:42:49 +00:00
|
|
|
if (NumDstElts == NumSrcElts) {
|
2009-09-09 13:00:44 +00:00
|
|
|
// Use shuffle vector is the src and destination are the same number of
|
|
|
|
|
// elements and restore the vector mask since it is on the side it will be
|
|
|
|
|
// stored.
|
2020-04-15 12:41:54 +02:00
|
|
|
SmallVector<int, 4> Mask(NumDstElts);
|
2012-01-25 05:34:41 +00:00
|
|
|
for (unsigned i = 0; i != NumSrcElts; ++i)
|
2020-04-15 12:41:54 +02:00
|
|
|
Mask[getAccessedFieldNo(i, Elts)] = i;
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2020-12-30 07:28:17 +09:00
|
|
|
Vec = Builder.CreateShuffleVector(SrcVal, Mask);
|
2009-07-30 22:28:39 +00:00
|
|
|
} else if (NumDstElts > NumSrcElts) {
|
2009-01-18 06:42:49 +00:00
|
|
|
// Extended the source vector to the same length and then shuffle it
|
|
|
|
|
// into the destination.
|
|
|
|
|
// FIXME: since we're shuffling with undef, can we just use the indices
|
|
|
|
|
// into that? This could be simpler.
|
2020-04-15 12:41:54 +02:00
|
|
|
SmallVector<int, 4> ExtMask;
|
2012-02-14 12:06:21 +00:00
|
|
|
for (unsigned i = 0; i != NumSrcElts; ++i)
|
2020-04-15 12:41:54 +02:00
|
|
|
ExtMask.push_back(i);
|
|
|
|
|
ExtMask.resize(NumDstElts, -1);
|
2020-12-30 07:28:17 +09:00
|
|
|
llvm::Value *ExtSrcVal = Builder.CreateShuffleVector(SrcVal, ExtMask);
|
2009-01-18 06:42:49 +00:00
|
|
|
// build identity
|
2020-04-15 12:41:54 +02:00
|
|
|
SmallVector<int, 4> Mask;
|
2009-10-28 17:39:19 +00:00
|
|
|
for (unsigned i = 0; i != NumDstElts; ++i)
|
2020-04-15 12:41:54 +02:00
|
|
|
Mask.push_back(i);
|
2009-10-28 17:39:19 +00:00
|
|
|
|
2013-11-21 17:09:05 +00:00
|
|
|
// When the vector size is odd and .odd or .hi is used, the last element
|
|
|
|
|
// of the Elts constant array will be one past the size of the vector.
|
|
|
|
|
// Ignore the last element here, if it is greater than the mask size.
|
|
|
|
|
if (getAccessedFieldNo(NumSrcElts - 1, Elts) == Mask.size())
|
|
|
|
|
NumSrcElts--;
|
|
|
|
|
|
2009-01-18 06:42:49 +00:00
|
|
|
// modify when what gets shuffled in
|
2012-01-25 05:34:41 +00:00
|
|
|
for (unsigned i = 0; i != NumSrcElts; ++i)
|
2020-04-15 12:41:54 +02:00
|
|
|
Mask[getAccessedFieldNo(i, Elts)] = i + NumDstElts;
|
|
|
|
|
Vec = Builder.CreateShuffleVector(Vec, ExtSrcVal, Mask);
|
2009-07-30 22:28:39 +00:00
|
|
|
} else {
|
2009-01-18 06:42:49 +00:00
|
|
|
// We should never shorten the vector
|
2011-09-23 05:06:16 +00:00
|
|
|
llvm_unreachable("unexpected shorten vector length");
|
2007-08-03 16:37:04 +00:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// If the Src is a scalar (not a vector) it must be updating one element.
|
2008-05-22 00:50:06 +00:00
|
|
|
unsigned InIdx = getAccessedFieldNo(0, Elts);
|
2014-05-31 00:22:12 +00:00
|
|
|
llvm::Value *Elt = llvm::ConstantInt::get(SizeTy, InIdx);
|
2011-09-27 21:06:10 +00:00
|
|
|
Vec = Builder.CreateInsertElement(Vec, SrcVal, Elt);
|
2007-08-03 16:28:33 +00:00
|
|
|
}
|
2009-09-09 13:00:44 +00: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 08:05:57 +00:00
|
|
|
Builder.CreateStore(Vec, Dst.getExtVectorAddress(),
|
|
|
|
|
Dst.isVolatileQualified());
|
2007-08-03 16:28:33 +00:00
|
|
|
}
|
|
|
|
|
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Store of global named registers are always calls to intrinsics.
|
2014-05-19 18:15:42 +00:00
|
|
|
void CodeGenFunction::EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst) {
|
2014-06-05 16:45:22 +00:00
|
|
|
assert((Dst.getType()->isIntegerType() || Dst.getType()->isPointerType()) &&
|
|
|
|
|
"Bad type for register variable");
|
2014-12-09 18:39:32 +00:00
|
|
|
llvm::MDNode *RegName = cast<llvm::MDNode>(
|
|
|
|
|
cast<llvm::MetadataAsValue>(Dst.getGlobalReg())->getMetadata());
|
2014-05-19 18:15:42 +00:00
|
|
|
assert(RegName && "Register LValue is not metadata");
|
2014-06-05 16:45:22 +00:00
|
|
|
|
|
|
|
|
// We accept integer and pointer types only
|
|
|
|
|
llvm::Type *OrigTy = CGM.getTypes().ConvertType(Dst.getType());
|
|
|
|
|
llvm::Type *Ty = OrigTy;
|
|
|
|
|
if (OrigTy->isPointerTy())
|
|
|
|
|
Ty = CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
|
|
|
|
|
llvm::Type *Types[] = { Ty };
|
|
|
|
|
|
2019-02-03 21:53:49 +00:00
|
|
|
llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
|
2014-05-19 18:15:42 +00:00
|
|
|
llvm::Value *Value = Src.getScalarVal();
|
2014-06-05 16:45:22 +00:00
|
|
|
if (OrigTy->isPointerTy())
|
|
|
|
|
Value = Builder.CreatePtrToInt(Value, Ty);
|
2015-05-18 22:14:03 +00:00
|
|
|
Builder.CreateCall(
|
|
|
|
|
F, {llvm::MetadataAsValue::get(Ty->getContext(), RegName), Value});
|
2014-05-19 18:15:42 +00:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 17:10:39 +00:00
|
|
|
// setObjCGCLValueClass - sets class of the lvalue for the purpose of
|
2009-09-16 21:37:16 +00:00
|
|
|
// generating write-barries API. It is currently a global, ivar,
|
|
|
|
|
// or neither.
|
2009-10-28 17:39:19 +00:00
|
|
|
static void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E,
|
2011-09-30 18:23:36 +00:00
|
|
|
LValue &LV,
|
|
|
|
|
bool IsMemberAccess=false) {
|
2012-03-11 07:00:24 +00:00
|
|
|
if (Ctx.getLangOpts().getGC() == LangOptions::NonGC)
|
2009-09-16 21:37:16 +00:00
|
|
|
return;
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2009-09-16 23:11:23 +00:00
|
|
|
if (isa<ObjCIvarRefExpr>(E)) {
|
2011-09-30 18:23:36 +00:00
|
|
|
QualType ExpTy = E->getType();
|
|
|
|
|
if (IsMemberAccess && ExpTy->isPointerType()) {
|
|
|
|
|
// If ivar is a structure pointer, assigning to field of
|
2013-07-26 05:59:26 +00:00
|
|
|
// this struct follows gcc's behavior and makes it a non-ivar
|
2011-09-30 18:23:36 +00:00
|
|
|
// writer-barrier conservatively.
|
2019-10-07 16:42:25 +00:00
|
|
|
ExpTy = ExpTy->castAs<PointerType>()->getPointeeType();
|
2011-09-30 18:23:36 +00:00
|
|
|
if (ExpTy->isRecordType()) {
|
|
|
|
|
LV.setObjCIvar(false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-08-21 03:51:29 +00:00
|
|
|
LV.setObjCIvar(true);
|
2014-05-09 00:08:36 +00:00
|
|
|
auto *Exp = cast<ObjCIvarRefExpr>(const_cast<Expr *>(E));
|
2009-09-24 22:25:38 +00:00
|
|
|
LV.setBaseIvarExp(Exp->getBase());
|
2010-08-21 03:51:29 +00:00
|
|
|
LV.setObjCArray(E->getType()->isArrayType());
|
2009-09-16 23:11:23 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *Exp = dyn_cast<DeclRefExpr>(E)) {
|
|
|
|
|
if (const auto *VD = dyn_cast<VarDecl>(Exp->getDecl())) {
|
2010-10-15 04:57:14 +00:00
|
|
|
if (VD->hasGlobalStorage()) {
|
2010-08-21 03:51:29 +00:00
|
|
|
LV.setGlobalObjCRef(true);
|
2013-04-13 02:43:54 +00:00
|
|
|
LV.setThreadLocalRef(VD->getTLSKind() != VarDecl::TLS_None);
|
2010-07-20 20:30:03 +00:00
|
|
|
}
|
2009-09-16 21:37:16 +00:00
|
|
|
}
|
2010-08-21 03:51:29 +00:00
|
|
|
LV.setObjCArray(E->getType()->isArrayType());
|
2009-10-28 17:39:19 +00:00
|
|
|
return;
|
2009-09-16 21:37:16 +00:00
|
|
|
}
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *Exp = dyn_cast<UnaryOperator>(E)) {
|
2011-09-30 18:23:36 +00:00
|
|
|
setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV, IsMemberAccess);
|
2009-10-28 17:39:19 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *Exp = dyn_cast<ParenExpr>(E)) {
|
2011-09-30 18:23:36 +00:00
|
|
|
setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV, IsMemberAccess);
|
2009-09-30 17:10:29 +00:00
|
|
|
if (LV.isObjCIvar()) {
|
|
|
|
|
// If cast is to a structure pointer, follow gcc's behavior and make it
|
|
|
|
|
// a non-ivar write-barrier.
|
|
|
|
|
QualType ExpTy = E->getType();
|
|
|
|
|
if (ExpTy->isPointerType())
|
2019-10-07 16:42:25 +00:00
|
|
|
ExpTy = ExpTy->castAs<PointerType>()->getPointeeType();
|
2009-09-30 17:10:29 +00:00
|
|
|
if (ExpTy->isRecordType())
|
2013-07-26 05:59:26 +00:00
|
|
|
LV.setObjCIvar(false);
|
2009-10-28 17:39:19 +00:00
|
|
|
}
|
|
|
|
|
return;
|
2009-09-30 17:10:29 +00:00
|
|
|
}
|
2011-04-15 00:35:48 +00:00
|
|
|
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *Exp = dyn_cast<GenericSelectionExpr>(E)) {
|
2011-04-15 00:35:48 +00:00
|
|
|
setObjCGCLValueClass(Ctx, Exp->getResultExpr(), LV);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *Exp = dyn_cast<ImplicitCastExpr>(E)) {
|
2011-09-30 18:23:36 +00:00
|
|
|
setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV, IsMemberAccess);
|
2009-10-28 17:39:19 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *Exp = dyn_cast<CStyleCastExpr>(E)) {
|
2011-09-30 18:23:36 +00:00
|
|
|
setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV, IsMemberAccess);
|
2009-10-28 17:39:19 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2011-06-15 23:02:42 +00:00
|
|
|
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *Exp = dyn_cast<ObjCBridgedCastExpr>(E)) {
|
2011-09-30 18:23:36 +00:00
|
|
|
setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV, IsMemberAccess);
|
2011-06-15 23:02:42 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *Exp = dyn_cast<ArraySubscriptExpr>(E)) {
|
2009-09-16 21:37:16 +00:00
|
|
|
setObjCGCLValueClass(Ctx, Exp->getBase(), LV);
|
2013-07-26 05:59:26 +00:00
|
|
|
if (LV.isObjCIvar() && !LV.isObjCArray())
|
|
|
|
|
// Using array syntax to assigning to what an ivar points to is not
|
2009-09-18 00:04:00 +00:00
|
|
|
// same as assigning to the ivar itself. {id *Names;} Names[i] = 0;
|
2013-07-26 05:59:26 +00:00
|
|
|
LV.setObjCIvar(false);
|
2009-09-21 18:54:29 +00:00
|
|
|
else if (LV.isGlobalObjCRef() && !LV.isObjCArray())
|
2013-07-26 05:59:26 +00:00
|
|
|
// Using array syntax to assigning to what global points to is not
|
2009-09-21 18:54:29 +00:00
|
|
|
// same as assigning to the global itself. {id *G;} G[i] = 0;
|
2010-08-21 03:51:29 +00:00
|
|
|
LV.setGlobalObjCRef(false);
|
2009-10-28 17:39:19 +00:00
|
|
|
return;
|
2009-09-18 00:04:00 +00:00
|
|
|
}
|
2011-09-30 18:23:36 +00:00
|
|
|
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *Exp = dyn_cast<MemberExpr>(E)) {
|
2011-09-30 18:23:36 +00:00
|
|
|
setObjCGCLValueClass(Ctx, Exp->getBase(), LV, true);
|
2009-09-18 00:04:00 +00:00
|
|
|
// We don't know if member is an 'ivar', but this flag is looked at
|
|
|
|
|
// only in the context of LV.isObjCIvar().
|
2010-08-21 03:51:29 +00:00
|
|
|
LV.setObjCArray(E->getType()->isArrayType());
|
2009-10-28 17:39:19 +00:00
|
|
|
return;
|
2009-09-16 21:37:16 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-12 06:52:18 +00:00
|
|
|
static llvm::Value *
|
2011-07-12 08:58:26 +00:00
|
|
|
EmitBitCastOfLValueToProperType(CodeGenFunction &CGF,
|
2011-07-12 06:52:18 +00:00
|
|
|
llvm::Value *V, llvm::Type *IRType,
|
2011-07-23 10:55:15 +00:00
|
|
|
StringRef Name = StringRef()) {
|
2011-07-12 06:52:18 +00:00
|
|
|
unsigned AS = cast<llvm::PointerType>(V->getType())->getAddressSpace();
|
2011-07-12 08:58:26 +00:00
|
|
|
return CGF.Builder.CreateBitCast(V, IRType->getPointerTo(AS), Name);
|
2011-07-12 06:52:18 +00:00
|
|
|
}
|
|
|
|
|
|
2014-11-11 04:05:39 +00:00
|
|
|
static LValue EmitThreadPrivateVarDeclLValue(
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
CodeGenFunction &CGF, const VarDecl *VD, QualType T, Address Addr,
|
|
|
|
|
llvm::Type *RealVarTy, SourceLocation Loc) {
|
2020-07-05 15:24:36 +02:00
|
|
|
if (CGF.CGM.getLangOpts().OpenMPIRBuilder)
|
2020-06-04 15:55:17 -04:00
|
|
|
Addr = CodeGenFunction::OMPBuilderCBHelpers::getAddrOfThreadPrivate(
|
|
|
|
|
CGF, VD, Addr, Loc);
|
|
|
|
|
else
|
|
|
|
|
Addr =
|
|
|
|
|
CGF.CGM.getOpenMPRuntime().getAddrOfThreadPrivate(CGF, VD, Addr, Loc);
|
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Addr = CGF.Builder.CreateElementBitCast(Addr, RealVarTy);
|
2017-10-10 09:39:32 +00:00
|
|
|
return CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
}
|
|
|
|
|
|
2019-06-20 18:04:47 +00:00
|
|
|
static Address emitDeclTargetVarDeclLValue(CodeGenFunction &CGF,
|
|
|
|
|
const VarDecl *VD, QualType T) {
|
2018-08-15 19:45:12 +00:00
|
|
|
llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
|
|
|
|
|
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
|
2019-06-20 18:04:47 +00:00
|
|
|
// Return an invalid address if variable is MT_To and unified
|
|
|
|
|
// memory is not enabled. For all other cases: MT_Link and
|
|
|
|
|
// MT_To with unified memory, return a valid address.
|
|
|
|
|
if (!Res || (*Res == OMPDeclareTargetDeclAttr::MT_To &&
|
|
|
|
|
!CGF.CGM.getOpenMPRuntime().hasRequiresUnifiedSharedMemory()))
|
2018-08-15 19:45:12 +00:00
|
|
|
return Address::invalid();
|
2019-06-20 18:04:47 +00:00
|
|
|
assert(((*Res == OMPDeclareTargetDeclAttr::MT_Link) ||
|
|
|
|
|
(*Res == OMPDeclareTargetDeclAttr::MT_To &&
|
|
|
|
|
CGF.CGM.getOpenMPRuntime().hasRequiresUnifiedSharedMemory())) &&
|
|
|
|
|
"Expected link clause OR to clause with unified memory enabled.");
|
2018-08-15 19:45:12 +00:00
|
|
|
QualType PtrTy = CGF.getContext().getPointerType(VD->getType());
|
2019-06-20 18:04:47 +00:00
|
|
|
Address Addr = CGF.CGM.getOpenMPRuntime().getAddrOfDeclareTargetVar(VD);
|
2018-08-15 19:45:12 +00:00
|
|
|
return CGF.EmitLoadOfPointer(Addr, PtrTy->castAs<PointerType>());
|
2018-03-26 16:40:55 +00:00
|
|
|
}
|
|
|
|
|
|
2017-10-30 11:49:31 +00:00
|
|
|
Address
|
|
|
|
|
CodeGenFunction::EmitLoadOfReference(LValue RefLVal,
|
|
|
|
|
LValueBaseInfo *PointeeBaseInfo,
|
|
|
|
|
TBAAAccessInfo *PointeeTBAAInfo) {
|
2019-12-03 15:17:01 -08:00
|
|
|
llvm::LoadInst *Load =
|
|
|
|
|
Builder.CreateLoad(RefLVal.getAddress(*this), RefLVal.isVolatile());
|
2017-10-31 11:05:34 +00:00
|
|
|
CGM.DecorateInstructionWithTBAA(Load, RefLVal.getTBAAInfo());
|
2017-10-30 11:49:31 +00:00
|
|
|
|
2020-05-18 11:29:11 -07:00
|
|
|
CharUnits Align = CGM.getNaturalTypeAlignment(
|
|
|
|
|
RefLVal.getType()->getPointeeType(), PointeeBaseInfo, PointeeTBAAInfo,
|
|
|
|
|
/* forPointeeType= */ true);
|
2017-10-30 11:49:31 +00:00
|
|
|
return Address(Load, Align);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LValue CodeGenFunction::EmitLoadOfReferenceLValue(LValue RefLVal) {
|
|
|
|
|
LValueBaseInfo PointeeBaseInfo;
|
|
|
|
|
TBAAAccessInfo PointeeTBAAInfo;
|
|
|
|
|
Address PointeeAddr = EmitLoadOfReference(RefLVal, &PointeeBaseInfo,
|
|
|
|
|
&PointeeTBAAInfo);
|
|
|
|
|
return MakeAddrLValue(PointeeAddr, RefLVal.getType()->getPointeeType(),
|
|
|
|
|
PointeeBaseInfo, PointeeTBAAInfo);
|
2014-11-11 04:05:39 +00:00
|
|
|
}
|
|
|
|
|
|
2016-02-04 11:27:03 +00:00
|
|
|
Address CodeGenFunction::EmitLoadOfPointer(Address Ptr,
|
|
|
|
|
const PointerType *PtrTy,
|
2017-10-13 16:47:22 +00:00
|
|
|
LValueBaseInfo *BaseInfo,
|
|
|
|
|
TBAAAccessInfo *TBAAInfo) {
|
2016-02-04 11:27:03 +00:00
|
|
|
llvm::Value *Addr = Builder.CreateLoad(Ptr);
|
2020-05-18 11:29:11 -07:00
|
|
|
return Address(Addr, CGM.getNaturalTypeAlignment(PtrTy->getPointeeType(),
|
|
|
|
|
BaseInfo, TBAAInfo,
|
|
|
|
|
/*forPointeeType=*/true));
|
2016-02-04 11:27:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LValue CodeGenFunction::EmitLoadOfPointerLValue(Address PtrAddr,
|
|
|
|
|
const PointerType *PtrTy) {
|
2017-05-18 17:07:11 +00:00
|
|
|
LValueBaseInfo BaseInfo;
|
2017-10-13 16:47:22 +00:00
|
|
|
TBAAAccessInfo TBAAInfo;
|
|
|
|
|
Address Addr = EmitLoadOfPointer(PtrAddr, PtrTy, &BaseInfo, &TBAAInfo);
|
|
|
|
|
return MakeAddrLValue(Addr, PtrTy->getPointeeType(), BaseInfo, TBAAInfo);
|
2016-02-04 11:27:03 +00:00
|
|
|
}
|
|
|
|
|
|
2009-11-07 23:06:58 +00:00
|
|
|
static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
|
|
|
|
|
const Expr *E, const VarDecl *VD) {
|
2014-03-26 22:48:22 +00:00
|
|
|
QualType T = E->getType();
|
|
|
|
|
|
|
|
|
|
// If it's thread_local, emit a call to its wrapper function instead.
|
2014-10-05 05:05:40 +00:00
|
|
|
if (VD->getTLSKind() == VarDecl::TLS_Dynamic &&
|
2019-09-12 20:00:24 +00:00
|
|
|
CGF.CGM.getCXXABI().usesThreadWrapperFunction(VD))
|
2014-03-26 22:48:22 +00:00
|
|
|
return CGF.CGM.getCXXABI().EmitThreadLocalVarDeclLValue(CGF, VD, T);
|
2018-03-26 16:40:55 +00:00
|
|
|
// Check if the variable is marked as declare target with link clause in
|
|
|
|
|
// device codegen.
|
|
|
|
|
if (CGF.getLangOpts().OpenMPIsDevice) {
|
2019-06-20 18:04:47 +00:00
|
|
|
Address Addr = emitDeclTargetVarDeclLValue(CGF, VD, T);
|
2018-03-26 16:40:55 +00:00
|
|
|
if (Addr.isValid())
|
|
|
|
|
return CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl);
|
|
|
|
|
}
|
2014-03-26 22:48:22 +00:00
|
|
|
|
2009-11-07 23:06:58 +00:00
|
|
|
llvm::Value *V = CGF.CGM.GetAddrOfGlobalVar(VD);
|
2011-11-16 00:42:57 +00:00
|
|
|
llvm::Type *RealVarTy = CGF.getTypes().ConvertTypeForMem(VD->getType());
|
|
|
|
|
V = EmitBitCastOfLValueToProperType(CGF, V, RealVarTy);
|
2011-12-03 04:14:32 +00:00
|
|
|
CharUnits Alignment = CGF.getContext().getDeclAlign(VD);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Address Addr(V, Alignment);
|
2014-11-11 04:05:39 +00:00
|
|
|
// Emit reference to the private copy of the variable if it is an OpenMP
|
|
|
|
|
// threadprivate variable.
|
2017-12-29 18:07:07 +00:00
|
|
|
if (CGF.getLangOpts().OpenMP && !CGF.getLangOpts().OpenMPSimd &&
|
|
|
|
|
VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
return EmitThreadPrivateVarDeclLValue(CGF, VD, T, Addr, RealVarTy,
|
2014-11-11 04:05:39 +00:00
|
|
|
E->getExprLoc());
|
2017-12-29 18:07:07 +00:00
|
|
|
}
|
2017-10-30 11:49:31 +00:00
|
|
|
LValue LV = VD->getType()->isReferenceType() ?
|
|
|
|
|
CGF.EmitLoadOfReferenceLValue(Addr, VD->getType(),
|
|
|
|
|
AlignmentSource::Decl) :
|
|
|
|
|
CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl);
|
2009-11-07 23:06:58 +00:00
|
|
|
setObjCGCLValueClass(CGF.getContext(), E, LV);
|
|
|
|
|
return LV;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-26 23:46:34 +00:00
|
|
|
static llvm::Constant *EmitFunctionDeclPointer(CodeGenModule &CGM,
|
2020-03-05 12:02:13 -05:00
|
|
|
GlobalDecl GD) {
|
|
|
|
|
const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
|
2016-10-26 23:46:34 +00:00
|
|
|
if (FD->hasAttr<WeakRefAttr>()) {
|
|
|
|
|
ConstantAddress aliasee = CGM.GetWeakRefReference(FD);
|
|
|
|
|
return aliasee.getPointer();
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-05 12:02:13 -05:00
|
|
|
llvm::Constant *V = CGM.GetAddrOfFunction(GD);
|
2009-11-26 06:08:14 +00:00
|
|
|
if (!FD->hasPrototype()) {
|
|
|
|
|
if (const FunctionProtoType *Proto =
|
|
|
|
|
FD->getType()->getAs<FunctionProtoType>()) {
|
|
|
|
|
// Ugly case: for a K&R-style definition, the type of the definition
|
|
|
|
|
// isn't the same as the type of a use. Correct for this with a
|
|
|
|
|
// bitcast.
|
|
|
|
|
QualType NoProtoType =
|
2016-10-26 23:46:34 +00:00
|
|
|
CGM.getContext().getFunctionNoProtoType(Proto->getReturnType());
|
|
|
|
|
NoProtoType = CGM.getContext().getPointerType(NoProtoType);
|
|
|
|
|
V = llvm::ConstantExpr::getBitCast(V,
|
|
|
|
|
CGM.getTypes().ConvertType(NoProtoType));
|
2009-11-26 06:08:14 +00:00
|
|
|
}
|
|
|
|
|
}
|
2016-10-26 23:46:34 +00:00
|
|
|
return V;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-05 12:02:13 -05:00
|
|
|
static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF, const Expr *E,
|
|
|
|
|
GlobalDecl GD) {
|
|
|
|
|
const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
|
|
|
|
|
llvm::Value *V = EmitFunctionDeclPointer(CGF.CGM, GD);
|
2011-12-03 04:14:32 +00:00
|
|
|
CharUnits Alignment = CGF.getContext().getDeclAlign(FD);
|
2017-10-10 09:39:32 +00:00
|
|
|
return CGF.MakeAddrLValue(V, E->getType(), Alignment,
|
|
|
|
|
AlignmentSource::Decl);
|
2009-11-26 06:08:14 +00:00
|
|
|
}
|
|
|
|
|
|
2013-05-09 19:17:11 +00:00
|
|
|
static LValue EmitCapturedFieldLValue(CodeGenFunction &CGF, const FieldDecl *FD,
|
|
|
|
|
llvm::Value *ThisValue) {
|
|
|
|
|
QualType TagType = CGF.getContext().getTagDeclType(FD->getParent());
|
|
|
|
|
LValue LV = CGF.MakeNaturalAlignAddrLValue(ThisValue, TagType);
|
|
|
|
|
return CGF.EmitLValueForField(LV, FD);
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-19 18:15:42 +00:00
|
|
|
/// Named Registers are named metadata pointing to the register name
|
|
|
|
|
/// which will be read from/written to as an argument to the intrinsic
|
|
|
|
|
/// @llvm.read/write_register.
|
|
|
|
|
/// So far, only the name is being passed down, but other options such as
|
|
|
|
|
/// register type, allocation type or even optimization options could be
|
|
|
|
|
/// passed down via the metadata node.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
static LValue EmitGlobalNamedRegister(const VarDecl *VD, CodeGenModule &CGM) {
|
2014-05-19 23:25:25 +00:00
|
|
|
SmallString<64> Name("llvm.named.register.");
|
2014-05-19 18:15:42 +00:00
|
|
|
AsmLabelAttr *Asm = VD->getAttr<AsmLabelAttr>();
|
2014-05-19 23:25:25 +00:00
|
|
|
assert(Asm->getLabel().size() < 64-Name.size() &&
|
|
|
|
|
"Register name too big");
|
|
|
|
|
Name.append(Asm->getLabel());
|
2014-05-19 22:36:19 +00:00
|
|
|
llvm::NamedMDNode *M =
|
2014-05-19 23:25:25 +00:00
|
|
|
CGM.getModule().getOrInsertNamedMetadata(Name);
|
2014-05-19 18:15:42 +00:00
|
|
|
if (M->getNumOperands() == 0) {
|
|
|
|
|
llvm::MDString *Str = llvm::MDString::get(CGM.getLLVMContext(),
|
|
|
|
|
Asm->getLabel());
|
2014-12-09 18:39:32 +00:00
|
|
|
llvm::Metadata *Ops[] = {Str};
|
2014-05-19 18:15:42 +00:00
|
|
|
M->addOperand(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
|
|
|
|
|
}
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
|
|
|
|
|
CharUnits Alignment = CGM.getContext().getDeclAlign(VD);
|
|
|
|
|
|
|
|
|
|
llvm::Value *Ptr =
|
|
|
|
|
llvm::MetadataAsValue::get(CGM.getLLVMContext(), M->getOperand(0));
|
|
|
|
|
return LValue::MakeGlobalReg(Address(Ptr, Alignment), VD->getType());
|
2014-05-19 18:15:42 +00:00
|
|
|
}
|
|
|
|
|
|
2019-06-14 17:46:37 +00:00
|
|
|
/// Determine whether we can emit a reference to \p VD from the current
|
|
|
|
|
/// context, despite not necessarily having seen an odr-use of the variable in
|
|
|
|
|
/// this context.
|
|
|
|
|
static bool canEmitSpuriousReferenceToVariable(CodeGenFunction &CGF,
|
|
|
|
|
const DeclRefExpr *E,
|
|
|
|
|
const VarDecl *VD,
|
|
|
|
|
bool IsConstant) {
|
|
|
|
|
// For a variable declared in an enclosing scope, do not emit a spurious
|
|
|
|
|
// reference even if we have a capture, as that will emit an unwarranted
|
|
|
|
|
// reference to our capture state, and will likely generate worse code than
|
|
|
|
|
// emitting a local copy.
|
|
|
|
|
if (E->refersToEnclosingVariableOrCapture())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// For a local declaration declared in this function, we can always reference
|
|
|
|
|
// it even if we don't have an odr-use.
|
|
|
|
|
if (VD->hasLocalStorage()) {
|
|
|
|
|
return VD->getDeclContext() ==
|
|
|
|
|
dyn_cast_or_null<DeclContext>(CGF.CurCodeDecl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For a global declaration, we can emit a reference to it if we know
|
|
|
|
|
// for sure that we are able to emit a definition of it.
|
|
|
|
|
VD = VD->getDefinition(CGF.getContext());
|
|
|
|
|
if (!VD)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// Don't emit a spurious reference if it might be to a variable that only
|
|
|
|
|
// exists on a different device / target.
|
|
|
|
|
// FIXME: This is unnecessarily broad. Check whether this would actually be a
|
|
|
|
|
// cross-target reference.
|
|
|
|
|
if (CGF.getLangOpts().OpenMP || CGF.getLangOpts().CUDA ||
|
|
|
|
|
CGF.getLangOpts().OpenCL) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// We can emit a spurious reference only if the linkage implies that we'll
|
|
|
|
|
// be emitting a non-interposable symbol that will be retained until link
|
|
|
|
|
// time.
|
|
|
|
|
switch (CGF.CGM.getLLVMLinkageVarDefinition(VD, IsConstant)) {
|
|
|
|
|
case llvm::GlobalValue::ExternalLinkage:
|
|
|
|
|
case llvm::GlobalValue::LinkOnceODRLinkage:
|
|
|
|
|
case llvm::GlobalValue::WeakODRLinkage:
|
|
|
|
|
case llvm::GlobalValue::InternalLinkage:
|
|
|
|
|
case llvm::GlobalValue::PrivateLinkage:
|
|
|
|
|
return true;
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-06-02 05:24:33 +00:00
|
|
|
LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
|
2009-11-07 22:53:10 +00:00
|
|
|
const NamedDecl *ND = E->getDecl();
|
2011-11-16 00:42:57 +00:00
|
|
|
QualType T = E->getType();
|
2014-05-19 18:15:42 +00:00
|
|
|
|
2019-06-14 17:46:37 +00:00
|
|
|
assert(E->isNonOdrUse() != NOUR_Unevaluated &&
|
|
|
|
|
"should not emit an unevaluated operand");
|
|
|
|
|
|
2014-05-27 16:46:27 +00:00
|
|
|
if (const auto *VD = dyn_cast<VarDecl>(ND)) {
|
|
|
|
|
// Global Named registers access via intrinsics only
|
2021-01-04 23:17:45 +01:00
|
|
|
if (VD->getStorageClass() == SC_Register &&
|
2014-05-27 16:46:27 +00:00
|
|
|
VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
return EmitGlobalNamedRegister(VD, CGM);
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2019-06-14 17:46:37 +00:00
|
|
|
// If this DeclRefExpr does not constitute an odr-use of the variable,
|
|
|
|
|
// we're not permitted to emit a reference to it in general, and it might
|
|
|
|
|
// not be captured if capture would be necessary for a use. Emit the
|
|
|
|
|
// constant value directly instead.
|
|
|
|
|
if (E->isNonOdrUse() == NOUR_Constant &&
|
|
|
|
|
(VD->getType()->isReferenceType() ||
|
|
|
|
|
!canEmitSpuriousReferenceToVariable(*this, E, VD, true))) {
|
|
|
|
|
VD->getAnyInitializer(VD);
|
|
|
|
|
llvm::Constant *Val = ConstantEmitter(*this).emitAbstract(
|
|
|
|
|
E->getLocation(), *VD->evaluateValue(), VD->getType());
|
|
|
|
|
assert(Val && "failed to emit constant expression");
|
|
|
|
|
|
|
|
|
|
Address Addr = Address::invalid();
|
|
|
|
|
if (!VD->getType()->isReferenceType()) {
|
|
|
|
|
// Spill the constant value to a global.
|
|
|
|
|
Addr = CGM.createUnnamedGlobalFrom(*VD, Val,
|
|
|
|
|
getContext().getDeclAlign(VD));
|
2019-09-10 19:16:56 +00:00
|
|
|
llvm::Type *VarTy = getTypes().ConvertTypeForMem(VD->getType());
|
|
|
|
|
auto *PTy = llvm::PointerType::get(
|
|
|
|
|
VarTy, getContext().getTargetAddressSpace(VD->getType()));
|
|
|
|
|
if (PTy != Addr.getType())
|
|
|
|
|
Addr = Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, PTy);
|
2019-06-14 17:46:37 +00:00
|
|
|
} else {
|
|
|
|
|
// Should we be using the alignment of the constant pointer we emitted?
|
|
|
|
|
CharUnits Alignment =
|
2020-05-18 11:29:11 -07:00
|
|
|
CGM.getNaturalTypeAlignment(E->getType(),
|
|
|
|
|
/* BaseInfo= */ nullptr,
|
|
|
|
|
/* TBAAInfo= */ nullptr,
|
|
|
|
|
/* forPointeeType= */ true);
|
2019-06-14 17:46:37 +00:00
|
|
|
Addr = Address(Val, Alignment);
|
|
|
|
|
}
|
|
|
|
|
return MakeAddrLValue(Addr, T, AlignmentSource::Decl);
|
2012-10-20 01:38:33 +00:00
|
|
|
}
|
2015-01-01 09:49:44 +00:00
|
|
|
|
2019-06-11 17:50:32 +00:00
|
|
|
// FIXME: Handle other kinds of non-odr-use DeclRefExprs.
|
|
|
|
|
|
2015-01-01 09:49:44 +00:00
|
|
|
// Check for captured variables.
|
2015-01-12 10:17:46 +00:00
|
|
|
if (E->refersToEnclosingVariableOrCapture()) {
|
2017-08-22 17:54:52 +00:00
|
|
|
VD = VD->getCanonicalDecl();
|
2015-01-01 09:49:44 +00:00
|
|
|
if (auto *FD = LambdaCaptureFields.lookup(VD))
|
|
|
|
|
return EmitCapturedFieldLValue(*this, FD, CXXABIThisValue);
|
2019-12-19 10:01:10 -05:00
|
|
|
if (CapturedStmtInfo) {
|
2016-11-07 11:16:04 +00:00
|
|
|
auto I = LocalDeclMap.find(VD);
|
|
|
|
|
if (I != LocalDeclMap.end()) {
|
2019-12-19 10:01:10 -05:00
|
|
|
LValue CapLVal;
|
2017-10-30 11:49:31 +00:00
|
|
|
if (VD->getType()->isReferenceType())
|
2019-12-19 10:01:10 -05:00
|
|
|
CapLVal = EmitLoadOfReferenceLValue(I->second, VD->getType(),
|
|
|
|
|
AlignmentSource::Decl);
|
|
|
|
|
else
|
|
|
|
|
CapLVal = MakeAddrLValue(I->second, T);
|
|
|
|
|
// Mark lvalue as nontemporal if the variable is marked as nontemporal
|
|
|
|
|
// in simd context.
|
|
|
|
|
if (getLangOpts().OpenMP &&
|
|
|
|
|
CGM.getOpenMPRuntime().isNontemporalDecl(VD))
|
|
|
|
|
CapLVal.setNontemporal(/*Value=*/true);
|
|
|
|
|
return CapLVal;
|
2015-09-04 11:26:21 +00:00
|
|
|
}
|
2015-09-11 10:29:41 +00:00
|
|
|
LValue CapLVal =
|
|
|
|
|
EmitCapturedFieldLValue(*this, CapturedStmtInfo->lookup(VD),
|
|
|
|
|
CapturedStmtInfo->getContextValue());
|
2019-12-19 10:01:10 -05:00
|
|
|
CapLVal = MakeAddrLValue(
|
2019-12-03 15:17:01 -08:00
|
|
|
Address(CapLVal.getPointer(*this), getContext().getDeclAlign(VD)),
|
2017-10-31 11:05:34 +00:00
|
|
|
CapLVal.getType(), LValueBaseInfo(AlignmentSource::Decl),
|
|
|
|
|
CapLVal.getTBAAInfo());
|
2019-12-19 10:01:10 -05:00
|
|
|
// Mark lvalue as nontemporal if the variable is marked as nontemporal
|
|
|
|
|
// in simd context.
|
|
|
|
|
if (getLangOpts().OpenMP &&
|
|
|
|
|
CGM.getOpenMPRuntime().isNontemporalDecl(VD))
|
|
|
|
|
CapLVal.setNontemporal(/*Value=*/true);
|
|
|
|
|
return CapLVal;
|
2015-01-01 09:49:44 +00: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 08:05:57 +00:00
|
|
|
|
2015-01-01 09:49:44 +00:00
|
|
|
assert(isa<BlockDecl>(CurCodeDecl));
|
2018-10-01 21:51:28 +00:00
|
|
|
Address addr = GetAddrOfBlockDecl(VD);
|
2017-10-10 09:39:32 +00:00
|
|
|
return MakeAddrLValue(addr, T, AlignmentSource::Decl);
|
2015-01-01 09:49:44 +00:00
|
|
|
}
|
2012-10-20 01:38:33 +00:00
|
|
|
}
|
|
|
|
|
|
2012-01-21 04:52:58 +00:00
|
|
|
// FIXME: We should be able to assert this for FunctionDecls as well!
|
|
|
|
|
// FIXME: We should be able to assert this for all DeclRefExprs, not just
|
|
|
|
|
// those with a valid source location.
|
2019-06-14 17:46:37 +00:00
|
|
|
assert((ND->isUsed(false) || !isa<VarDecl>(ND) || E->isNonOdrUse() ||
|
2012-01-21 04:52:58 +00:00
|
|
|
!E->getLocation().isValid()) &&
|
|
|
|
|
"Should not use decl without marking it used!");
|
|
|
|
|
|
2010-03-04 18:17:24 +00:00
|
|
|
if (ND->hasAttr<WeakRefAttr>()) {
|
2014-05-09 00:08:36 +00:00
|
|
|
const auto *VD = cast<ValueDecl>(ND);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
ConstantAddress Aliasee = CGM.GetWeakRefReference(VD);
|
2017-10-10 09:39:32 +00:00
|
|
|
return MakeAddrLValue(Aliasee, T, AlignmentSource::Decl);
|
2010-03-04 18:17:24 +00:00
|
|
|
}
|
|
|
|
|
|
2014-05-27 16:46:27 +00:00
|
|
|
if (const auto *VD = dyn_cast<VarDecl>(ND)) {
|
2009-11-07 22:53:10 +00:00
|
|
|
// Check if this is a global variable.
|
2014-03-26 22:48:22 +00:00
|
|
|
if (VD->hasLinkage() || VD->isStaticDataMember())
|
2009-11-07 23:06:58 +00:00
|
|
|
return EmitGlobalVarDeclLValue(*this, E, VD);
|
2009-11-07 22:43:34 +00: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 08:05:57 +00:00
|
|
|
Address addr = Address::invalid();
|
2012-03-10 09:33:50 +00: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 08:05:57 +00:00
|
|
|
// The variable should generally be present in the local decl map.
|
|
|
|
|
auto iter = LocalDeclMap.find(VD);
|
|
|
|
|
if (iter != LocalDeclMap.end()) {
|
|
|
|
|
addr = iter->second;
|
2012-02-11 02:57:39 +00: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 08:05:57 +00:00
|
|
|
// Otherwise, it might be static local we haven't emitted yet for
|
|
|
|
|
// some reason; most likely, because it's in an outer function.
|
|
|
|
|
} else if (VD->isStaticLocal()) {
|
|
|
|
|
addr = Address(CGM.getOrCreateStaticVarDecl(
|
2019-07-16 04:46:31 +00:00
|
|
|
*VD, CGM.getLLVMLinkageVarDefinition(VD, /*IsConstant=*/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 08:05:57 +00:00
|
|
|
getContext().getDeclAlign(VD));
|
|
|
|
|
|
|
|
|
|
// No other cases for now.
|
|
|
|
|
} else {
|
|
|
|
|
llvm_unreachable("DeclRefExpr for Decl not entered in LocalDeclMap?");
|
|
|
|
|
}
|
2014-11-11 04:05:39 +00:00
|
|
|
|
2009-09-24 19:53:00 +00: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 08:05:57 +00:00
|
|
|
// Check for OpenMP threadprivate variables.
|
2017-12-29 18:07:07 +00:00
|
|
|
if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd &&
|
|
|
|
|
VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
return EmitThreadPrivateVarDeclLValue(
|
|
|
|
|
*this, VD, T, addr, getTypes().ConvertTypeForMem(VD->getType()),
|
|
|
|
|
E->getExprLoc());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Drill into block byref variables.
|
2018-10-01 21:51:28 +00:00
|
|
|
bool isBlockByref = VD->isEscapingByref();
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
if (isBlockByref) {
|
|
|
|
|
addr = emitBlockByrefAddress(addr, VD);
|
|
|
|
|
}
|
2010-08-21 03:44:13 +00: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 08:05:57 +00:00
|
|
|
// Drill into reference types.
|
2017-10-30 11:49:31 +00:00
|
|
|
LValue LV = VD->getType()->isReferenceType() ?
|
|
|
|
|
EmitLoadOfReferenceLValue(addr, VD->getType(), AlignmentSource::Decl) :
|
|
|
|
|
MakeAddrLValue(addr, T, AlignmentSource::Decl);
|
2011-07-12 06:52:18 +00:00
|
|
|
|
2013-03-13 03:10:54 +00:00
|
|
|
bool isLocalStorage = VD->hasLocalStorage();
|
|
|
|
|
|
|
|
|
|
bool NonGCable = isLocalStorage &&
|
|
|
|
|
!VD->getType()->isReferenceType() &&
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
!isBlockByref;
|
2010-11-19 18:17:09 +00:00
|
|
|
if (NonGCable) {
|
2010-08-21 03:44:13 +00:00
|
|
|
LV.getQuals().removeObjCGCAttr();
|
2010-08-21 03:22:38 +00:00
|
|
|
LV.setNonGC(true);
|
|
|
|
|
}
|
2013-03-13 03:10:54 +00:00
|
|
|
|
|
|
|
|
bool isImpreciseLifetime =
|
|
|
|
|
(isLocalStorage && !VD->hasAttr<ObjCPreciseLifetimeAttr>());
|
|
|
|
|
if (isImpreciseLifetime)
|
|
|
|
|
LV.setARCPreciseLifetime(ARCImpreciseLifetime);
|
2009-09-16 21:37:16 +00:00
|
|
|
setObjCGCLValueClass(getContext(), E, LV);
|
2008-11-20 00:15:42 +00:00
|
|
|
return LV;
|
2009-10-28 17:39:19 +00:00
|
|
|
}
|
2011-02-03 08:15:49 +00:00
|
|
|
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *FD = dyn_cast<FunctionDecl>(ND))
|
2013-11-05 09:12:18 +00:00
|
|
|
return EmitFunctionDeclLValue(*this, E, FD);
|
2011-02-03 08:15:49 +00:00
|
|
|
|
2016-08-15 01:33:41 +00:00
|
|
|
// FIXME: While we're emitting a binding from an enclosing scope, all other
|
|
|
|
|
// DeclRefExprs we see should be implicitly treated as if they also refer to
|
|
|
|
|
// an enclosing scope.
|
|
|
|
|
if (const auto *BD = dyn_cast<BindingDecl>(ND))
|
|
|
|
|
return EmitLValue(BD->getBinding());
|
|
|
|
|
|
Rework how UuidAttr, CXXUuidofExpr, and GUID template arguments and constants are represented.
Summary:
Previously, we treated CXXUuidofExpr as quite a special case: it was the
only kind of expression that could be a canonical template argument, it
could be a constant lvalue base object, and so on. In addition, we
represented the UUID value as a string, whose source form we did not
preserve faithfully, and that we partially parsed in multiple different
places.
With this patch, we create an MSGuidDecl object to represent the
implicit object of type 'struct _GUID' created by a UuidAttr. Each
UuidAttr holds a pointer to its 'struct _GUID' and its original
(as-written) UUID string. A non-value-dependent CXXUuidofExpr behaves
like a DeclRefExpr denoting that MSGuidDecl object. We cache an APValue
representation of the GUID on the MSGuidDecl and use it from constant
evaluation where needed.
This allows removing a lot of the special-case logic to handle these
expressions. Unfortunately, many parts of Clang assume there are only
a couple of interesting kinds of ValueDecl, so the total amount of
special-case logic is not really reduced very much.
This fixes a few bugs and issues:
* PR38490: we now support reading from GUID objects returned from
__uuidof during constant evaluation.
* Our Itanium mangling for a non-instantiation-dependent template
argument involving __uuidof no longer depends on which CXXUuidofExpr
template argument we happened to see first.
* We now predeclare ::_GUID, and permit use of __uuidof without
any header inclusion, better matching MSVC's behavior. We do not
predefine ::__s_GUID, though; that seems like a step too far.
* Our IR representation for GUID constants now uses the correct IR type
wherever possible. We will still fall back to using the
{i32, i16, i16, [8 x i8]}
layout if a definition of struct _GUID is not available. This is not
ideal: in principle the two layouts could have different padding.
Reviewers: rnk, jdoerfert
Subscribers: arphaman, cfe-commits, aeubanks
Tags: #clang
Differential Revision: https://reviews.llvm.org/D78171
2020-04-11 22:15:29 -07:00
|
|
|
// We can form DeclRefExprs naming GUID declarations when reconstituting
|
|
|
|
|
// non-type template parameters into expressions.
|
|
|
|
|
if (const auto *GD = dyn_cast<MSGuidDecl>(ND))
|
|
|
|
|
return MakeAddrLValue(CGM.GetAddrOfMSGuidDecl(GD), T,
|
|
|
|
|
AlignmentSource::Decl);
|
|
|
|
|
|
2020-09-20 23:16:08 -07:00
|
|
|
if (const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND))
|
|
|
|
|
return MakeAddrLValue(CGM.GetAddrOfTemplateParamObject(TPO), T,
|
|
|
|
|
AlignmentSource::Decl);
|
|
|
|
|
|
2011-09-23 05:06:16 +00:00
|
|
|
llvm_unreachable("Unhandled DeclRefExpr");
|
2007-06-02 05:24:33 +00:00
|
|
|
}
|
2007-06-01 18:02:12 +00:00
|
|
|
|
2007-06-05 20:53:16 +00:00
|
|
|
LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
|
|
|
|
|
// __extension__ doesn't affect lvalue-ness.
|
2010-08-25 11:45:40 +00:00
|
|
|
if (E->getOpcode() == UO_Extension)
|
2007-06-05 20:53:16 +00:00
|
|
|
return EmitLValue(E->getSubExpr());
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2008-07-26 22:37:01 +00:00
|
|
|
QualType ExprTy = getContext().getCanonicalType(E->getSubExpr()->getType());
|
2007-10-30 22:53:42 +00:00
|
|
|
switch (E->getOpcode()) {
|
2011-09-23 05:06:16 +00:00
|
|
|
default: llvm_unreachable("Unknown unary operator lvalue!");
|
2010-08-25 11:45:40 +00:00
|
|
|
case UO_Deref: {
|
2009-10-28 17:39:19 +00:00
|
|
|
QualType T = E->getSubExpr()->getType()->getPointeeType();
|
|
|
|
|
assert(!T.isNull() && "CodeGenFunction::EmitUnaryOpLValue: Illegal type");
|
|
|
|
|
|
2017-05-18 17:07:11 +00:00
|
|
|
LValueBaseInfo BaseInfo;
|
2017-10-17 09:12:13 +00:00
|
|
|
TBAAAccessInfo TBAAInfo;
|
|
|
|
|
Address Addr = EmitPointerWithAlignment(E->getSubExpr(), &BaseInfo,
|
|
|
|
|
&TBAAInfo);
|
|
|
|
|
LValue LV = MakeAddrLValue(Addr, T, BaseInfo, TBAAInfo);
|
2010-08-21 03:44:13 +00:00
|
|
|
LV.getQuals().setAddressSpace(ExprTy.getAddressSpace());
|
2009-10-28 17:39:19 +00:00
|
|
|
|
|
|
|
|
// We should not generate __weak write barrier on indirect reference
|
|
|
|
|
// of a pointer to object; as in void foo (__weak id *param); *param = 0;
|
|
|
|
|
// But, we continue to generate __strong write barrier on indirect write
|
|
|
|
|
// into a pointer to object.
|
2018-10-30 20:31:30 +00:00
|
|
|
if (getLangOpts().ObjC &&
|
2012-11-01 22:30:59 +00:00
|
|
|
getLangOpts().getGC() != LangOptions::NonGC &&
|
2009-10-28 17:39:19 +00:00
|
|
|
LV.isObjCWeak())
|
2010-08-21 03:22:38 +00:00
|
|
|
LV.setNonGC(!E->isOBJCGCCandidate(getContext()));
|
2009-10-28 17:39:19 +00:00
|
|
|
return LV;
|
|
|
|
|
}
|
2010-08-25 11:45:40 +00:00
|
|
|
case UO_Real:
|
|
|
|
|
case UO_Imag: {
|
2007-10-30 22:53:42 +00:00
|
|
|
LValue LV = EmitLValue(E->getSubExpr());
|
2010-12-05 02:00:02 +00:00
|
|
|
assert(LV.isSimple() && "real/imag on non-ordinary l-value");
|
|
|
|
|
|
2012-02-18 20:53:32 +00:00
|
|
|
// __real is valid on scalars. This is a faster way of testing that.
|
|
|
|
|
// __imag can only produce an rvalue on scalars.
|
|
|
|
|
if (E->getOpcode() == UO_Real &&
|
2019-12-03 15:17:01 -08:00
|
|
|
!LV.getAddress(*this).getElementType()->isStructTy()) {
|
2010-12-05 02:00:02 +00:00
|
|
|
assert(E->getSubExpr()->getType()->isArithmeticType());
|
|
|
|
|
return LV;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-07 18:15:02 +00:00
|
|
|
QualType T = ExprTy->castAs<ComplexType>()->getElementType();
|
2010-12-05 02:00:02 +00: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 08:05:57 +00:00
|
|
|
Address Component =
|
2019-12-03 15:17:01 -08:00
|
|
|
(E->getOpcode() == UO_Real
|
|
|
|
|
? emitAddrOfRealComponent(LV.getAddress(*this), LV.getType())
|
|
|
|
|
: emitAddrOfImagComponent(LV.getAddress(*this), LV.getType()));
|
2017-10-12 11:29:46 +00:00
|
|
|
LValue ElemLV = MakeAddrLValue(Component, T, LV.getBaseInfo(),
|
2017-10-31 11:05:34 +00:00
|
|
|
CGM.getTBAAInfoForSubobject(LV, T));
|
2016-11-07 18:15:02 +00:00
|
|
|
ElemLV.getQuals().addQualifiers(LV.getQuals());
|
|
|
|
|
return ElemLV;
|
2007-10-30 22:53:42 +00:00
|
|
|
}
|
2010-08-25 11:45:40 +00:00
|
|
|
case UO_PreInc:
|
|
|
|
|
case UO_PreDec: {
|
2010-01-09 21:44:40 +00:00
|
|
|
LValue LV = EmitLValue(E->getSubExpr());
|
2010-08-25 11:45:40 +00:00
|
|
|
bool isInc = E->getOpcode() == UO_PreInc;
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2010-01-09 21:44:40 +00:00
|
|
|
if (E->getType()->isAnyComplexType())
|
|
|
|
|
EmitComplexPrePostIncDec(E, LV, isInc, true/*isPre*/);
|
|
|
|
|
else
|
|
|
|
|
EmitScalarPrePostIncDec(E, LV, isInc, true/*isPre*/);
|
|
|
|
|
return LV;
|
|
|
|
|
}
|
2009-11-09 04:20:47 +00:00
|
|
|
}
|
2007-06-05 20:53:16 +00:00
|
|
|
}
|
|
|
|
|
|
2007-06-06 04:54:52 +00:00
|
|
|
LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) {
|
2010-08-21 03:15:20 +00:00
|
|
|
return MakeAddrLValue(CGM.GetAddrOfConstantStringFromLiteral(E),
|
2017-10-10 09:39:32 +00:00
|
|
|
E->getType(), AlignmentSource::Decl);
|
2007-06-06 04:54:52 +00:00
|
|
|
}
|
|
|
|
|
|
2009-02-24 22:18:39 +00:00
|
|
|
LValue CodeGenFunction::EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E) {
|
2010-08-21 03:15:20 +00:00
|
|
|
return MakeAddrLValue(CGM.GetAddrOfConstantStringFromObjCEncode(E),
|
2017-10-10 09:39:32 +00:00
|
|
|
E->getType(), AlignmentSource::Decl);
|
2009-02-24 22:18:39 +00:00
|
|
|
}
|
|
|
|
|
|
2010-08-21 03:01:12 +00:00
|
|
|
LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
|
2014-10-09 08:45:04 +00:00
|
|
|
auto SL = E->getFunctionName();
|
|
|
|
|
assert(SL != nullptr && "No StringLiteral name in PredefinedExpr");
|
|
|
|
|
StringRef FnName = CurFn->getName();
|
|
|
|
|
if (FnName.startswith("\01"))
|
|
|
|
|
FnName = FnName.substr(1);
|
|
|
|
|
StringRef NameItems[] = {
|
2018-10-27 19:21:19 +00:00
|
|
|
PredefinedExpr::getIdentKindName(E->getIdentKind()), FnName};
|
2014-10-09 08:45:04 +00:00
|
|
|
std::string GVName = llvm::join(NameItems, NameItems + 2, ".");
|
2018-04-11 18:17:35 +00:00
|
|
|
if (auto *BD = dyn_cast_or_null<BlockDecl>(CurCodeDecl)) {
|
2020-01-28 20:23:46 +01:00
|
|
|
std::string Name = std::string(SL->getString());
|
2016-11-16 07:07:28 +00:00
|
|
|
if (!Name.empty()) {
|
|
|
|
|
unsigned Discriminator =
|
|
|
|
|
CGM.getCXXABI().getMangleContext().getBlockId(BD, true);
|
|
|
|
|
if (Discriminator)
|
|
|
|
|
Name += "_" + Twine(Discriminator + 1).str();
|
|
|
|
|
auto C = CGM.GetAddrOfConstantCString(Name, GVName.c_str());
|
2017-10-10 09:39:32 +00:00
|
|
|
return MakeAddrLValue(C, E->getType(), AlignmentSource::Decl);
|
2016-11-16 07:07:28 +00:00
|
|
|
} else {
|
2020-01-28 20:23:46 +01:00
|
|
|
auto C =
|
|
|
|
|
CGM.GetAddrOfConstantCString(std::string(FnName), GVName.c_str());
|
2017-10-10 09:39:32 +00:00
|
|
|
return MakeAddrLValue(C, E->getType(), AlignmentSource::Decl);
|
2016-11-16 07:07:28 +00:00
|
|
|
}
|
2014-11-14 23:55:27 +00:00
|
|
|
}
|
2014-10-09 08:45:04 +00:00
|
|
|
auto C = CGM.GetAddrOfConstantStringFromLiteral(SL, GVName);
|
2017-10-10 09:39:32 +00:00
|
|
|
return MakeAddrLValue(C, E->getType(), AlignmentSource::Decl);
|
2007-07-21 05:21:51 +00:00
|
|
|
}
|
|
|
|
|
|
2012-10-09 19:52:38 +00:00
|
|
|
/// Emit a type description suitable for use by a runtime sanitizer library. The
|
|
|
|
|
/// format of a type descriptor is
|
|
|
|
|
///
|
|
|
|
|
/// \code
|
2012-10-09 23:55:19 +00:00
|
|
|
/// { i16 TypeKind, i16 TypeInfo }
|
2012-10-09 19:52:38 +00:00
|
|
|
/// \endcode
|
|
|
|
|
///
|
2012-10-09 23:55:19 +00:00
|
|
|
/// followed by an array of i8 containing the type name. TypeKind is 0 for an
|
|
|
|
|
/// integer, 1 for a floating point value, and -1 for anything else.
|
2012-10-09 19:52:38 +00:00
|
|
|
llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) {
|
2013-11-08 01:09:22 +00:00
|
|
|
// Only emit each type's descriptor once.
|
2014-05-23 16:07:43 +00:00
|
|
|
if (llvm::Constant *C = CGM.getTypeDescriptorFromMap(T))
|
2013-11-08 01:09:22 +00:00
|
|
|
return C;
|
|
|
|
|
|
2012-10-09 19:52:38 +00:00
|
|
|
uint16_t TypeKind = -1;
|
|
|
|
|
uint16_t TypeInfo = 0;
|
|
|
|
|
|
|
|
|
|
if (T->isIntegerType()) {
|
|
|
|
|
TypeKind = 0;
|
|
|
|
|
TypeInfo = (llvm::Log2_32(getContext().getTypeSize(T)) << 1) |
|
2012-11-30 21:44:01 +00:00
|
|
|
(T->isSignedIntegerType() ? 1 : 0);
|
2012-10-09 19:52:38 +00:00
|
|
|
} else if (T->isFloatingType()) {
|
|
|
|
|
TypeKind = 1;
|
|
|
|
|
TypeInfo = getContext().getTypeSize(T);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Format the type name as if for a diagnostic, including quotes and
|
|
|
|
|
// optionally an 'aka'.
|
2013-01-12 19:30:44 +00:00
|
|
|
SmallString<32> Buffer;
|
2012-10-09 19:52:38 +00:00
|
|
|
CGM.getDiags().ConvertArgToString(DiagnosticsEngine::ak_qualtype,
|
|
|
|
|
(intptr_t)T.getAsOpaquePtr(),
|
2014-06-12 05:32:35 +00:00
|
|
|
StringRef(), StringRef(), None, Buffer,
|
2014-08-27 06:28:36 +00:00
|
|
|
None);
|
2012-10-09 19:52:38 +00:00
|
|
|
|
|
|
|
|
llvm::Constant *Components[] = {
|
2012-10-09 23:55:19 +00:00
|
|
|
Builder.getInt16(TypeKind), Builder.getInt16(TypeInfo),
|
|
|
|
|
llvm::ConstantDataArray::getString(getLLVMContext(), Buffer)
|
2012-10-09 19:52:38 +00:00
|
|
|
};
|
|
|
|
|
llvm::Constant *Descriptor = llvm::ConstantStruct::getAnon(Components);
|
2009-12-15 00:59:40 +00:00
|
|
|
|
2014-05-09 00:08:36 +00:00
|
|
|
auto *GV = new llvm::GlobalVariable(
|
|
|
|
|
CGM.getModule(), Descriptor->getType(),
|
|
|
|
|
/*isConstant=*/true, llvm::GlobalVariable::PrivateLinkage, Descriptor);
|
2016-06-14 21:02:05 +00:00
|
|
|
GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
|
2014-08-01 21:35:28 +00:00
|
|
|
CGM.getSanitizerMetadata()->disableSanitizerForGlobal(GV);
|
2013-11-08 01:09:22 +00:00
|
|
|
|
|
|
|
|
// Remember the descriptor for this type.
|
2014-05-23 16:07:43 +00:00
|
|
|
CGM.setTypeDescriptorInMap(T, GV);
|
2013-11-08 01:09:22 +00:00
|
|
|
|
2012-10-09 19:52:38 +00:00
|
|
|
return GV;
|
|
|
|
|
}
|
2012-09-08 02:08:36 +00:00
|
|
|
|
2012-10-09 19:52:38 +00:00
|
|
|
llvm::Value *CodeGenFunction::EmitCheckValue(llvm::Value *V) {
|
|
|
|
|
llvm::Type *TargetTy = IntPtrTy;
|
|
|
|
|
|
2017-10-03 01:27:24 +00:00
|
|
|
if (V->getType() == TargetTy)
|
|
|
|
|
return V;
|
|
|
|
|
|
2013-03-22 00:47:07 +00:00
|
|
|
// Floating-point types which fit into intptr_t are bitcast to integers
|
|
|
|
|
// and then passed directly (after zero-extension, if necessary).
|
|
|
|
|
if (V->getType()->isFloatingPointTy()) {
|
2020-10-13 13:41:54 +01:00
|
|
|
unsigned Bits = V->getType()->getPrimitiveSizeInBits().getFixedSize();
|
2013-03-22 00:47:07 +00:00
|
|
|
if (Bits <= TargetTy->getIntegerBitWidth())
|
|
|
|
|
V = Builder.CreateBitCast(V, llvm::Type::getIntNTy(getLLVMContext(),
|
|
|
|
|
Bits));
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-09 19:52:38 +00:00
|
|
|
// Integers which fit in intptr_t are zero-extended and passed directly.
|
|
|
|
|
if (V->getType()->isIntegerTy() &&
|
|
|
|
|
V->getType()->getIntegerBitWidth() <= TargetTy->getIntegerBitWidth())
|
|
|
|
|
return Builder.CreateZExt(V, TargetTy);
|
|
|
|
|
|
|
|
|
|
// Pointers are passed directly, everything else is passed by address.
|
|
|
|
|
if (!V->getType()->isPointerTy()) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Address Ptr = CreateDefaultAlignTempAlloca(V->getType());
|
2012-10-09 19:52:38 +00:00
|
|
|
Builder.CreateStore(V, Ptr);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
V = Ptr.getPointer();
|
2012-10-09 19:52:38 +00:00
|
|
|
}
|
|
|
|
|
return Builder.CreatePtrToInt(V, TargetTy);
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Emit a representation of a SourceLocation for passing to a handler
|
2012-10-09 19:52:38 +00:00
|
|
|
/// in a sanitizer runtime library. The format for this data is:
|
|
|
|
|
/// \code
|
|
|
|
|
/// struct SourceLocation {
|
|
|
|
|
/// const char *Filename;
|
|
|
|
|
/// int32_t Line, Column;
|
|
|
|
|
/// };
|
|
|
|
|
/// \endcode
|
|
|
|
|
/// For an invalid SourceLocation, the Filename pointer is null.
|
|
|
|
|
llvm::Constant *CodeGenFunction::EmitCheckSourceLocation(SourceLocation Loc) {
|
2014-07-18 17:50:06 +00:00
|
|
|
llvm::Constant *Filename;
|
|
|
|
|
int Line, Column;
|
|
|
|
|
|
2012-10-09 19:52:38 +00:00
|
|
|
PresumedLoc PLoc = getContext().getSourceManager().getPresumedLoc(Loc);
|
2014-07-18 17:50:06 +00:00
|
|
|
if (PLoc.isValid()) {
|
2016-05-12 16:51:36 +00:00
|
|
|
StringRef FilenameString = PLoc.getFilename();
|
|
|
|
|
|
|
|
|
|
int PathComponentsToStrip =
|
|
|
|
|
CGM.getCodeGenOpts().EmitCheckPathComponentsToStrip;
|
|
|
|
|
if (PathComponentsToStrip < 0) {
|
|
|
|
|
assert(PathComponentsToStrip != INT_MIN);
|
|
|
|
|
int PathComponentsToKeep = -PathComponentsToStrip;
|
|
|
|
|
auto I = llvm::sys::path::rbegin(FilenameString);
|
|
|
|
|
auto E = llvm::sys::path::rend(FilenameString);
|
|
|
|
|
while (I != E && --PathComponentsToKeep)
|
|
|
|
|
++I;
|
|
|
|
|
|
|
|
|
|
FilenameString = FilenameString.substr(I - E);
|
|
|
|
|
} else if (PathComponentsToStrip > 0) {
|
|
|
|
|
auto I = llvm::sys::path::begin(FilenameString);
|
|
|
|
|
auto E = llvm::sys::path::end(FilenameString);
|
|
|
|
|
while (I != E && PathComponentsToStrip--)
|
|
|
|
|
++I;
|
|
|
|
|
|
|
|
|
|
if (I != E)
|
|
|
|
|
FilenameString =
|
|
|
|
|
FilenameString.substr(I - llvm::sys::path::begin(FilenameString));
|
|
|
|
|
else
|
|
|
|
|
FilenameString = llvm::sys::path::filename(FilenameString);
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-28 20:23:46 +01:00
|
|
|
auto FilenameGV =
|
|
|
|
|
CGM.GetAddrOfConstantCString(std::string(FilenameString), ".src");
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
CGM.getSanitizerMetadata()->disableSanitizerForGlobal(
|
|
|
|
|
cast<llvm::GlobalVariable>(FilenameGV.getPointer()));
|
|
|
|
|
Filename = FilenameGV.getPointer();
|
2014-07-18 17:50:06 +00:00
|
|
|
Line = PLoc.getLine();
|
|
|
|
|
Column = PLoc.getColumn();
|
|
|
|
|
} else {
|
|
|
|
|
Filename = llvm::Constant::getNullValue(Int8PtrTy);
|
|
|
|
|
Line = Column = 0;
|
|
|
|
|
}
|
2012-10-09 19:52:38 +00:00
|
|
|
|
2014-07-18 17:50:06 +00:00
|
|
|
llvm::Constant *Data[] = {Filename, Builder.getInt32(Line),
|
|
|
|
|
Builder.getInt32(Column)};
|
2012-09-08 02:08:36 +00:00
|
|
|
|
2012-10-09 19:52:38 +00:00
|
|
|
return llvm::ConstantStruct::getAnon(Data);
|
|
|
|
|
}
|
2012-09-08 02:08:36 +00:00
|
|
|
|
2014-11-10 22:27:30 +00:00
|
|
|
namespace {
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Specify under what conditions this check can be recovered
|
2014-11-10 22:27:30 +00:00
|
|
|
enum class CheckRecoverableKind {
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
/// Always terminate program execution if this check fails.
|
2014-11-10 22:27:30 +00:00
|
|
|
Unrecoverable,
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
/// Check supports recovering, runtime has both fatal (noreturn) and
|
|
|
|
|
/// non-fatal handlers for this check.
|
2014-11-10 22:27:30 +00:00
|
|
|
Recoverable,
|
|
|
|
|
/// Runtime conditionally aborts, always need to support recovery.
|
|
|
|
|
AlwaysRecoverable
|
|
|
|
|
};
|
2015-06-22 23:07:51 +00:00
|
|
|
}
|
2014-11-10 22:27:30 +00:00
|
|
|
|
2015-05-11 21:39:14 +00:00
|
|
|
static CheckRecoverableKind getRecoverableKind(SanitizerMask Kind) {
|
2019-03-01 10:05:15 +00:00
|
|
|
assert(Kind.countPopulation() == 1);
|
2019-07-16 06:23:27 +00:00
|
|
|
if (Kind == SanitizerKind::Function || Kind == SanitizerKind::Vptr)
|
2014-11-10 22:27:30 +00:00
|
|
|
return CheckRecoverableKind::AlwaysRecoverable;
|
2019-03-01 10:05:15 +00:00
|
|
|
else if (Kind == SanitizerKind::Return || Kind == SanitizerKind::Unreachable)
|
2014-11-10 22:27:30 +00:00
|
|
|
return CheckRecoverableKind::Unrecoverable;
|
2019-03-01 10:05:15 +00:00
|
|
|
else
|
2014-11-10 22:27:30 +00:00
|
|
|
return CheckRecoverableKind::Recoverable;
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-12 16:18:40 +00:00
|
|
|
namespace {
|
|
|
|
|
struct SanitizerHandlerInfo {
|
|
|
|
|
char const *const Name;
|
|
|
|
|
unsigned Version;
|
|
|
|
|
};
|
2016-12-13 03:27:35 +00:00
|
|
|
}
|
2016-12-12 16:18:40 +00:00
|
|
|
|
|
|
|
|
const SanitizerHandlerInfo SanitizerHandlers[] = {
|
|
|
|
|
#define SANITIZER_CHECK(Enum, Name, Version) {#Name, Version},
|
|
|
|
|
LIST_SANITIZER_CHECKS
|
|
|
|
|
#undef SANITIZER_CHECK
|
|
|
|
|
};
|
|
|
|
|
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
static void emitCheckHandlerCall(CodeGenFunction &CGF,
|
|
|
|
|
llvm::FunctionType *FnType,
|
|
|
|
|
ArrayRef<llvm::Value *> FnArgs,
|
2016-12-12 16:18:40 +00:00
|
|
|
SanitizerHandler CheckHandler,
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
CheckRecoverableKind RecoverKind, bool IsFatal,
|
|
|
|
|
llvm::BasicBlock *ContBB) {
|
|
|
|
|
assert(IsFatal || RecoverKind != CheckRecoverableKind::Unrecoverable);
|
2018-11-28 21:44:06 +00:00
|
|
|
Optional<ApplyDebugLocation> DL;
|
|
|
|
|
if (!CGF.Builder.getCurrentDebugLocation()) {
|
|
|
|
|
// Ensure that the call has at least an artificial debug location.
|
|
|
|
|
DL.emplace(CGF, SourceLocation());
|
|
|
|
|
}
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
bool NeedsAbortSuffix =
|
|
|
|
|
IsFatal && RecoverKind != CheckRecoverableKind::Unrecoverable;
|
2017-08-29 20:03:51 +00:00
|
|
|
bool MinimalRuntime = CGF.CGM.getCodeGenOpts().SanitizeMinimalRuntime;
|
2016-12-12 16:18:40 +00:00
|
|
|
const SanitizerHandlerInfo &CheckInfo = SanitizerHandlers[CheckHandler];
|
|
|
|
|
const StringRef CheckName = CheckInfo.Name;
|
2017-08-29 20:03:51 +00:00
|
|
|
std::string FnName = "__ubsan_handle_" + CheckName.str();
|
|
|
|
|
if (CheckInfo.Version && !MinimalRuntime)
|
|
|
|
|
FnName += "_v" + llvm::utostr(CheckInfo.Version);
|
|
|
|
|
if (MinimalRuntime)
|
|
|
|
|
FnName += "_minimal";
|
|
|
|
|
if (NeedsAbortSuffix)
|
|
|
|
|
FnName += "_abort";
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
bool MayReturn =
|
|
|
|
|
!IsFatal || RecoverKind == CheckRecoverableKind::AlwaysRecoverable;
|
|
|
|
|
|
|
|
|
|
llvm::AttrBuilder B;
|
|
|
|
|
if (!MayReturn) {
|
|
|
|
|
B.addAttribute(llvm::Attribute::NoReturn)
|
|
|
|
|
.addAttribute(llvm::Attribute::NoUnwind);
|
|
|
|
|
}
|
|
|
|
|
B.addAttribute(llvm::Attribute::UWTable);
|
|
|
|
|
|
2019-02-05 16:42:33 +00:00
|
|
|
llvm::FunctionCallee Fn = CGF.CGM.CreateRuntimeFunction(
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
FnType, FnName,
|
2017-03-21 16:57:30 +00:00
|
|
|
llvm::AttributeList::get(CGF.getLLVMContext(),
|
|
|
|
|
llvm::AttributeList::FunctionIndex, B),
|
2016-12-15 16:30:20 +00:00
|
|
|
/*Local=*/true);
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
llvm::CallInst *HandlerCall = CGF.EmitNounwindRuntimeCall(Fn, FnArgs);
|
|
|
|
|
if (!MayReturn) {
|
|
|
|
|
HandlerCall->setDoesNotReturn();
|
|
|
|
|
CGF.Builder.CreateUnreachable();
|
|
|
|
|
} else {
|
|
|
|
|
CGF.Builder.CreateBr(ContBB);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-11 22:03:54 +00:00
|
|
|
void CodeGenFunction::EmitCheck(
|
2015-05-11 21:39:14 +00:00
|
|
|
ArrayRef<std::pair<llvm::Value *, SanitizerMask>> Checked,
|
2016-12-12 16:18:40 +00:00
|
|
|
SanitizerHandler CheckHandler, ArrayRef<llvm::Constant *> StaticArgs,
|
2014-11-11 22:03:54 +00:00
|
|
|
ArrayRef<llvm::Value *> DynamicArgs) {
|
2014-07-17 18:46:27 +00:00
|
|
|
assert(IsSanitizerScope);
|
2014-11-11 22:03:54 +00:00
|
|
|
assert(Checked.size() > 0);
|
2016-12-12 16:18:40 +00:00
|
|
|
assert(CheckHandler >= 0 &&
|
2017-12-14 22:07:03 +00:00
|
|
|
size_t(CheckHandler) < llvm::array_lengthof(SanitizerHandlers));
|
2016-12-12 16:18:40 +00:00
|
|
|
const StringRef CheckName = SanitizerHandlers[CheckHandler].Name;
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
|
|
|
|
|
llvm::Value *FatalCond = nullptr;
|
|
|
|
|
llvm::Value *RecoverableCond = nullptr;
|
2015-06-18 23:59:22 +00:00
|
|
|
llvm::Value *TrapCond = nullptr;
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
for (int i = 0, n = Checked.size(); i < n; ++i) {
|
|
|
|
|
llvm::Value *Check = Checked[i].first;
|
2015-06-18 23:59:22 +00:00
|
|
|
// -fsanitize-trap= overrides -fsanitize-recover=.
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
llvm::Value *&Cond =
|
2015-06-18 23:59:22 +00:00
|
|
|
CGM.getCodeGenOpts().SanitizeTrap.has(Checked[i].second)
|
|
|
|
|
? TrapCond
|
|
|
|
|
: CGM.getCodeGenOpts().SanitizeRecover.has(Checked[i].second)
|
|
|
|
|
? RecoverableCond
|
|
|
|
|
: FatalCond;
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
Cond = Cond ? Builder.CreateAnd(Cond, Check) : Check;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-18 23:59:22 +00:00
|
|
|
if (TrapCond)
|
2020-10-21 10:11:25 +01:00
|
|
|
EmitTrapCheck(TrapCond, CheckHandler);
|
2015-06-18 23:59:22 +00:00
|
|
|
if (!FatalCond && !RecoverableCond)
|
|
|
|
|
return;
|
|
|
|
|
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
llvm::Value *JointCond;
|
|
|
|
|
if (FatalCond && RecoverableCond)
|
|
|
|
|
JointCond = Builder.CreateAnd(FatalCond, RecoverableCond);
|
|
|
|
|
else
|
|
|
|
|
JointCond = FatalCond ? FatalCond : RecoverableCond;
|
|
|
|
|
assert(JointCond);
|
|
|
|
|
|
2014-11-11 22:03:54 +00:00
|
|
|
CheckRecoverableKind RecoverKind = getRecoverableKind(Checked[0].second);
|
2016-03-15 20:19:29 +00:00
|
|
|
assert(SanOpts.has(Checked[0].second));
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
#ifndef NDEBUG
|
2014-11-11 22:03:54 +00:00
|
|
|
for (int i = 1, n = Checked.size(); i < n; ++i) {
|
|
|
|
|
assert(RecoverKind == getRecoverableKind(Checked[i].second) &&
|
2014-11-10 22:27:30 +00:00
|
|
|
"All recoverable kinds in a single check must be same!");
|
2016-03-15 20:19:29 +00:00
|
|
|
assert(SanOpts.has(Checked[i].second));
|
2014-11-11 22:03:54 +00:00
|
|
|
}
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
#endif
|
2013-01-29 23:31:22 +00:00
|
|
|
|
2012-10-09 19:52:38 +00:00
|
|
|
llvm::BasicBlock *Cont = createBasicBlock("cont");
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
llvm::BasicBlock *Handlers = createBasicBlock("handler." + CheckName);
|
|
|
|
|
llvm::Instruction *Branch = Builder.CreateCondBr(JointCond, Cont, Handlers);
|
2012-12-15 01:39:14 +00:00
|
|
|
// Give hint that we very much don't expect to execute the handler
|
|
|
|
|
// Value chosen to match UR_NONTAKEN_WEIGHT, see BranchProbabilityInfo.cpp
|
|
|
|
|
llvm::MDBuilder MDHelper(getLLVMContext());
|
|
|
|
|
llvm::MDNode *Node = MDHelper.createBranchWeights((1U << 20) - 1, 1);
|
|
|
|
|
Branch->setMetadata(llvm::LLVMContext::MD_prof, Node);
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
EmitBlock(Handlers);
|
2012-12-15 01:39:14 +00:00
|
|
|
|
2016-01-25 23:34:52 +00:00
|
|
|
// Handler functions take an i8* pointing to the (handler-specific) static
|
|
|
|
|
// information block, followed by a sequence of intptr_t arguments
|
|
|
|
|
// representing operand values.
|
2013-01-12 19:30:44 +00:00
|
|
|
SmallVector<llvm::Value *, 4> Args;
|
|
|
|
|
SmallVector<llvm::Type *, 4> ArgTypes;
|
2017-08-29 20:03:51 +00:00
|
|
|
if (!CGM.getCodeGenOpts().SanitizeMinimalRuntime) {
|
|
|
|
|
Args.reserve(DynamicArgs.size() + 1);
|
|
|
|
|
ArgTypes.reserve(DynamicArgs.size() + 1);
|
|
|
|
|
|
|
|
|
|
// Emit handler arguments and create handler function type.
|
|
|
|
|
if (!StaticArgs.empty()) {
|
|
|
|
|
llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
|
|
|
|
|
auto *InfoPtr =
|
|
|
|
|
new llvm::GlobalVariable(CGM.getModule(), Info->getType(), false,
|
|
|
|
|
llvm::GlobalVariable::PrivateLinkage, Info);
|
|
|
|
|
InfoPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
|
|
|
|
|
CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr);
|
|
|
|
|
Args.push_back(Builder.CreateBitCast(InfoPtr, Int8PtrTy));
|
|
|
|
|
ArgTypes.push_back(Int8PtrTy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0, n = DynamicArgs.size(); i != n; ++i) {
|
|
|
|
|
Args.push_back(EmitCheckValue(DynamicArgs[i]));
|
|
|
|
|
ArgTypes.push_back(IntPtrTy);
|
|
|
|
|
}
|
2012-10-09 19:52:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llvm::FunctionType *FnType =
|
|
|
|
|
llvm::FunctionType::get(CGM.VoidTy, ArgTypes, false);
|
2012-12-02 19:50:33 +00:00
|
|
|
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
if (!FatalCond || !RecoverableCond) {
|
|
|
|
|
// Simple case: we need to generate a single handler call, either
|
|
|
|
|
// fatal, or non-fatal.
|
2016-12-12 16:18:40 +00:00
|
|
|
emitCheckHandlerCall(*this, FnType, Args, CheckHandler, RecoverKind,
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
(FatalCond != nullptr), Cont);
|
2012-10-25 02:14:12 +00:00
|
|
|
} else {
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
// Emit two handler calls: first one for set of unrecoverable checks,
|
|
|
|
|
// another one for recoverable.
|
|
|
|
|
llvm::BasicBlock *NonFatalHandlerBB =
|
|
|
|
|
createBasicBlock("non_fatal." + CheckName);
|
|
|
|
|
llvm::BasicBlock *FatalHandlerBB = createBasicBlock("fatal." + CheckName);
|
|
|
|
|
Builder.CreateCondBr(FatalCond, NonFatalHandlerBB, FatalHandlerBB);
|
|
|
|
|
EmitBlock(FatalHandlerBB);
|
2016-12-12 16:18:40 +00:00
|
|
|
emitCheckHandlerCall(*this, FnType, Args, CheckHandler, RecoverKind, true,
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
NonFatalHandlerBB);
|
|
|
|
|
EmitBlock(NonFatalHandlerBB);
|
2016-12-12 16:18:40 +00:00
|
|
|
emitCheckHandlerCall(*this, FnType, Args, CheckHandler, RecoverKind, false,
|
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
2015-01-12 22:39:12 +00:00
|
|
|
Cont);
|
2012-10-25 02:14:12 +00:00
|
|
|
}
|
2012-10-09 19:52:38 +00:00
|
|
|
|
2012-09-08 02:08:36 +00:00
|
|
|
EmitBlock(Cont);
|
2009-12-12 01:27:46 +00:00
|
|
|
}
|
|
|
|
|
|
2016-01-25 23:34:52 +00:00
|
|
|
void CodeGenFunction::EmitCfiSlowPathCheck(
|
|
|
|
|
SanitizerMask Kind, llvm::Value *Cond, llvm::ConstantInt *TypeId,
|
|
|
|
|
llvm::Value *Ptr, ArrayRef<llvm::Constant *> StaticArgs) {
|
2015-12-15 23:00:20 +00:00
|
|
|
llvm::BasicBlock *Cont = createBasicBlock("cfi.cont");
|
|
|
|
|
|
|
|
|
|
llvm::BasicBlock *CheckBB = createBasicBlock("cfi.slowpath");
|
|
|
|
|
llvm::BranchInst *BI = Builder.CreateCondBr(Cond, Cont, CheckBB);
|
|
|
|
|
|
|
|
|
|
llvm::MDBuilder MDHelper(getLLVMContext());
|
|
|
|
|
llvm::MDNode *Node = MDHelper.createBranchWeights((1U << 20) - 1, 1);
|
|
|
|
|
BI->setMetadata(llvm::LLVMContext::MD_prof, Node);
|
|
|
|
|
|
|
|
|
|
EmitBlock(CheckBB);
|
|
|
|
|
|
2016-01-25 23:34:52 +00:00
|
|
|
bool WithDiag = !CGM.getCodeGenOpts().SanitizeTrap.has(Kind);
|
|
|
|
|
|
|
|
|
|
llvm::CallInst *CheckCall;
|
[opaque pointer types] Add a FunctionCallee wrapper type, and use it.
Recommit r352791 after tweaking DerivedTypes.h slightly, so that gcc
doesn't choke on it, hopefully.
Original Message:
The FunctionCallee type is effectively a {FunctionType*,Value*} pair,
and is a useful convenience to enable code to continue passing the
result of getOrInsertFunction() through to EmitCall, even once pointer
types lose their pointee-type.
Then:
- update the CallInst/InvokeInst instruction creation functions to
take a Callee,
- modify getOrInsertFunction to return FunctionCallee, and
- update all callers appropriately.
One area of particular note is the change to the sanitizer
code. Previously, they had been casting the result of
`getOrInsertFunction` to a `Function*` via
`checkSanitizerInterfaceFunction`, and storing that. That would report
an error if someone had already inserted a function declaraction with
a mismatching signature.
However, in general, LLVM allows for such mismatches, as
`getOrInsertFunction` will automatically insert a bitcast if
needed. As part of this cleanup, cause the sanitizer code to do the
same. (It will call its functions using the expected signature,
however they may have been declared.)
Finally, in a small number of locations, callers of
`getOrInsertFunction` actually were expecting/requiring that a brand
new function was being created. In such cases, I've switched them to
Function::Create instead.
Differential Revision: https://reviews.llvm.org/D57315
llvm-svn: 352827
2019-02-01 02:28:03 +00:00
|
|
|
llvm::FunctionCallee SlowPathFn;
|
2016-01-25 23:34:52 +00:00
|
|
|
if (WithDiag) {
|
|
|
|
|
llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
|
|
|
|
|
auto *InfoPtr =
|
|
|
|
|
new llvm::GlobalVariable(CGM.getModule(), Info->getType(), false,
|
|
|
|
|
llvm::GlobalVariable::PrivateLinkage, Info);
|
2016-06-14 21:02:05 +00:00
|
|
|
InfoPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
|
2016-01-25 23:34:52 +00:00
|
|
|
CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr);
|
|
|
|
|
|
2018-03-29 22:08:01 +00:00
|
|
|
SlowPathFn = CGM.getModule().getOrInsertFunction(
|
2016-01-25 23:34:52 +00:00
|
|
|
"__cfi_slowpath_diag",
|
|
|
|
|
llvm::FunctionType::get(VoidTy, {Int64Ty, Int8PtrTy, Int8PtrTy},
|
|
|
|
|
false));
|
|
|
|
|
CheckCall = Builder.CreateCall(
|
2018-03-29 22:08:01 +00:00
|
|
|
SlowPathFn, {TypeId, Ptr, Builder.CreateBitCast(InfoPtr, Int8PtrTy)});
|
2016-01-25 23:34:52 +00:00
|
|
|
} else {
|
2018-03-29 22:08:01 +00:00
|
|
|
SlowPathFn = CGM.getModule().getOrInsertFunction(
|
2016-01-25 23:34:52 +00:00
|
|
|
"__cfi_slowpath",
|
|
|
|
|
llvm::FunctionType::get(VoidTy, {Int64Ty, Int8PtrTy}, false));
|
|
|
|
|
CheckCall = Builder.CreateCall(SlowPathFn, {TypeId, Ptr});
|
|
|
|
|
}
|
|
|
|
|
|
[opaque pointer types] Add a FunctionCallee wrapper type, and use it.
Recommit r352791 after tweaking DerivedTypes.h slightly, so that gcc
doesn't choke on it, hopefully.
Original Message:
The FunctionCallee type is effectively a {FunctionType*,Value*} pair,
and is a useful convenience to enable code to continue passing the
result of getOrInsertFunction() through to EmitCall, even once pointer
types lose their pointee-type.
Then:
- update the CallInst/InvokeInst instruction creation functions to
take a Callee,
- modify getOrInsertFunction to return FunctionCallee, and
- update all callers appropriately.
One area of particular note is the change to the sanitizer
code. Previously, they had been casting the result of
`getOrInsertFunction` to a `Function*` via
`checkSanitizerInterfaceFunction`, and storing that. That would report
an error if someone had already inserted a function declaraction with
a mismatching signature.
However, in general, LLVM allows for such mismatches, as
`getOrInsertFunction` will automatically insert a bitcast if
needed. As part of this cleanup, cause the sanitizer code to do the
same. (It will call its functions using the expected signature,
however they may have been declared.)
Finally, in a small number of locations, callers of
`getOrInsertFunction` actually were expecting/requiring that a brand
new function was being created. In such cases, I've switched them to
Function::Create instead.
Differential Revision: https://reviews.llvm.org/D57315
llvm-svn: 352827
2019-02-01 02:28:03 +00:00
|
|
|
CGM.setDSOLocal(
|
|
|
|
|
cast<llvm::GlobalValue>(SlowPathFn.getCallee()->stripPointerCasts()));
|
2015-12-15 23:00:20 +00:00
|
|
|
CheckCall->setDoesNotThrow();
|
|
|
|
|
|
|
|
|
|
EmitBlock(Cont);
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-07 23:00:38 +00:00
|
|
|
// Emit a stub for __cfi_check function so that the linker knows about this
|
|
|
|
|
// symbol in LTO mode.
|
|
|
|
|
void CodeGenFunction::EmitCfiCheckStub() {
|
|
|
|
|
llvm::Module *M = &CGM.getModule();
|
|
|
|
|
auto &Ctx = M->getContext();
|
|
|
|
|
llvm::Function *F = llvm::Function::Create(
|
|
|
|
|
llvm::FunctionType::get(VoidTy, {Int64Ty, Int8PtrTy, Int8PtrTy}, false),
|
|
|
|
|
llvm::GlobalValue::WeakAnyLinkage, "__cfi_check", M);
|
2018-03-29 20:51:30 +00:00
|
|
|
CGM.setDSOLocal(F);
|
2017-04-07 23:00:38 +00:00
|
|
|
llvm::BasicBlock *BB = llvm::BasicBlock::Create(Ctx, "entry", F);
|
|
|
|
|
// FIXME: consider emitting an intrinsic call like
|
|
|
|
|
// call void @llvm.cfi_check(i64 %0, i8* %1, i8* %2)
|
|
|
|
|
// which can be lowered in CrossDSOCFI pass to the actual contents of
|
|
|
|
|
// __cfi_check. This would allow inlining of __cfi_check calls.
|
|
|
|
|
llvm::CallInst::Create(
|
|
|
|
|
llvm::Intrinsic::getDeclaration(M, llvm::Intrinsic::trap), "", BB);
|
|
|
|
|
llvm::ReturnInst::Create(Ctx, nullptr, BB);
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-25 23:34:52 +00:00
|
|
|
// This function is basically a switch over the CFI failure kind, which is
|
|
|
|
|
// extracted from CFICheckFailData (1st function argument). Each case is either
|
|
|
|
|
// llvm.trap or a call to one of the two runtime handlers, based on
|
|
|
|
|
// -fsanitize-trap and -fsanitize-recover settings. Default case (invalid
|
|
|
|
|
// failure kind) traps, but this should really never happen. CFICheckFailData
|
|
|
|
|
// can be nullptr if the calling module has -fsanitize-trap behavior for this
|
|
|
|
|
// check kind; in this case __cfi_check_fail traps as well.
|
|
|
|
|
void CodeGenFunction::EmitCfiCheckFail() {
|
|
|
|
|
SanitizerScope SanScope(this);
|
|
|
|
|
FunctionArgList Args;
|
2017-06-09 13:40:18 +00:00
|
|
|
ImplicitParamDecl ArgData(getContext(), getContext().VoidPtrTy,
|
|
|
|
|
ImplicitParamDecl::Other);
|
|
|
|
|
ImplicitParamDecl ArgAddr(getContext(), getContext().VoidPtrTy,
|
|
|
|
|
ImplicitParamDecl::Other);
|
2016-01-25 23:34:52 +00:00
|
|
|
Args.push_back(&ArgData);
|
|
|
|
|
Args.push_back(&ArgAddr);
|
|
|
|
|
|
2016-03-11 04:30:31 +00:00
|
|
|
const CGFunctionInfo &FI =
|
|
|
|
|
CGM.getTypes().arrangeBuiltinFunctionDeclaration(getContext().VoidTy, Args);
|
2016-01-25 23:34:52 +00:00
|
|
|
|
|
|
|
|
llvm::Function *F = llvm::Function::Create(
|
|
|
|
|
llvm::FunctionType::get(VoidTy, {VoidPtrTy, VoidPtrTy}, false),
|
|
|
|
|
llvm::GlobalValue::WeakODRLinkage, "__cfi_check_fail", &CGM.getModule());
|
2019-11-25 12:28:11 -08:00
|
|
|
|
|
|
|
|
CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, F);
|
|
|
|
|
CGM.SetLLVMFunctionAttributesForDefinition(nullptr, F);
|
2016-01-25 23:34:52 +00:00
|
|
|
F->setVisibility(llvm::GlobalValue::HiddenVisibility);
|
|
|
|
|
|
|
|
|
|
StartFunction(GlobalDecl(), CGM.getContext().VoidTy, F, FI, Args,
|
|
|
|
|
SourceLocation());
|
|
|
|
|
|
2018-06-21 23:22:37 +00:00
|
|
|
// This function should not be affected by blacklist. This function does
|
|
|
|
|
// not have a source location, but "src:*" would still apply. Revert any
|
|
|
|
|
// changes to SanOpts made in StartFunction.
|
|
|
|
|
SanOpts = CGM.getLangOpts().Sanitize;
|
|
|
|
|
|
2016-01-25 23:34:52 +00:00
|
|
|
llvm::Value *Data =
|
|
|
|
|
EmitLoadOfScalar(GetAddrOfLocalVar(&ArgData), /*Volatile=*/false,
|
|
|
|
|
CGM.getContext().VoidPtrTy, ArgData.getLocation());
|
|
|
|
|
llvm::Value *Addr =
|
|
|
|
|
EmitLoadOfScalar(GetAddrOfLocalVar(&ArgAddr), /*Volatile=*/false,
|
|
|
|
|
CGM.getContext().VoidPtrTy, ArgAddr.getLocation());
|
|
|
|
|
|
|
|
|
|
// Data == nullptr means the calling module has trap behaviour for this check.
|
|
|
|
|
llvm::Value *DataIsNotNullPtr =
|
|
|
|
|
Builder.CreateICmpNE(Data, llvm::ConstantPointerNull::get(Int8PtrTy));
|
2020-10-21 10:11:25 +01:00
|
|
|
EmitTrapCheck(DataIsNotNullPtr, SanitizerHandler::CFICheckFail);
|
2016-01-25 23:34:52 +00:00
|
|
|
|
|
|
|
|
llvm::StructType *SourceLocationTy =
|
2017-05-09 19:31:30 +00:00
|
|
|
llvm::StructType::get(VoidPtrTy, Int32Ty, Int32Ty);
|
2016-01-25 23:34:52 +00:00
|
|
|
llvm::StructType *CfiCheckFailDataTy =
|
2017-05-09 19:31:30 +00:00
|
|
|
llvm::StructType::get(Int8Ty, SourceLocationTy, VoidPtrTy);
|
2016-01-25 23:34:52 +00:00
|
|
|
|
|
|
|
|
llvm::Value *V = Builder.CreateConstGEP2_32(
|
|
|
|
|
CfiCheckFailDataTy,
|
|
|
|
|
Builder.CreatePointerCast(Data, CfiCheckFailDataTy->getPointerTo(0)), 0,
|
|
|
|
|
0);
|
|
|
|
|
Address CheckKindAddr(V, getIntAlign());
|
|
|
|
|
llvm::Value *CheckKind = Builder.CreateLoad(CheckKindAddr);
|
|
|
|
|
|
2016-02-03 22:18:55 +00:00
|
|
|
llvm::Value *AllVtables = llvm::MetadataAsValue::get(
|
|
|
|
|
CGM.getLLVMContext(),
|
|
|
|
|
llvm::MDString::get(CGM.getLLVMContext(), "all-vtables"));
|
|
|
|
|
llvm::Value *ValidVtable = Builder.CreateZExt(
|
2016-06-24 21:21:46 +00:00
|
|
|
Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
|
2016-02-03 22:18:55 +00:00
|
|
|
{Addr, AllVtables}),
|
|
|
|
|
IntPtrTy);
|
|
|
|
|
|
2016-01-25 23:45:37 +00:00
|
|
|
const std::pair<int, SanitizerMask> CheckKinds[] = {
|
2016-01-25 23:34:52 +00:00
|
|
|
{CFITCK_VCall, SanitizerKind::CFIVCall},
|
|
|
|
|
{CFITCK_NVCall, SanitizerKind::CFINVCall},
|
|
|
|
|
{CFITCK_DerivedCast, SanitizerKind::CFIDerivedCast},
|
|
|
|
|
{CFITCK_UnrelatedCast, SanitizerKind::CFIUnrelatedCast},
|
|
|
|
|
{CFITCK_ICall, SanitizerKind::CFIICall}};
|
|
|
|
|
|
|
|
|
|
SmallVector<std::pair<llvm::Value *, SanitizerMask>, 5> Checks;
|
|
|
|
|
for (auto CheckKindMaskPair : CheckKinds) {
|
|
|
|
|
int Kind = CheckKindMaskPair.first;
|
|
|
|
|
SanitizerMask Mask = CheckKindMaskPair.second;
|
|
|
|
|
llvm::Value *Cond =
|
|
|
|
|
Builder.CreateICmpNE(CheckKind, llvm::ConstantInt::get(Int8Ty, Kind));
|
2016-03-15 20:19:29 +00:00
|
|
|
if (CGM.getLangOpts().Sanitize.has(Mask))
|
2016-12-12 16:18:40 +00:00
|
|
|
EmitCheck(std::make_pair(Cond, Mask), SanitizerHandler::CFICheckFail, {},
|
2016-03-15 20:19:29 +00:00
|
|
|
{Data, Addr, ValidVtable});
|
|
|
|
|
else
|
2020-10-21 10:11:25 +01:00
|
|
|
EmitTrapCheck(Cond, SanitizerHandler::CFICheckFail);
|
2016-01-25 23:34:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FinishFunction();
|
|
|
|
|
// The only reference to this function will be created during LTO link.
|
|
|
|
|
// Make sure it survives until then.
|
|
|
|
|
CGM.addUsedGlobal(F);
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-21 00:10:25 +00:00
|
|
|
void CodeGenFunction::EmitUnreachable(SourceLocation Loc) {
|
|
|
|
|
if (SanOpts.has(SanitizerKind::Unreachable)) {
|
|
|
|
|
SanitizerScope SanScope(this);
|
|
|
|
|
EmitCheck(std::make_pair(static_cast<llvm::Value *>(Builder.getFalse()),
|
|
|
|
|
SanitizerKind::Unreachable),
|
|
|
|
|
SanitizerHandler::BuiltinUnreachable,
|
|
|
|
|
EmitCheckSourceLocation(Loc), None);
|
|
|
|
|
}
|
|
|
|
|
Builder.CreateUnreachable();
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-21 10:11:25 +01:00
|
|
|
void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
|
|
|
|
|
SanitizerHandler CheckHandlerID) {
|
2012-11-01 22:15:34 +00:00
|
|
|
llvm::BasicBlock *Cont = createBasicBlock("cont");
|
|
|
|
|
|
|
|
|
|
// If we're optimizing, collapse all calls to trap down to just one per
|
2020-10-21 10:11:25 +01:00
|
|
|
// check-type per function to save on code size.
|
|
|
|
|
if (TrapBBs.size() <= CheckHandlerID)
|
|
|
|
|
TrapBBs.resize(CheckHandlerID + 1);
|
|
|
|
|
llvm::BasicBlock *&TrapBB = TrapBBs[CheckHandlerID];
|
|
|
|
|
|
2012-11-01 22:15:34 +00:00
|
|
|
if (!CGM.getCodeGenOpts().OptimizationLevel || !TrapBB) {
|
|
|
|
|
TrapBB = createBasicBlock("trap");
|
|
|
|
|
Builder.CreateCondBr(Checked, Cont, TrapBB);
|
|
|
|
|
EmitBlock(TrapBB);
|
2020-10-21 10:11:25 +01:00
|
|
|
|
|
|
|
|
llvm::CallInst *TrapCall =
|
|
|
|
|
Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
|
|
|
|
|
llvm::ConstantInt::get(CGM.Int8Ty, CheckHandlerID));
|
|
|
|
|
|
|
|
|
|
if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
|
|
|
|
|
auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
|
|
|
|
|
CGM.getCodeGenOpts().TrapFuncName);
|
|
|
|
|
TrapCall->addAttribute(llvm::AttributeList::FunctionIndex, A);
|
|
|
|
|
}
|
2012-11-01 22:15:34 +00:00
|
|
|
TrapCall->setDoesNotReturn();
|
|
|
|
|
TrapCall->setDoesNotThrow();
|
|
|
|
|
Builder.CreateUnreachable();
|
|
|
|
|
} else {
|
2020-10-21 10:11:25 +01:00
|
|
|
auto Call = TrapBB->begin();
|
|
|
|
|
assert(isa<llvm::CallInst>(Call) && "Expected call in trap BB");
|
|
|
|
|
|
|
|
|
|
Call->applyMergedLocation(Call->getDebugLoc(),
|
|
|
|
|
Builder.getCurrentDebugLocation());
|
2012-11-01 22:15:34 +00:00
|
|
|
Builder.CreateCondBr(Checked, Cont, TrapBB);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EmitBlock(Cont);
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-02 22:15:41 +00:00
|
|
|
llvm::CallInst *CodeGenFunction::EmitTrapCall(llvm::Intrinsic::ID IntrID) {
|
2020-10-21 10:11:25 +01:00
|
|
|
llvm::CallInst *TrapCall =
|
|
|
|
|
Builder.CreateCall(CGM.getIntrinsic(IntrID));
|
2015-07-02 22:15:41 +00:00
|
|
|
|
2016-09-09 04:42:49 +00:00
|
|
|
if (!CGM.getCodeGenOpts().TrapFuncName.empty()) {
|
|
|
|
|
auto A = llvm::Attribute::get(getLLVMContext(), "trap-func-name",
|
|
|
|
|
CGM.getCodeGenOpts().TrapFuncName);
|
2017-03-21 16:57:30 +00:00
|
|
|
TrapCall->addAttribute(llvm::AttributeList::FunctionIndex, A);
|
2016-09-09 04:42:49 +00:00
|
|
|
}
|
2015-07-02 22:15:41 +00:00
|
|
|
|
|
|
|
|
return TrapCall;
|
|
|
|
|
}
|
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Address CodeGenFunction::EmitArrayToPointerDecay(const Expr *E,
|
2017-10-17 09:12:13 +00:00
|
|
|
LValueBaseInfo *BaseInfo,
|
|
|
|
|
TBAAAccessInfo *TBAAInfo) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
assert(E->getType()->isArrayType() &&
|
|
|
|
|
"Array to pointer decay must have array source type!");
|
|
|
|
|
|
|
|
|
|
// Expressions of array type can't be bitfields or vector elements.
|
|
|
|
|
LValue LV = EmitLValue(E);
|
2019-12-03 15:17:01 -08:00
|
|
|
Address Addr = LV.getAddress(*this);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
|
|
|
|
|
// If the array type was an incomplete type, we need to make sure
|
|
|
|
|
// the decay ends up being the right type.
|
|
|
|
|
llvm::Type *NewTy = ConvertType(E->getType());
|
|
|
|
|
Addr = Builder.CreateElementBitCast(Addr, NewTy);
|
|
|
|
|
|
|
|
|
|
// Note that VLA pointers are always decayed, so we don't need to do
|
|
|
|
|
// anything here.
|
|
|
|
|
if (!E->getType()->isVariableArrayType()) {
|
|
|
|
|
assert(isa<llvm::ArrayType>(Addr.getElementType()) &&
|
|
|
|
|
"Expected pointer to array");
|
2019-02-08 15:34:12 +00:00
|
|
|
Addr = Builder.CreateConstArrayGEP(Addr, 0, "arraydecay");
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
}
|
|
|
|
|
|
2017-10-20 12:35:17 +00:00
|
|
|
// The result of this decay conversion points to an array element within the
|
|
|
|
|
// base lvalue. However, since TBAA currently does not support representing
|
|
|
|
|
// accesses to elements of member arrays, we conservatively represent accesses
|
|
|
|
|
// to the pointee object as if it had no any base lvalue specified.
|
|
|
|
|
// TODO: Support TBAA for member arrays.
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
QualType EltType = E->getType()->castAsArrayTypeUnsafe()->getElementType();
|
2017-10-20 12:35:17 +00:00
|
|
|
if (BaseInfo) *BaseInfo = LV.getBaseInfo();
|
|
|
|
|
if (TBAAInfo) *TBAAInfo = CGM.getTBAAAccessInfo(EltType);
|
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
return Builder.CreateElementBitCast(Addr, ConvertTypeForMem(EltType));
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-26 23:03:20 +00:00
|
|
|
/// isSimpleArrayDecayOperand - If the specified expr is a simple decay from an
|
|
|
|
|
/// array to pointer, return the array subexpression.
|
|
|
|
|
static const Expr *isSimpleArrayDecayOperand(const Expr *E) {
|
|
|
|
|
// If this isn't just an array->pointer decay, bail out.
|
2014-05-09 00:08:36 +00:00
|
|
|
const auto *CE = dyn_cast<CastExpr>(E);
|
2014-05-21 05:09:00 +00:00
|
|
|
if (!CE || CE->getCastKind() != CK_ArrayToPointerDecay)
|
2014-06-09 02:04:02 +00:00
|
|
|
return nullptr;
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2010-06-26 23:03:20 +00:00
|
|
|
// If this is a decay from variable width array, bail out.
|
|
|
|
|
const Expr *SubExpr = CE->getSubExpr();
|
|
|
|
|
if (SubExpr->getType()->isVariableArrayType())
|
2014-05-21 05:09:00 +00:00
|
|
|
return nullptr;
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2010-06-26 23:03:20 +00:00
|
|
|
return SubExpr;
|
|
|
|
|
}
|
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
static llvm::Value *emitArraySubscriptGEP(CodeGenFunction &CGF,
|
|
|
|
|
llvm::Value *ptr,
|
|
|
|
|
ArrayRef<llvm::Value*> indices,
|
|
|
|
|
bool inbounds,
|
2017-06-12 18:42:51 +00:00
|
|
|
bool signedIndices,
|
2017-06-01 19:22:18 +00:00
|
|
|
SourceLocation loc,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
const llvm::Twine &name = "arrayidx") {
|
|
|
|
|
if (inbounds) {
|
2017-07-13 20:55:26 +00:00
|
|
|
return CGF.EmitCheckedInBoundsGEP(ptr, indices, signedIndices,
|
|
|
|
|
CodeGenFunction::NotSubtraction, loc,
|
|
|
|
|
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 08:05:57 +00:00
|
|
|
} else {
|
|
|
|
|
return CGF.Builder.CreateGEP(ptr, indices, name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static CharUnits getArrayElementAlign(CharUnits arrayAlign,
|
|
|
|
|
llvm::Value *idx,
|
|
|
|
|
CharUnits eltSize) {
|
|
|
|
|
// If we have a constant index, we can use the exact offset of the
|
|
|
|
|
// element we're accessing.
|
|
|
|
|
if (auto constantIdx = dyn_cast<llvm::ConstantInt>(idx)) {
|
|
|
|
|
CharUnits offset = constantIdx->getZExtValue() * eltSize;
|
|
|
|
|
return arrayAlign.alignmentAtOffset(offset);
|
|
|
|
|
|
|
|
|
|
// Otherwise, use the worst-case alignment for any element.
|
|
|
|
|
} else {
|
|
|
|
|
return arrayAlign.alignmentOfArrayElement(eltSize);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static QualType getFixedSizeElementType(const ASTContext &ctx,
|
|
|
|
|
const VariableArrayType *vla) {
|
|
|
|
|
QualType eltType;
|
|
|
|
|
do {
|
|
|
|
|
eltType = vla->getElementType();
|
|
|
|
|
} while ((vla = ctx.getAsVariableArrayType(eltType)));
|
|
|
|
|
return eltType;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-01 22:16:59 -07:00
|
|
|
/// Given an array base, check whether its member access belongs to a record
|
|
|
|
|
/// with preserve_access_index attribute or not.
|
|
|
|
|
static bool IsPreserveAIArrayBase(CodeGenFunction &CGF, const Expr *ArrayBase) {
|
|
|
|
|
if (!ArrayBase || !CGF.getDebugInfo())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// Only support base as either a MemberExpr or DeclRefExpr.
|
|
|
|
|
// DeclRefExpr to cover cases like:
|
|
|
|
|
// struct s { int a; int b[10]; };
|
|
|
|
|
// struct s *p;
|
|
|
|
|
// p[1].a
|
|
|
|
|
// p[1] will generate a DeclRefExpr and p[1].a is a MemberExpr.
|
|
|
|
|
// p->b[5] is a MemberExpr example.
|
2019-11-14 10:34:35 -08:00
|
|
|
const Expr *E = ArrayBase->IgnoreImpCasts();
|
|
|
|
|
if (const auto *ME = dyn_cast<MemberExpr>(E))
|
|
|
|
|
return ME->getMemberDecl()->hasAttr<BPFPreserveAccessIndexAttr>();
|
|
|
|
|
|
|
|
|
|
if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
|
|
|
|
|
const auto *VarDef = dyn_cast<VarDecl>(DRE->getDecl());
|
2019-11-01 22:16:59 -07:00
|
|
|
if (!VarDef)
|
|
|
|
|
return false;
|
|
|
|
|
|
2019-11-14 10:34:35 -08:00
|
|
|
const auto *PtrT = VarDef->getType()->getAs<PointerType>();
|
2019-11-01 22:16:59 -07:00
|
|
|
if (!PtrT)
|
|
|
|
|
return false;
|
|
|
|
|
|
2019-11-14 10:34:35 -08:00
|
|
|
const auto *PointeeT = PtrT->getPointeeType()
|
|
|
|
|
->getUnqualifiedDesugaredType();
|
|
|
|
|
if (const auto *RecT = dyn_cast<RecordType>(PointeeT))
|
|
|
|
|
return RecT->getDecl()->hasAttr<BPFPreserveAccessIndexAttr>();
|
|
|
|
|
return false;
|
2019-11-01 22:16:59 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 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 08:05:57 +00:00
|
|
|
static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr,
|
2017-06-01 19:22:18 +00:00
|
|
|
ArrayRef<llvm::Value *> indices,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
QualType eltType, bool inbounds,
|
2017-06-12 18:42:51 +00:00
|
|
|
bool signedIndices, SourceLocation loc,
|
2019-08-02 21:28:28 +00:00
|
|
|
QualType *arrayType = nullptr,
|
2019-11-01 22:16:59 -07:00
|
|
|
const Expr *Base = nullptr,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
const llvm::Twine &name = "arrayidx") {
|
|
|
|
|
// All the indices except that last must be zero.
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
for (auto idx : indices.drop_back())
|
|
|
|
|
assert(isa<llvm::ConstantInt>(idx) &&
|
|
|
|
|
cast<llvm::ConstantInt>(idx)->isZero());
|
2018-07-30 19:24:48 +00:00
|
|
|
#endif
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
|
|
|
|
|
// Determine the element size of the statically-sized base. This is
|
|
|
|
|
// the thing that the indices are expressed in terms of.
|
|
|
|
|
if (auto vla = CGF.getContext().getAsVariableArrayType(eltType)) {
|
|
|
|
|
eltType = getFixedSizeElementType(CGF.getContext(), vla);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// We can use that to compute the best alignment of the element.
|
|
|
|
|
CharUnits eltSize = CGF.getContext().getTypeSizeInChars(eltType);
|
|
|
|
|
CharUnits eltAlign =
|
|
|
|
|
getArrayElementAlign(addr.getAlignment(), indices.back(), eltSize);
|
|
|
|
|
|
[BPF] Preserve debuginfo array/union/struct type/access index
For background of BPF CO-RE project, please refer to
http://vger.kernel.org/bpfconf2019.html
In summary, BPF CO-RE intends to compile bpf programs
adjustable on struct/union layout change so the same
program can run on multiple kernels with adjustment
before loading based on native kernel structures.
In order to do this, we need keep track of GEP(getelementptr)
instruction base and result debuginfo types, so we
can adjust on the host based on kernel BTF info.
Capturing such information as an IR optimization is hard
as various optimization may have tweaked GEP and also
union is replaced by structure it is impossible to track
fieldindex for union member accesses.
Three intrinsic functions, preserve_{array,union,struct}_access_index,
are introducted.
addr = preserve_array_access_index(base, index, dimension)
addr = preserve_union_access_index(base, di_index)
addr = preserve_struct_access_index(base, gep_index, di_index)
here,
base: the base pointer for the array/union/struct access.
index: the last access index for array, the same for IR/DebugInfo layout.
dimension: the array dimension.
gep_index: the access index based on IR layout.
di_index: the access index based on user/debuginfo types.
If using these intrinsics blindly, i.e., transforming all GEPs
to these intrinsics and later on reducing them to GEPs, we have
seen up to 7% more instructions generated. To avoid such an overhead,
a clang builtin is proposed:
base = __builtin_preserve_access_index(base)
such that user wraps to-be-relocated GEPs in this builtin
and preserve_*_access_index intrinsics only apply to
those GEPs. Such a buyin will prevent performance degradation
if people do not use CO-RE, even for programs which use
bpf_probe_read().
For example, for the following example,
$ cat test.c
struct sk_buff {
int i;
int b1:1;
int b2:2;
union {
struct {
int o1;
int o2;
} o;
struct {
char flags;
char dev_id;
} dev;
int netid;
} u[10];
};
static int (*bpf_probe_read)(void *dst, int size, const void *unsafe_ptr)
= (void *) 4;
#define _(x) (__builtin_preserve_access_index(x))
int bpf_prog(struct sk_buff *ctx) {
char dev_id;
bpf_probe_read(&dev_id, sizeof(char), _(&ctx->u[5].dev.dev_id));
return dev_id;
}
$ clang -target bpf -O2 -g -emit-llvm -S -mllvm -print-before-all \
test.c >& log
The generated IR looks like below:
...
define dso_local i32 @bpf_prog(%struct.sk_buff*) #0 !dbg !15 {
%2 = alloca %struct.sk_buff*, align 8
%3 = alloca i8, align 1
store %struct.sk_buff* %0, %struct.sk_buff** %2, align 8, !tbaa !45
call void @llvm.dbg.declare(metadata %struct.sk_buff** %2, metadata !43, metadata !DIExpression()), !dbg !49
call void @llvm.lifetime.start.p0i8(i64 1, i8* %3) #4, !dbg !50
call void @llvm.dbg.declare(metadata i8* %3, metadata !44, metadata !DIExpression()), !dbg !51
%4 = load i32 (i8*, i32, i8*)*, i32 (i8*, i32, i8*)** @bpf_probe_read, align 8, !dbg !52, !tbaa !45
%5 = load %struct.sk_buff*, %struct.sk_buff** %2, align 8, !dbg !53, !tbaa !45
%6 = call [10 x %union.anon]* @llvm.preserve.struct.access.index.p0a10s_union.anons.p0s_struct.sk_buffs(
%struct.sk_buff* %5, i32 2, i32 3), !dbg !53, !llvm.preserve.access.index !19
%7 = call %union.anon* @llvm.preserve.array.access.index.p0s_union.anons.p0a10s_union.anons(
[10 x %union.anon]* %6, i32 1, i32 5), !dbg !53
%8 = call %union.anon* @llvm.preserve.union.access.index.p0s_union.anons.p0s_union.anons(
%union.anon* %7, i32 1), !dbg !53, !llvm.preserve.access.index !26
%9 = bitcast %union.anon* %8 to %struct.anon.0*, !dbg !53
%10 = call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.anon.0s(
%struct.anon.0* %9, i32 1, i32 1), !dbg !53, !llvm.preserve.access.index !34
%11 = call i32 %4(i8* %3, i32 1, i8* %10), !dbg !52
%12 = load i8, i8* %3, align 1, !dbg !54, !tbaa !55
%13 = sext i8 %12 to i32, !dbg !54
call void @llvm.lifetime.end.p0i8(i64 1, i8* %3) #4, !dbg !56
ret i32 %13, !dbg !57
}
!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "sk_buff", file: !3, line: 1, size: 704, elements: !20)
!26 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !19, file: !3, line: 5, size: 64, elements: !27)
!34 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !26, file: !3, line: 10, size: 16, elements: !35)
Note that @llvm.preserve.{struct,union}.access.index calls have metadata llvm.preserve.access.index
attached to instructions to provide struct/union debuginfo type information.
For &ctx->u[5].dev.dev_id,
. The "%6 = ..." represents struct member "u" with index 2 for IR layout and index 3 for DI layout.
. The "%7 = ..." represents array subscript "5".
. The "%8 = ..." represents union member "dev" with index 1 for DI layout.
. The "%10 = ..." represents struct member "dev_id" with index 1 for both IR and DI layout.
Basically, traversing the use-def chain recursively for the 3rd argument of bpf_probe_read() and
examining all preserve_*_access_index calls, the debuginfo struct/union/array access index
can be achieved.
The intrinsics also contain enough information to regenerate codes for IR layout.
For array and structure intrinsics, the proper GEP can be constructed.
For union intrinsics, replacing all uses of "addr" with "base" should be enough.
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D61809
llvm-svn: 365438
2019-07-09 04:21:50 +00:00
|
|
|
llvm::Value *eltPtr;
|
|
|
|
|
auto LastIndex = dyn_cast<llvm::ConstantInt>(indices.back());
|
2019-11-01 22:16:59 -07:00
|
|
|
if (!LastIndex ||
|
|
|
|
|
(!CGF.IsInPreservedAIRegion && !IsPreserveAIArrayBase(CGF, Base))) {
|
[BPF] Preserve debuginfo array/union/struct type/access index
For background of BPF CO-RE project, please refer to
http://vger.kernel.org/bpfconf2019.html
In summary, BPF CO-RE intends to compile bpf programs
adjustable on struct/union layout change so the same
program can run on multiple kernels with adjustment
before loading based on native kernel structures.
In order to do this, we need keep track of GEP(getelementptr)
instruction base and result debuginfo types, so we
can adjust on the host based on kernel BTF info.
Capturing such information as an IR optimization is hard
as various optimization may have tweaked GEP and also
union is replaced by structure it is impossible to track
fieldindex for union member accesses.
Three intrinsic functions, preserve_{array,union,struct}_access_index,
are introducted.
addr = preserve_array_access_index(base, index, dimension)
addr = preserve_union_access_index(base, di_index)
addr = preserve_struct_access_index(base, gep_index, di_index)
here,
base: the base pointer for the array/union/struct access.
index: the last access index for array, the same for IR/DebugInfo layout.
dimension: the array dimension.
gep_index: the access index based on IR layout.
di_index: the access index based on user/debuginfo types.
If using these intrinsics blindly, i.e., transforming all GEPs
to these intrinsics and later on reducing them to GEPs, we have
seen up to 7% more instructions generated. To avoid such an overhead,
a clang builtin is proposed:
base = __builtin_preserve_access_index(base)
such that user wraps to-be-relocated GEPs in this builtin
and preserve_*_access_index intrinsics only apply to
those GEPs. Such a buyin will prevent performance degradation
if people do not use CO-RE, even for programs which use
bpf_probe_read().
For example, for the following example,
$ cat test.c
struct sk_buff {
int i;
int b1:1;
int b2:2;
union {
struct {
int o1;
int o2;
} o;
struct {
char flags;
char dev_id;
} dev;
int netid;
} u[10];
};
static int (*bpf_probe_read)(void *dst, int size, const void *unsafe_ptr)
= (void *) 4;
#define _(x) (__builtin_preserve_access_index(x))
int bpf_prog(struct sk_buff *ctx) {
char dev_id;
bpf_probe_read(&dev_id, sizeof(char), _(&ctx->u[5].dev.dev_id));
return dev_id;
}
$ clang -target bpf -O2 -g -emit-llvm -S -mllvm -print-before-all \
test.c >& log
The generated IR looks like below:
...
define dso_local i32 @bpf_prog(%struct.sk_buff*) #0 !dbg !15 {
%2 = alloca %struct.sk_buff*, align 8
%3 = alloca i8, align 1
store %struct.sk_buff* %0, %struct.sk_buff** %2, align 8, !tbaa !45
call void @llvm.dbg.declare(metadata %struct.sk_buff** %2, metadata !43, metadata !DIExpression()), !dbg !49
call void @llvm.lifetime.start.p0i8(i64 1, i8* %3) #4, !dbg !50
call void @llvm.dbg.declare(metadata i8* %3, metadata !44, metadata !DIExpression()), !dbg !51
%4 = load i32 (i8*, i32, i8*)*, i32 (i8*, i32, i8*)** @bpf_probe_read, align 8, !dbg !52, !tbaa !45
%5 = load %struct.sk_buff*, %struct.sk_buff** %2, align 8, !dbg !53, !tbaa !45
%6 = call [10 x %union.anon]* @llvm.preserve.struct.access.index.p0a10s_union.anons.p0s_struct.sk_buffs(
%struct.sk_buff* %5, i32 2, i32 3), !dbg !53, !llvm.preserve.access.index !19
%7 = call %union.anon* @llvm.preserve.array.access.index.p0s_union.anons.p0a10s_union.anons(
[10 x %union.anon]* %6, i32 1, i32 5), !dbg !53
%8 = call %union.anon* @llvm.preserve.union.access.index.p0s_union.anons.p0s_union.anons(
%union.anon* %7, i32 1), !dbg !53, !llvm.preserve.access.index !26
%9 = bitcast %union.anon* %8 to %struct.anon.0*, !dbg !53
%10 = call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.anon.0s(
%struct.anon.0* %9, i32 1, i32 1), !dbg !53, !llvm.preserve.access.index !34
%11 = call i32 %4(i8* %3, i32 1, i8* %10), !dbg !52
%12 = load i8, i8* %3, align 1, !dbg !54, !tbaa !55
%13 = sext i8 %12 to i32, !dbg !54
call void @llvm.lifetime.end.p0i8(i64 1, i8* %3) #4, !dbg !56
ret i32 %13, !dbg !57
}
!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "sk_buff", file: !3, line: 1, size: 704, elements: !20)
!26 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !19, file: !3, line: 5, size: 64, elements: !27)
!34 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !26, file: !3, line: 10, size: 16, elements: !35)
Note that @llvm.preserve.{struct,union}.access.index calls have metadata llvm.preserve.access.index
attached to instructions to provide struct/union debuginfo type information.
For &ctx->u[5].dev.dev_id,
. The "%6 = ..." represents struct member "u" with index 2 for IR layout and index 3 for DI layout.
. The "%7 = ..." represents array subscript "5".
. The "%8 = ..." represents union member "dev" with index 1 for DI layout.
. The "%10 = ..." represents struct member "dev_id" with index 1 for both IR and DI layout.
Basically, traversing the use-def chain recursively for the 3rd argument of bpf_probe_read() and
examining all preserve_*_access_index calls, the debuginfo struct/union/array access index
can be achieved.
The intrinsics also contain enough information to regenerate codes for IR layout.
For array and structure intrinsics, the proper GEP can be constructed.
For union intrinsics, replacing all uses of "addr" with "base" should be enough.
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D61809
llvm-svn: 365438
2019-07-09 04:21:50 +00:00
|
|
|
eltPtr = emitArraySubscriptGEP(
|
|
|
|
|
CGF, addr.getPointer(), indices, inbounds, signedIndices,
|
|
|
|
|
loc, name);
|
|
|
|
|
} else {
|
|
|
|
|
// Remember the original array subscript for bpf target
|
|
|
|
|
unsigned idx = LastIndex->getZExtValue();
|
2019-08-02 21:28:28 +00:00
|
|
|
llvm::DIType *DbgInfo = nullptr;
|
|
|
|
|
if (arrayType)
|
|
|
|
|
DbgInfo = CGF.getDebugInfo()->getOrCreateStandaloneType(*arrayType, loc);
|
2019-11-03 09:30:08 -08:00
|
|
|
eltPtr = CGF.Builder.CreatePreserveArrayAccessIndex(addr.getElementType(),
|
|
|
|
|
addr.getPointer(),
|
[BPF] Preserve debuginfo array/union/struct type/access index
For background of BPF CO-RE project, please refer to
http://vger.kernel.org/bpfconf2019.html
In summary, BPF CO-RE intends to compile bpf programs
adjustable on struct/union layout change so the same
program can run on multiple kernels with adjustment
before loading based on native kernel structures.
In order to do this, we need keep track of GEP(getelementptr)
instruction base and result debuginfo types, so we
can adjust on the host based on kernel BTF info.
Capturing such information as an IR optimization is hard
as various optimization may have tweaked GEP and also
union is replaced by structure it is impossible to track
fieldindex for union member accesses.
Three intrinsic functions, preserve_{array,union,struct}_access_index,
are introducted.
addr = preserve_array_access_index(base, index, dimension)
addr = preserve_union_access_index(base, di_index)
addr = preserve_struct_access_index(base, gep_index, di_index)
here,
base: the base pointer for the array/union/struct access.
index: the last access index for array, the same for IR/DebugInfo layout.
dimension: the array dimension.
gep_index: the access index based on IR layout.
di_index: the access index based on user/debuginfo types.
If using these intrinsics blindly, i.e., transforming all GEPs
to these intrinsics and later on reducing them to GEPs, we have
seen up to 7% more instructions generated. To avoid such an overhead,
a clang builtin is proposed:
base = __builtin_preserve_access_index(base)
such that user wraps to-be-relocated GEPs in this builtin
and preserve_*_access_index intrinsics only apply to
those GEPs. Such a buyin will prevent performance degradation
if people do not use CO-RE, even for programs which use
bpf_probe_read().
For example, for the following example,
$ cat test.c
struct sk_buff {
int i;
int b1:1;
int b2:2;
union {
struct {
int o1;
int o2;
} o;
struct {
char flags;
char dev_id;
} dev;
int netid;
} u[10];
};
static int (*bpf_probe_read)(void *dst, int size, const void *unsafe_ptr)
= (void *) 4;
#define _(x) (__builtin_preserve_access_index(x))
int bpf_prog(struct sk_buff *ctx) {
char dev_id;
bpf_probe_read(&dev_id, sizeof(char), _(&ctx->u[5].dev.dev_id));
return dev_id;
}
$ clang -target bpf -O2 -g -emit-llvm -S -mllvm -print-before-all \
test.c >& log
The generated IR looks like below:
...
define dso_local i32 @bpf_prog(%struct.sk_buff*) #0 !dbg !15 {
%2 = alloca %struct.sk_buff*, align 8
%3 = alloca i8, align 1
store %struct.sk_buff* %0, %struct.sk_buff** %2, align 8, !tbaa !45
call void @llvm.dbg.declare(metadata %struct.sk_buff** %2, metadata !43, metadata !DIExpression()), !dbg !49
call void @llvm.lifetime.start.p0i8(i64 1, i8* %3) #4, !dbg !50
call void @llvm.dbg.declare(metadata i8* %3, metadata !44, metadata !DIExpression()), !dbg !51
%4 = load i32 (i8*, i32, i8*)*, i32 (i8*, i32, i8*)** @bpf_probe_read, align 8, !dbg !52, !tbaa !45
%5 = load %struct.sk_buff*, %struct.sk_buff** %2, align 8, !dbg !53, !tbaa !45
%6 = call [10 x %union.anon]* @llvm.preserve.struct.access.index.p0a10s_union.anons.p0s_struct.sk_buffs(
%struct.sk_buff* %5, i32 2, i32 3), !dbg !53, !llvm.preserve.access.index !19
%7 = call %union.anon* @llvm.preserve.array.access.index.p0s_union.anons.p0a10s_union.anons(
[10 x %union.anon]* %6, i32 1, i32 5), !dbg !53
%8 = call %union.anon* @llvm.preserve.union.access.index.p0s_union.anons.p0s_union.anons(
%union.anon* %7, i32 1), !dbg !53, !llvm.preserve.access.index !26
%9 = bitcast %union.anon* %8 to %struct.anon.0*, !dbg !53
%10 = call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.anon.0s(
%struct.anon.0* %9, i32 1, i32 1), !dbg !53, !llvm.preserve.access.index !34
%11 = call i32 %4(i8* %3, i32 1, i8* %10), !dbg !52
%12 = load i8, i8* %3, align 1, !dbg !54, !tbaa !55
%13 = sext i8 %12 to i32, !dbg !54
call void @llvm.lifetime.end.p0i8(i64 1, i8* %3) #4, !dbg !56
ret i32 %13, !dbg !57
}
!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "sk_buff", file: !3, line: 1, size: 704, elements: !20)
!26 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !19, file: !3, line: 5, size: 64, elements: !27)
!34 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !26, file: !3, line: 10, size: 16, elements: !35)
Note that @llvm.preserve.{struct,union}.access.index calls have metadata llvm.preserve.access.index
attached to instructions to provide struct/union debuginfo type information.
For &ctx->u[5].dev.dev_id,
. The "%6 = ..." represents struct member "u" with index 2 for IR layout and index 3 for DI layout.
. The "%7 = ..." represents array subscript "5".
. The "%8 = ..." represents union member "dev" with index 1 for DI layout.
. The "%10 = ..." represents struct member "dev_id" with index 1 for both IR and DI layout.
Basically, traversing the use-def chain recursively for the 3rd argument of bpf_probe_read() and
examining all preserve_*_access_index calls, the debuginfo struct/union/array access index
can be achieved.
The intrinsics also contain enough information to regenerate codes for IR layout.
For array and structure intrinsics, the proper GEP can be constructed.
For union intrinsics, replacing all uses of "addr" with "base" should be enough.
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D61809
llvm-svn: 365438
2019-07-09 04:21:50 +00:00
|
|
|
indices.size() - 1,
|
2019-08-02 21:28:28 +00:00
|
|
|
idx, DbgInfo);
|
[BPF] Preserve debuginfo array/union/struct type/access index
For background of BPF CO-RE project, please refer to
http://vger.kernel.org/bpfconf2019.html
In summary, BPF CO-RE intends to compile bpf programs
adjustable on struct/union layout change so the same
program can run on multiple kernels with adjustment
before loading based on native kernel structures.
In order to do this, we need keep track of GEP(getelementptr)
instruction base and result debuginfo types, so we
can adjust on the host based on kernel BTF info.
Capturing such information as an IR optimization is hard
as various optimization may have tweaked GEP and also
union is replaced by structure it is impossible to track
fieldindex for union member accesses.
Three intrinsic functions, preserve_{array,union,struct}_access_index,
are introducted.
addr = preserve_array_access_index(base, index, dimension)
addr = preserve_union_access_index(base, di_index)
addr = preserve_struct_access_index(base, gep_index, di_index)
here,
base: the base pointer for the array/union/struct access.
index: the last access index for array, the same for IR/DebugInfo layout.
dimension: the array dimension.
gep_index: the access index based on IR layout.
di_index: the access index based on user/debuginfo types.
If using these intrinsics blindly, i.e., transforming all GEPs
to these intrinsics and later on reducing them to GEPs, we have
seen up to 7% more instructions generated. To avoid such an overhead,
a clang builtin is proposed:
base = __builtin_preserve_access_index(base)
such that user wraps to-be-relocated GEPs in this builtin
and preserve_*_access_index intrinsics only apply to
those GEPs. Such a buyin will prevent performance degradation
if people do not use CO-RE, even for programs which use
bpf_probe_read().
For example, for the following example,
$ cat test.c
struct sk_buff {
int i;
int b1:1;
int b2:2;
union {
struct {
int o1;
int o2;
} o;
struct {
char flags;
char dev_id;
} dev;
int netid;
} u[10];
};
static int (*bpf_probe_read)(void *dst, int size, const void *unsafe_ptr)
= (void *) 4;
#define _(x) (__builtin_preserve_access_index(x))
int bpf_prog(struct sk_buff *ctx) {
char dev_id;
bpf_probe_read(&dev_id, sizeof(char), _(&ctx->u[5].dev.dev_id));
return dev_id;
}
$ clang -target bpf -O2 -g -emit-llvm -S -mllvm -print-before-all \
test.c >& log
The generated IR looks like below:
...
define dso_local i32 @bpf_prog(%struct.sk_buff*) #0 !dbg !15 {
%2 = alloca %struct.sk_buff*, align 8
%3 = alloca i8, align 1
store %struct.sk_buff* %0, %struct.sk_buff** %2, align 8, !tbaa !45
call void @llvm.dbg.declare(metadata %struct.sk_buff** %2, metadata !43, metadata !DIExpression()), !dbg !49
call void @llvm.lifetime.start.p0i8(i64 1, i8* %3) #4, !dbg !50
call void @llvm.dbg.declare(metadata i8* %3, metadata !44, metadata !DIExpression()), !dbg !51
%4 = load i32 (i8*, i32, i8*)*, i32 (i8*, i32, i8*)** @bpf_probe_read, align 8, !dbg !52, !tbaa !45
%5 = load %struct.sk_buff*, %struct.sk_buff** %2, align 8, !dbg !53, !tbaa !45
%6 = call [10 x %union.anon]* @llvm.preserve.struct.access.index.p0a10s_union.anons.p0s_struct.sk_buffs(
%struct.sk_buff* %5, i32 2, i32 3), !dbg !53, !llvm.preserve.access.index !19
%7 = call %union.anon* @llvm.preserve.array.access.index.p0s_union.anons.p0a10s_union.anons(
[10 x %union.anon]* %6, i32 1, i32 5), !dbg !53
%8 = call %union.anon* @llvm.preserve.union.access.index.p0s_union.anons.p0s_union.anons(
%union.anon* %7, i32 1), !dbg !53, !llvm.preserve.access.index !26
%9 = bitcast %union.anon* %8 to %struct.anon.0*, !dbg !53
%10 = call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.anon.0s(
%struct.anon.0* %9, i32 1, i32 1), !dbg !53, !llvm.preserve.access.index !34
%11 = call i32 %4(i8* %3, i32 1, i8* %10), !dbg !52
%12 = load i8, i8* %3, align 1, !dbg !54, !tbaa !55
%13 = sext i8 %12 to i32, !dbg !54
call void @llvm.lifetime.end.p0i8(i64 1, i8* %3) #4, !dbg !56
ret i32 %13, !dbg !57
}
!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "sk_buff", file: !3, line: 1, size: 704, elements: !20)
!26 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !19, file: !3, line: 5, size: 64, elements: !27)
!34 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !26, file: !3, line: 10, size: 16, elements: !35)
Note that @llvm.preserve.{struct,union}.access.index calls have metadata llvm.preserve.access.index
attached to instructions to provide struct/union debuginfo type information.
For &ctx->u[5].dev.dev_id,
. The "%6 = ..." represents struct member "u" with index 2 for IR layout and index 3 for DI layout.
. The "%7 = ..." represents array subscript "5".
. The "%8 = ..." represents union member "dev" with index 1 for DI layout.
. The "%10 = ..." represents struct member "dev_id" with index 1 for both IR and DI layout.
Basically, traversing the use-def chain recursively for the 3rd argument of bpf_probe_read() and
examining all preserve_*_access_index calls, the debuginfo struct/union/array access index
can be achieved.
The intrinsics also contain enough information to regenerate codes for IR layout.
For array and structure intrinsics, the proper GEP can be constructed.
For union intrinsics, replacing all uses of "addr" with "base" should be enough.
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D61809
llvm-svn: 365438
2019-07-09 04:21:50 +00: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 08:05:57 +00:00
|
|
|
return Address(eltPtr, eltAlign);
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-23 02:53:19 +00:00
|
|
|
LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
|
|
|
|
|
bool Accessed) {
|
2016-09-26 23:49:47 +00:00
|
|
|
// The index must always be an integer, which is not an aggregate. Emit it
|
|
|
|
|
// in lexical order (this complexity is, sadly, required by C++17).
|
|
|
|
|
llvm::Value *IdxPre =
|
|
|
|
|
(E->getLHS() == E->getIdx()) ? EmitScalarExpr(E->getIdx()) : nullptr;
|
2017-06-12 18:42:51 +00:00
|
|
|
bool SignedIndices = false;
|
2016-09-27 00:53:24 +00:00
|
|
|
auto EmitIdxAfterBase = [&, IdxPre](bool Promote) -> llvm::Value * {
|
2016-09-26 23:49:47 +00:00
|
|
|
auto *Idx = IdxPre;
|
|
|
|
|
if (E->getLHS() != E->getIdx()) {
|
|
|
|
|
assert(E->getRHS() == E->getIdx() && "index was neither LHS nor RHS");
|
|
|
|
|
Idx = EmitScalarExpr(E->getIdx());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QualType IdxTy = E->getIdx()->getType();
|
|
|
|
|
bool IdxSigned = IdxTy->isSignedIntegerOrEnumerationType();
|
2017-06-12 18:42:51 +00:00
|
|
|
SignedIndices |= IdxSigned;
|
2009-06-06 19:09:26 +00:00
|
|
|
|
2016-09-26 23:49:47 +00:00
|
|
|
if (SanOpts.has(SanitizerKind::ArrayBounds))
|
|
|
|
|
EmitBoundsCheck(E, E->getBase(), Idx, IdxTy, Accessed);
|
|
|
|
|
|
|
|
|
|
// Extend or truncate the index type to 32 or 64-bits.
|
|
|
|
|
if (Promote && Idx->getType() != IntPtrTy)
|
|
|
|
|
Idx = Builder.CreateIntCast(Idx, IntPtrTy, IdxSigned, "idxprom");
|
|
|
|
|
|
|
|
|
|
return Idx;
|
|
|
|
|
};
|
|
|
|
|
IdxPre = nullptr;
|
2013-02-23 02:53:19 +00:00
|
|
|
|
2007-07-10 21:17:59 +00:00
|
|
|
// If the base is a vector type, then we are forming a vector element lvalue
|
|
|
|
|
// with this subscript.
|
2014-08-19 17:17:40 +00:00
|
|
|
if (E->getBase()->getType()->isVectorType() &&
|
|
|
|
|
!isa<ExtVectorElementExpr>(E->getBase())) {
|
2007-07-10 21:17:59 +00:00
|
|
|
// Emit the vector as an lvalue to get its address.
|
2008-06-13 23:01:12 +00:00
|
|
|
LValue LHS = EmitLValue(E->getBase());
|
2016-09-26 23:49:47 +00:00
|
|
|
auto *Idx = EmitIdxAfterBase(/*Promote*/false);
|
2007-08-20 16:18:38 +00:00
|
|
|
assert(LHS.isSimple() && "Can only subscript lvalue vectors here!");
|
2019-12-03 15:17:01 -08:00
|
|
|
return LValue::MakeVectorElt(LHS.getAddress(*this), Idx,
|
|
|
|
|
E->getBase()->getType(), LHS.getBaseInfo(),
|
|
|
|
|
TBAAAccessInfo());
|
2007-07-10 21:17:59 +00:00
|
|
|
}
|
2009-09-09 13:00:44 +00: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 08:05:57 +00:00
|
|
|
// All the other cases basically behave like simple offsetting.
|
|
|
|
|
|
|
|
|
|
// Handle the extvector case we ignored above.
|
2014-08-19 17:17:40 +00:00
|
|
|
if (isa<ExtVectorElementExpr>(E->getBase())) {
|
|
|
|
|
LValue LV = EmitLValue(E->getBase());
|
2016-09-26 23:49:47 +00:00
|
|
|
auto *Idx = EmitIdxAfterBase(/*Promote*/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 08:05:57 +00:00
|
|
|
Address Addr = EmitExtVectorElementLValue(LV);
|
|
|
|
|
|
|
|
|
|
QualType EltType = LV.getType()->castAs<VectorType>()->getElementType();
|
2017-06-01 19:22:18 +00:00
|
|
|
Addr = emitArraySubscriptGEP(*this, Addr, Idx, EltType, /*inbounds*/ true,
|
2017-06-12 18:42:51 +00:00
|
|
|
SignedIndices, E->getExprLoc());
|
2017-10-12 11:29:46 +00:00
|
|
|
return MakeAddrLValue(Addr, EltType, LV.getBaseInfo(),
|
2017-10-31 11:05:34 +00:00
|
|
|
CGM.getTBAAInfoForSubobject(LV, EltType));
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
}
|
|
|
|
|
|
2017-10-31 11:05:34 +00:00
|
|
|
LValueBaseInfo EltBaseInfo;
|
|
|
|
|
TBAAAccessInfo EltTBAAInfo;
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Address Addr = Address::invalid();
|
|
|
|
|
if (const VariableArrayType *vla =
|
2014-08-19 17:17:40 +00:00
|
|
|
getContext().getAsVariableArrayType(E->getType())) {
|
2011-06-24 21:55:10 +00:00
|
|
|
// The base must be a pointer, which is not an aggregate. Emit
|
|
|
|
|
// it. It needs to be emitted first in case it's what captures
|
|
|
|
|
// the VLA bounds.
|
2017-10-31 11:05:34 +00:00
|
|
|
Addr = EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo);
|
2016-09-26 23:49:47 +00:00
|
|
|
auto *Idx = EmitIdxAfterBase(/*Promote*/true);
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2011-06-24 21:55:10 +00:00
|
|
|
// The element count here is the total number of non-VLA elements.
|
2018-02-03 13:55:59 +00:00
|
|
|
llvm::Value *numElements = getVLASize(vla).NumElts;
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2011-06-25 01:32:37 +00:00
|
|
|
// Effectively, the multiply by the VLA size is part of the GEP.
|
|
|
|
|
// GEP indexes are signed, and scaling an index isn't permitted to
|
|
|
|
|
// signed-overflow, so we use the same semantics for our explicit
|
|
|
|
|
// multiply. We suppress this if overflow is not undefined behavior.
|
2012-03-11 07:00:24 +00:00
|
|
|
if (getLangOpts().isSignedOverflowDefined()) {
|
2011-06-25 01:32:37 +00:00
|
|
|
Idx = Builder.CreateMul(Idx, numElements);
|
|
|
|
|
} else {
|
|
|
|
|
Idx = Builder.CreateNSWMul(Idx, numElements);
|
|
|
|
|
}
|
2009-09-09 13:00:44 +00: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 08:05:57 +00:00
|
|
|
Addr = emitArraySubscriptGEP(*this, Addr, Idx, vla->getElementType(),
|
2017-06-01 19:22:18 +00:00
|
|
|
!getLangOpts().isSignedOverflowDefined(),
|
2017-06-12 18:42:51 +00:00
|
|
|
SignedIndices, E->getExprLoc());
|
2009-04-25 05:08:32 +00: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 08:05:57 +00:00
|
|
|
} else if (const ObjCObjectType *OIT = E->getType()->getAs<ObjCObjectType>()){
|
|
|
|
|
// Indexing over an interface, as in "NSString *P; P[4];"
|
|
|
|
|
|
|
|
|
|
// Emit the base pointer.
|
2017-10-31 11:05:34 +00:00
|
|
|
Addr = EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo);
|
2016-09-26 23:49:47 +00:00
|
|
|
auto *Idx = EmitIdxAfterBase(/*Promote*/true);
|
|
|
|
|
|
|
|
|
|
CharUnits InterfaceSize = getContext().getTypeSizeInChars(OIT);
|
|
|
|
|
llvm::Value *InterfaceSizeVal =
|
|
|
|
|
llvm::ConstantInt::get(Idx->getType(), InterfaceSize.getQuantity());
|
|
|
|
|
|
|
|
|
|
llvm::Value *ScaledIdx = Builder.CreateMul(Idx, InterfaceSizeVal);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
|
|
|
|
|
// We don't necessarily build correct LLVM struct types for ObjC
|
|
|
|
|
// interfaces, so we can't rely on GEP to do this scaling
|
|
|
|
|
// correctly, so we need to cast to i8*. FIXME: is this actually
|
|
|
|
|
// true? A lot of other things in the fragile ABI would break...
|
|
|
|
|
llvm::Type *OrigBaseTy = Addr.getType();
|
|
|
|
|
Addr = Builder.CreateElementBitCast(Addr, Int8Ty);
|
|
|
|
|
|
|
|
|
|
// Do the GEP.
|
|
|
|
|
CharUnits EltAlign =
|
|
|
|
|
getArrayElementAlign(Addr.getAlignment(), Idx, InterfaceSize);
|
2017-06-12 18:42:51 +00:00
|
|
|
llvm::Value *EltPtr =
|
|
|
|
|
emitArraySubscriptGEP(*this, Addr.getPointer(), ScaledIdx, false,
|
|
|
|
|
SignedIndices, E->getExprLoc());
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Addr = Address(EltPtr, EltAlign);
|
|
|
|
|
|
|
|
|
|
// Cast back.
|
|
|
|
|
Addr = Builder.CreateBitCast(Addr, OrigBaseTy);
|
2010-06-26 23:03:20 +00:00
|
|
|
} else if (const Expr *Array = isSimpleArrayDecayOperand(E->getBase())) {
|
|
|
|
|
// If this is A[i] where A is an array, the frontend will have decayed the
|
|
|
|
|
// base to be a ArrayToPointerDecay implicit cast. While correct, it is
|
|
|
|
|
// inefficient at -O0 to emit a "gep A, 0, 0" when codegen'ing it, then a
|
|
|
|
|
// "gep x, i" here. Emit one "gep A, 0, i".
|
|
|
|
|
assert(Array->getType()->isArrayType() &&
|
|
|
|
|
"Array to pointer decay must have array source type!");
|
2013-02-23 02:53:19 +00:00
|
|
|
LValue ArrayLV;
|
|
|
|
|
// For simple multidimensional array indexing, set the 'accessed' flag for
|
|
|
|
|
// better bounds-checking of the base expression.
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(Array))
|
2013-02-23 02:53:19 +00:00
|
|
|
ArrayLV = EmitArraySubscriptExpr(ASE, /*Accessed*/ true);
|
|
|
|
|
else
|
|
|
|
|
ArrayLV = EmitLValue(Array);
|
2016-09-26 23:49:47 +00:00
|
|
|
auto *Idx = EmitIdxAfterBase(/*Promote*/true);
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2011-04-01 00:49:43 +00:00
|
|
|
// Propagate the alignment from the array itself to the result.
|
2019-08-02 21:28:28 +00:00
|
|
|
QualType arrayType = Array->getType();
|
2017-06-12 18:42:51 +00:00
|
|
|
Addr = emitArraySubscriptGEP(
|
2019-12-03 15:17:01 -08:00
|
|
|
*this, ArrayLV.getAddress(*this), {CGM.getSize(CharUnits::Zero()), Idx},
|
2017-06-12 18:42:51 +00:00
|
|
|
E->getType(), !getLangOpts().isSignedOverflowDefined(), SignedIndices,
|
2019-11-01 22:16:59 -07:00
|
|
|
E->getExprLoc(), &arrayType, E->getBase());
|
2017-10-31 11:05:34 +00:00
|
|
|
EltBaseInfo = ArrayLV.getBaseInfo();
|
|
|
|
|
EltTBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, E->getType());
|
2009-04-25 05:08:32 +00: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 08:05:57 +00:00
|
|
|
// The base must be a pointer; emit it with an estimate of its alignment.
|
2017-10-31 11:05:34 +00:00
|
|
|
Addr = EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo);
|
2016-09-26 23:49:47 +00:00
|
|
|
auto *Idx = EmitIdxAfterBase(/*Promote*/true);
|
2019-08-02 21:28:28 +00:00
|
|
|
QualType ptrType = E->getBase()->getType();
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Addr = emitArraySubscriptGEP(*this, Addr, Idx, E->getType(),
|
2017-06-01 19:22:18 +00:00
|
|
|
!getLangOpts().isSignedOverflowDefined(),
|
2019-11-01 22:16:59 -07:00
|
|
|
SignedIndices, E->getExprLoc(), &ptrType,
|
|
|
|
|
E->getBase());
|
2008-12-21 00:11:23 +00:00
|
|
|
}
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2017-10-31 11:05:34 +00:00
|
|
|
LValue LV = MakeAddrLValue(Addr, E->getType(), EltBaseInfo, EltTBAAInfo);
|
2009-09-24 19:53:00 +00:00
|
|
|
|
2018-10-30 20:31:30 +00:00
|
|
|
if (getLangOpts().ObjC &&
|
2012-11-01 22:30:59 +00:00
|
|
|
getLangOpts().getGC() != LangOptions::NonGC) {
|
2010-08-21 03:22:38 +00:00
|
|
|
LV.setNonGC(!E->isOBJCGCCandidate(getContext()));
|
2009-09-16 21:37:16 +00:00
|
|
|
setObjCGCLValueClass(getContext(), E, LV);
|
|
|
|
|
}
|
2009-02-21 23:37:19 +00:00
|
|
|
return LV;
|
2007-06-08 23:31:14 +00:00
|
|
|
}
|
|
|
|
|
|
[Matrix] Implement matrix index expressions ([][]).
This patch implements matrix index expressions
(matrix[RowIdx][ColumnIdx]).
It does so by introducing a new MatrixSubscriptExpr(Base, RowIdx, ColumnIdx).
MatrixSubscriptExprs are built in 2 steps in ActOnMatrixSubscriptExpr. First,
if the base of a subscript is of matrix type, we create a incomplete
MatrixSubscriptExpr(base, idx, nullptr). Second, if the base is an incomplete
MatrixSubscriptExpr, we create a complete
MatrixSubscriptExpr(base->getBase(), base->getRowIdx(), idx)
Similar to vector elements, it is not possible to take the address of
a MatrixSubscriptExpr.
For CodeGen, a new MatrixElt type is added to LValue, which is very
similar to VectorElt. The only difference is that we may need to cast
the type of the base from an array to a vector type when accessing it.
Reviewers: rjmccall, anemet, Bigcheese, rsmith, martong
Reviewed By: rjmccall
Differential Revision: https://reviews.llvm.org/D76791
2020-06-01 19:42:03 +01:00
|
|
|
LValue CodeGenFunction::EmitMatrixSubscriptExpr(const MatrixSubscriptExpr *E) {
|
|
|
|
|
assert(
|
|
|
|
|
!E->isIncomplete() &&
|
|
|
|
|
"incomplete matrix subscript expressions should be rejected during Sema");
|
|
|
|
|
LValue Base = EmitLValue(E->getBase());
|
|
|
|
|
llvm::Value *RowIdx = EmitScalarExpr(E->getRowIdx());
|
|
|
|
|
llvm::Value *ColIdx = EmitScalarExpr(E->getColumnIdx());
|
|
|
|
|
llvm::Value *NumRows = Builder.getIntN(
|
|
|
|
|
RowIdx->getType()->getScalarSizeInBits(),
|
2021-01-05 16:59:23 +00:00
|
|
|
E->getBase()->getType()->castAs<ConstantMatrixType>()->getNumRows());
|
[Matrix] Implement matrix index expressions ([][]).
This patch implements matrix index expressions
(matrix[RowIdx][ColumnIdx]).
It does so by introducing a new MatrixSubscriptExpr(Base, RowIdx, ColumnIdx).
MatrixSubscriptExprs are built in 2 steps in ActOnMatrixSubscriptExpr. First,
if the base of a subscript is of matrix type, we create a incomplete
MatrixSubscriptExpr(base, idx, nullptr). Second, if the base is an incomplete
MatrixSubscriptExpr, we create a complete
MatrixSubscriptExpr(base->getBase(), base->getRowIdx(), idx)
Similar to vector elements, it is not possible to take the address of
a MatrixSubscriptExpr.
For CodeGen, a new MatrixElt type is added to LValue, which is very
similar to VectorElt. The only difference is that we may need to cast
the type of the base from an array to a vector type when accessing it.
Reviewers: rjmccall, anemet, Bigcheese, rsmith, martong
Reviewed By: rjmccall
Differential Revision: https://reviews.llvm.org/D76791
2020-06-01 19:42:03 +01:00
|
|
|
llvm::Value *FinalIdx =
|
|
|
|
|
Builder.CreateAdd(Builder.CreateMul(ColIdx, NumRows), RowIdx);
|
|
|
|
|
return LValue::MakeMatrixElt(
|
|
|
|
|
MaybeConvertMatrixAddress(Base.getAddress(*this), *this), FinalIdx,
|
|
|
|
|
E->getBase()->getType(), Base.getBaseInfo(), TBAAAccessInfo());
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-04 11:27:03 +00:00
|
|
|
static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base,
|
2017-05-18 17:07:11 +00:00
|
|
|
LValueBaseInfo &BaseInfo,
|
2017-10-13 17:34:18 +00:00
|
|
|
TBAAAccessInfo &TBAAInfo,
|
2016-02-04 11:27:03 +00:00
|
|
|
QualType BaseTy, QualType ElTy,
|
|
|
|
|
bool IsLowerBound) {
|
|
|
|
|
LValue BaseLVal;
|
|
|
|
|
if (auto *ASE = dyn_cast<OMPArraySectionExpr>(Base->IgnoreParenImpCasts())) {
|
|
|
|
|
BaseLVal = CGF.EmitOMPArraySectionExpr(ASE, IsLowerBound);
|
|
|
|
|
if (BaseTy->isArrayType()) {
|
2019-12-03 15:17:01 -08:00
|
|
|
Address Addr = BaseLVal.getAddress(CGF);
|
2017-05-18 17:07:11 +00:00
|
|
|
BaseInfo = BaseLVal.getBaseInfo();
|
2016-02-04 11:27:03 +00:00
|
|
|
|
|
|
|
|
// If the array type was an incomplete type, we need to make sure
|
|
|
|
|
// the decay ends up being the right type.
|
|
|
|
|
llvm::Type *NewTy = CGF.ConvertType(BaseTy);
|
|
|
|
|
Addr = CGF.Builder.CreateElementBitCast(Addr, NewTy);
|
|
|
|
|
|
|
|
|
|
// Note that VLA pointers are always decayed, so we don't need to do
|
|
|
|
|
// anything here.
|
|
|
|
|
if (!BaseTy->isVariableArrayType()) {
|
|
|
|
|
assert(isa<llvm::ArrayType>(Addr.getElementType()) &&
|
|
|
|
|
"Expected pointer to array");
|
2019-02-08 15:34:12 +00:00
|
|
|
Addr = CGF.Builder.CreateConstArrayGEP(Addr, 0, "arraydecay");
|
2016-02-04 11:27:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return CGF.Builder.CreateElementBitCast(Addr,
|
|
|
|
|
CGF.ConvertTypeForMem(ElTy));
|
|
|
|
|
}
|
2017-10-31 11:05:34 +00:00
|
|
|
LValueBaseInfo TypeBaseInfo;
|
|
|
|
|
TBAAAccessInfo TypeTBAAInfo;
|
2020-05-18 11:29:11 -07:00
|
|
|
CharUnits Align =
|
|
|
|
|
CGF.CGM.getNaturalTypeAlignment(ElTy, &TypeBaseInfo, &TypeTBAAInfo);
|
2017-10-31 11:05:34 +00:00
|
|
|
BaseInfo.mergeForCast(TypeBaseInfo);
|
|
|
|
|
TBAAInfo = CGF.CGM.mergeTBAAInfoForCast(TBAAInfo, TypeTBAAInfo);
|
2019-12-03 15:17:01 -08:00
|
|
|
return Address(CGF.Builder.CreateLoad(BaseLVal.getAddress(CGF)), Align);
|
2016-02-04 11:27:03 +00:00
|
|
|
}
|
2017-10-17 09:12:13 +00:00
|
|
|
return CGF.EmitPointerWithAlignment(Base, &BaseInfo, &TBAAInfo);
|
2016-02-04 11:27:03 +00:00
|
|
|
}
|
|
|
|
|
|
2015-08-31 07:32:19 +00:00
|
|
|
LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E,
|
|
|
|
|
bool IsLowerBound) {
|
2017-10-12 15:18:41 +00:00
|
|
|
QualType BaseTy = OMPArraySectionExpr::getBaseOriginalType(E->getBase());
|
2015-08-31 07:32:19 +00:00
|
|
|
QualType ResultExprTy;
|
|
|
|
|
if (auto *AT = getContext().getAsArrayType(BaseTy))
|
|
|
|
|
ResultExprTy = AT->getElementType();
|
|
|
|
|
else
|
|
|
|
|
ResultExprTy = BaseTy->getPointeeType();
|
2016-02-04 11:27:03 +00:00
|
|
|
llvm::Value *Idx = nullptr;
|
2020-07-09 13:27:32 -05:00
|
|
|
if (IsLowerBound || E->getColonLocFirst().isInvalid()) {
|
2015-08-31 07:32:19 +00:00
|
|
|
// Requesting lower bound or upper bound, but without provided length and
|
|
|
|
|
// without ':' symbol for the default length -> length = 1.
|
|
|
|
|
// Idx = LowerBound ?: 0;
|
|
|
|
|
if (auto *LowerBound = E->getLowerBound()) {
|
|
|
|
|
Idx = Builder.CreateIntCast(
|
|
|
|
|
EmitScalarExpr(LowerBound), IntPtrTy,
|
|
|
|
|
LowerBound->getType()->hasSignedIntegerRepresentation());
|
|
|
|
|
} else
|
|
|
|
|
Idx = llvm::ConstantInt::getNullValue(IntPtrTy);
|
|
|
|
|
} else {
|
2016-02-04 11:27:03 +00:00
|
|
|
// Try to emit length or lower bound as constant. If this is possible, 1
|
|
|
|
|
// is subtracted from constant length or lower bound. Otherwise, emit LLVM
|
|
|
|
|
// IR (LB + Len) - 1.
|
2015-08-31 07:32:19 +00:00
|
|
|
auto &C = CGM.getContext();
|
|
|
|
|
auto *Length = E->getLength();
|
|
|
|
|
llvm::APSInt ConstLength;
|
|
|
|
|
if (Length) {
|
|
|
|
|
// Idx = LowerBound + Length - 1;
|
2020-07-12 20:31:08 -07:00
|
|
|
if (Optional<llvm::APSInt> CL = Length->getIntegerConstantExpr(C)) {
|
|
|
|
|
ConstLength = CL->zextOrTrunc(PointerWidthInBits);
|
2015-08-31 07:32:19 +00:00
|
|
|
Length = nullptr;
|
|
|
|
|
}
|
|
|
|
|
auto *LowerBound = E->getLowerBound();
|
|
|
|
|
llvm::APSInt ConstLowerBound(PointerWidthInBits, /*isUnsigned=*/false);
|
2020-07-12 20:31:08 -07:00
|
|
|
if (LowerBound) {
|
|
|
|
|
if (Optional<llvm::APSInt> LB = LowerBound->getIntegerConstantExpr(C)) {
|
|
|
|
|
ConstLowerBound = LB->zextOrTrunc(PointerWidthInBits);
|
|
|
|
|
LowerBound = nullptr;
|
|
|
|
|
}
|
2015-08-31 07:32:19 +00:00
|
|
|
}
|
|
|
|
|
if (!Length)
|
|
|
|
|
--ConstLength;
|
|
|
|
|
else if (!LowerBound)
|
|
|
|
|
--ConstLowerBound;
|
|
|
|
|
|
|
|
|
|
if (Length || LowerBound) {
|
|
|
|
|
auto *LowerBoundVal =
|
|
|
|
|
LowerBound
|
|
|
|
|
? Builder.CreateIntCast(
|
|
|
|
|
EmitScalarExpr(LowerBound), IntPtrTy,
|
|
|
|
|
LowerBound->getType()->hasSignedIntegerRepresentation())
|
|
|
|
|
: llvm::ConstantInt::get(IntPtrTy, ConstLowerBound);
|
|
|
|
|
auto *LengthVal =
|
|
|
|
|
Length
|
|
|
|
|
? Builder.CreateIntCast(
|
|
|
|
|
EmitScalarExpr(Length), IntPtrTy,
|
|
|
|
|
Length->getType()->hasSignedIntegerRepresentation())
|
|
|
|
|
: llvm::ConstantInt::get(IntPtrTy, ConstLength);
|
|
|
|
|
Idx = Builder.CreateAdd(LowerBoundVal, LengthVal, "lb_add_len",
|
|
|
|
|
/*HasNUW=*/false,
|
|
|
|
|
!getLangOpts().isSignedOverflowDefined());
|
|
|
|
|
if (Length && LowerBound) {
|
|
|
|
|
Idx = Builder.CreateSub(
|
|
|
|
|
Idx, llvm::ConstantInt::get(IntPtrTy, /*V=*/1), "idx_sub_1",
|
|
|
|
|
/*HasNUW=*/false, !getLangOpts().isSignedOverflowDefined());
|
|
|
|
|
}
|
|
|
|
|
} else
|
|
|
|
|
Idx = llvm::ConstantInt::get(IntPtrTy, ConstLength + ConstLowerBound);
|
|
|
|
|
} else {
|
|
|
|
|
// Idx = ArraySize - 1;
|
2016-02-04 11:27:03 +00:00
|
|
|
QualType ArrayTy = BaseTy->isPointerType()
|
|
|
|
|
? E->getBase()->IgnoreParenImpCasts()->getType()
|
|
|
|
|
: BaseTy;
|
|
|
|
|
if (auto *VAT = C.getAsVariableArrayType(ArrayTy)) {
|
2015-08-31 07:32:19 +00:00
|
|
|
Length = VAT->getSizeExpr();
|
2020-07-12 20:31:08 -07:00
|
|
|
if (Optional<llvm::APSInt> L = Length->getIntegerConstantExpr(C)) {
|
|
|
|
|
ConstLength = *L;
|
2015-08-31 07:32:19 +00:00
|
|
|
Length = nullptr;
|
2020-07-12 20:31:08 -07:00
|
|
|
}
|
2015-08-31 07:32:19 +00:00
|
|
|
} else {
|
2016-02-04 11:27:03 +00:00
|
|
|
auto *CAT = C.getAsConstantArrayType(ArrayTy);
|
2015-08-31 07:32:19 +00:00
|
|
|
ConstLength = CAT->getSize();
|
|
|
|
|
}
|
|
|
|
|
if (Length) {
|
|
|
|
|
auto *LengthVal = Builder.CreateIntCast(
|
|
|
|
|
EmitScalarExpr(Length), IntPtrTy,
|
|
|
|
|
Length->getType()->hasSignedIntegerRepresentation());
|
|
|
|
|
Idx = Builder.CreateSub(
|
|
|
|
|
LengthVal, llvm::ConstantInt::get(IntPtrTy, /*V=*/1), "len_sub_1",
|
|
|
|
|
/*HasNUW=*/false, !getLangOpts().isSignedOverflowDefined());
|
|
|
|
|
} else {
|
|
|
|
|
ConstLength = ConstLength.zextOrTrunc(PointerWidthInBits);
|
|
|
|
|
--ConstLength;
|
|
|
|
|
Idx = llvm::ConstantInt::get(IntPtrTy, ConstLength);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
assert(Idx);
|
|
|
|
|
|
2016-02-04 11:27:03 +00:00
|
|
|
Address EltPtr = Address::invalid();
|
2017-05-18 17:07:11 +00:00
|
|
|
LValueBaseInfo BaseInfo;
|
2017-10-13 17:34:18 +00:00
|
|
|
TBAAAccessInfo TBAAInfo;
|
2015-08-31 07:32:19 +00:00
|
|
|
if (auto *VLA = getContext().getAsVariableArrayType(ResultExprTy)) {
|
2016-02-04 11:27:03 +00:00
|
|
|
// The base must be a pointer, which is not an aggregate. Emit
|
|
|
|
|
// it. It needs to be emitted first in case it's what captures
|
|
|
|
|
// the VLA bounds.
|
|
|
|
|
Address Base =
|
2017-10-13 17:34:18 +00:00
|
|
|
emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, TBAAInfo,
|
|
|
|
|
BaseTy, VLA->getElementType(), IsLowerBound);
|
2015-08-31 07:32:19 +00:00
|
|
|
// The element count here is the total number of non-VLA elements.
|
2018-02-03 13:55:59 +00:00
|
|
|
llvm::Value *NumElements = getVLASize(VLA).NumElts;
|
2015-08-31 07:32:19 +00:00
|
|
|
|
|
|
|
|
// Effectively, the multiply by the VLA size is part of the GEP.
|
|
|
|
|
// GEP indexes are signed, and scaling an index isn't permitted to
|
|
|
|
|
// signed-overflow, so we use the same semantics for our explicit
|
|
|
|
|
// multiply. We suppress this if overflow is not undefined behavior.
|
|
|
|
|
if (getLangOpts().isSignedOverflowDefined())
|
2016-02-04 11:27:03 +00:00
|
|
|
Idx = Builder.CreateMul(Idx, NumElements);
|
2015-08-31 07:32:19 +00:00
|
|
|
else
|
2016-02-04 11:27:03 +00:00
|
|
|
Idx = Builder.CreateNSWMul(Idx, NumElements);
|
|
|
|
|
EltPtr = emitArraySubscriptGEP(*this, Base, Idx, VLA->getElementType(),
|
2017-06-01 19:22:18 +00:00
|
|
|
!getLangOpts().isSignedOverflowDefined(),
|
2019-07-16 04:46:31 +00:00
|
|
|
/*signedIndices=*/false, E->getExprLoc());
|
2016-02-04 11:27:03 +00:00
|
|
|
} else if (const Expr *Array = isSimpleArrayDecayOperand(E->getBase())) {
|
|
|
|
|
// If this is A[i] where A is an array, the frontend will have decayed the
|
|
|
|
|
// base to be a ArrayToPointerDecay implicit cast. While correct, it is
|
|
|
|
|
// inefficient at -O0 to emit a "gep A, 0, 0" when codegen'ing it, then a
|
|
|
|
|
// "gep x, i" here. Emit one "gep A, 0, i".
|
|
|
|
|
assert(Array->getType()->isArrayType() &&
|
|
|
|
|
"Array to pointer decay must have array source type!");
|
|
|
|
|
LValue ArrayLV;
|
|
|
|
|
// For simple multidimensional array indexing, set the 'accessed' flag for
|
|
|
|
|
// better bounds-checking of the base expression.
|
|
|
|
|
if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(Array))
|
|
|
|
|
ArrayLV = EmitArraySubscriptExpr(ASE, /*Accessed*/ true);
|
2015-08-31 07:32:19 +00:00
|
|
|
else
|
2016-02-04 11:27:03 +00:00
|
|
|
ArrayLV = EmitLValue(Array);
|
2015-08-31 07:32:19 +00:00
|
|
|
|
2016-02-04 11:27:03 +00:00
|
|
|
// Propagate the alignment from the array itself to the result.
|
|
|
|
|
EltPtr = emitArraySubscriptGEP(
|
2019-12-03 15:17:01 -08:00
|
|
|
*this, ArrayLV.getAddress(*this), {CGM.getSize(CharUnits::Zero()), Idx},
|
2017-06-01 19:22:18 +00:00
|
|
|
ResultExprTy, !getLangOpts().isSignedOverflowDefined(),
|
2019-07-16 04:46:31 +00:00
|
|
|
/*signedIndices=*/false, E->getExprLoc());
|
2017-05-18 17:07:11 +00:00
|
|
|
BaseInfo = ArrayLV.getBaseInfo();
|
2017-10-31 11:05:34 +00:00
|
|
|
TBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, ResultExprTy);
|
2016-02-04 11:27:03 +00:00
|
|
|
} else {
|
2017-05-18 17:07:11 +00:00
|
|
|
Address Base = emitOMPArraySectionBase(*this, E->getBase(), BaseInfo,
|
2017-10-13 17:34:18 +00:00
|
|
|
TBAAInfo, BaseTy, ResultExprTy,
|
|
|
|
|
IsLowerBound);
|
2016-02-04 11:27:03 +00:00
|
|
|
EltPtr = emitArraySubscriptGEP(*this, Base, Idx, ResultExprTy,
|
2017-06-01 19:22:18 +00:00
|
|
|
!getLangOpts().isSignedOverflowDefined(),
|
2019-07-16 04:46:31 +00:00
|
|
|
/*signedIndices=*/false, E->getExprLoc());
|
2016-02-04 11:27:03 +00:00
|
|
|
}
|
2015-08-31 07:32:19 +00:00
|
|
|
|
2017-10-13 17:34:18 +00:00
|
|
|
return MakeAddrLValue(EltPtr, ResultExprTy, BaseInfo, TBAAInfo);
|
2015-08-31 07:32:19 +00:00
|
|
|
}
|
|
|
|
|
|
2007-08-02 23:37:31 +00:00
|
|
|
LValue CodeGenFunction::
|
2008-04-18 23:10:10 +00:00
|
|
|
EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
|
2007-08-02 23:37:31 +00:00
|
|
|
// Emit the base vector as an l-value.
|
2009-02-16 21:11:58 +00:00
|
|
|
LValue Base;
|
|
|
|
|
|
|
|
|
|
// ExtVectorElementExpr's base can either be a vector or pointer to vector.
|
2009-12-23 21:31:11 +00:00
|
|
|
if (E->isArrow()) {
|
|
|
|
|
// If it is a pointer to a vector, emit the address and form an lvalue with
|
|
|
|
|
// it.
|
2017-05-18 17:07:11 +00:00
|
|
|
LValueBaseInfo BaseInfo;
|
2017-10-17 09:12:13 +00:00
|
|
|
TBAAAccessInfo TBAAInfo;
|
|
|
|
|
Address Ptr = EmitPointerWithAlignment(E->getBase(), &BaseInfo, &TBAAInfo);
|
2020-01-11 15:33:25 +00:00
|
|
|
const auto *PT = E->getBase()->getType()->castAs<PointerType>();
|
2017-10-17 09:12:13 +00:00
|
|
|
Base = MakeAddrLValue(Ptr, PT->getPointeeType(), BaseInfo, TBAAInfo);
|
2010-08-21 03:44:13 +00:00
|
|
|
Base.getQuals().removeObjCGCAttr();
|
2010-11-24 05:12:34 +00:00
|
|
|
} else if (E->getBase()->isGLValue()) {
|
2009-12-23 21:31:11 +00:00
|
|
|
// Otherwise, if the base is an lvalue ( as in the case of foo.x.x),
|
|
|
|
|
// emit the base as an lvalue.
|
|
|
|
|
assert(E->getBase()->getType()->isVectorType());
|
|
|
|
|
Base = EmitLValue(E->getBase());
|
|
|
|
|
} else {
|
|
|
|
|
// Otherwise, the base is a normal rvalue (as in (V+V).x), emit it as such.
|
2011-06-16 04:16:24 +00:00
|
|
|
assert(E->getBase()->getType()->isVectorType() &&
|
2010-01-04 18:02:28 +00:00
|
|
|
"Result must be a vector");
|
2009-12-23 21:31:11 +00:00
|
|
|
llvm::Value *Vec = EmitScalarExpr(E->getBase());
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2009-12-23 21:33:41 +00:00
|
|
|
// Store the vector to memory (because LValue wants an address).
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Address VecMem = CreateMemTemp(E->getBase()->getType());
|
2009-12-23 21:31:11 +00:00
|
|
|
Builder.CreateStore(Vec, VecMem);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Base = MakeAddrLValue(VecMem, E->getBase()->getType(),
|
2017-10-10 09:39:32 +00:00
|
|
|
AlignmentSource::Decl);
|
2009-02-16 21:11:58 +00:00
|
|
|
}
|
2011-06-16 04:16:24 +00:00
|
|
|
|
|
|
|
|
QualType type =
|
|
|
|
|
E->getType().withCVRQualifiers(Base.getQuals().getCVRQualifiers());
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2008-05-13 21:03:02 +00:00
|
|
|
// Encode the element access list into a vector of unsigned indices.
|
2015-07-28 16:25:32 +00:00
|
|
|
SmallVector<uint32_t, 4> Indices;
|
2008-05-13 21:03:02 +00:00
|
|
|
E->getEncodedElementAccess(Indices);
|
|
|
|
|
|
|
|
|
|
if (Base.isSimple()) {
|
2015-07-28 16:25:32 +00:00
|
|
|
llvm::Constant *CV =
|
|
|
|
|
llvm::ConstantDataVector::get(getLLVMContext(), Indices);
|
2019-12-03 15:17:01 -08:00
|
|
|
return LValue::MakeExtVectorElt(Base.getAddress(*this), CV, type,
|
2017-10-17 10:17:43 +00:00
|
|
|
Base.getBaseInfo(), TBAAAccessInfo());
|
2008-05-09 06:41:27 +00:00
|
|
|
}
|
2008-05-13 21:03:02 +00:00
|
|
|
assert(Base.isExtVectorElt() && "Can only subscript lvalue vec elts here!");
|
|
|
|
|
|
|
|
|
|
llvm::Constant *BaseElts = Base.getExtVectorElts();
|
2011-07-23 10:55:15 +00:00
|
|
|
SmallVector<llvm::Constant *, 4> CElts;
|
2007-08-02 23:37:31 +00:00
|
|
|
|
2012-01-30 06:20:36 +00:00
|
|
|
for (unsigned i = 0, e = Indices.size(); i != e; ++i)
|
|
|
|
|
CElts.push_back(BaseElts->getAggregateElement(Indices[i]));
|
2011-02-15 00:14:06 +00:00
|
|
|
llvm::Constant *CV = llvm::ConstantVector::get(CElts);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
return LValue::MakeExtVectorElt(Base.getExtVectorAddress(), CV, type,
|
2017-10-17 10:17:43 +00:00
|
|
|
Base.getBaseInfo(), TBAAAccessInfo());
|
2007-08-02 23:37:31 +00:00
|
|
|
}
|
|
|
|
|
|
2007-10-23 20:28:39 +00:00
|
|
|
LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
|
2017-08-25 10:07:00 +00:00
|
|
|
if (DeclRefExpr *DRE = tryToConvertMemberExprToDeclRefExpr(*this, E)) {
|
|
|
|
|
EmitIgnoredExpr(E->getBase());
|
|
|
|
|
return EmitDeclRefLValue(DRE);
|
|
|
|
|
}
|
|
|
|
|
|
2007-10-24 22:26:28 +00:00
|
|
|
Expr *BaseExpr = E->getBase();
|
2007-12-02 18:52:07 +00:00
|
|
|
// If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar.
|
2012-04-16 03:54:45 +00:00
|
|
|
LValue BaseLV;
|
2012-08-24 00:54:33 +00:00
|
|
|
if (E->isArrow()) {
|
2017-05-18 17:07:11 +00:00
|
|
|
LValueBaseInfo BaseInfo;
|
2017-10-17 09:12:13 +00:00
|
|
|
TBAAAccessInfo TBAAInfo;
|
|
|
|
|
Address Addr = EmitPointerWithAlignment(BaseExpr, &BaseInfo, &TBAAInfo);
|
2012-08-24 00:54:33 +00:00
|
|
|
QualType PtrTy = BaseExpr->getType()->getPointeeType();
|
Retry^2: [ubsan] Reduce null checking of C++ object pointers (PR27581)
This patch teaches ubsan to insert exactly one null check for the 'this'
pointer per method/lambda.
Previously, given a load of a member variable from an instance method
('this->x'), ubsan would insert a null check for 'this', and another
null check for '&this->x', before allowing the load to occur.
Similarly, given a call to a method from another method bound to the
same instance ('this->foo()'), ubsan would a redundant null check for
'this'. There is also a redundant null check in the case where the
object pointer is a reference ('Ref.foo()').
This patch teaches ubsan to remove the redundant null checks identified
above.
Testing: check-clang, check-ubsan, and a stage2 ubsan build.
I also compiled X86FastISel.cpp with -fsanitize=null using
patched/unpatched clangs based on r293572. Here are the number of null
checks emitted:
-------------------------------------
| Setup | # of null checks |
-------------------------------------
| unpatched, -O0 | 21767 |
| patched, -O0 | 10758 |
-------------------------------------
Changes since the initial commit:
- Don't introduce any unintentional object-size or alignment checks.
- Don't rely on IRGen of C labels in the test.
Differential Revision: https://reviews.llvm.org/D29530
llvm-svn: 295515
2017-02-17 23:22:59 +00:00
|
|
|
SanitizerSet SkippedChecks;
|
2017-04-14 22:03:34 +00:00
|
|
|
bool IsBaseCXXThis = IsWrappedCXXThis(BaseExpr);
|
|
|
|
|
if (IsBaseCXXThis)
|
|
|
|
|
SkippedChecks.set(SanitizerKind::Alignment, true);
|
|
|
|
|
if (IsBaseCXXThis || isa<DeclRefExpr>(BaseExpr))
|
Retry^2: [ubsan] Reduce null checking of C++ object pointers (PR27581)
This patch teaches ubsan to insert exactly one null check for the 'this'
pointer per method/lambda.
Previously, given a load of a member variable from an instance method
('this->x'), ubsan would insert a null check for 'this', and another
null check for '&this->x', before allowing the load to occur.
Similarly, given a call to a method from another method bound to the
same instance ('this->foo()'), ubsan would a redundant null check for
'this'. There is also a redundant null check in the case where the
object pointer is a reference ('Ref.foo()').
This patch teaches ubsan to remove the redundant null checks identified
above.
Testing: check-clang, check-ubsan, and a stage2 ubsan build.
I also compiled X86FastISel.cpp with -fsanitize=null using
patched/unpatched clangs based on r293572. Here are the number of null
checks emitted:
-------------------------------------
| Setup | # of null checks |
-------------------------------------
| unpatched, -O0 | 21767 |
| patched, -O0 | 10758 |
-------------------------------------
Changes since the initial commit:
- Don't introduce any unintentional object-size or alignment checks.
- Don't rely on IRGen of C labels in the test.
Differential Revision: https://reviews.llvm.org/D29530
llvm-svn: 295515
2017-02-17 23:22:59 +00:00
|
|
|
SkippedChecks.set(SanitizerKind::Null, true);
|
|
|
|
|
EmitTypeCheck(TCK_MemberAccess, E->getExprLoc(), Addr.getPointer(), PtrTy,
|
|
|
|
|
/*Alignment=*/CharUnits::Zero(), SkippedChecks);
|
2017-10-17 09:12:13 +00:00
|
|
|
BaseLV = MakeAddrLValue(Addr, PtrTy, BaseInfo, TBAAInfo);
|
2012-08-24 00:54:33 +00:00
|
|
|
} else
|
2012-09-08 02:08:36 +00:00
|
|
|
BaseLV = EmitCheckedLValue(BaseExpr, TCK_MemberAccess);
|
2007-10-23 20:28:39 +00:00
|
|
|
|
2009-11-07 23:06:58 +00:00
|
|
|
NamedDecl *ND = E->getMemberDecl();
|
2014-05-09 00:08:36 +00:00
|
|
|
if (auto *Field = dyn_cast<FieldDecl>(ND)) {
|
2012-04-16 03:54:45 +00:00
|
|
|
LValue LV = EmitLValueForField(BaseLV, Field);
|
2009-11-07 23:06:58 +00:00
|
|
|
setObjCGCLValueClass(getContext(), E, LV);
|
2019-12-19 10:01:10 -05:00
|
|
|
if (getLangOpts().OpenMP) {
|
|
|
|
|
// If the member was explicitly marked as nontemporal, mark it as
|
|
|
|
|
// nontemporal. If the base lvalue is marked as nontemporal, mark access
|
|
|
|
|
// to children as nontemporal too.
|
|
|
|
|
if ((IsWrappedCXXThis(BaseExpr) &&
|
|
|
|
|
CGM.getOpenMPRuntime().isNontemporalDecl(Field)) ||
|
|
|
|
|
BaseLV.isNontemporal())
|
|
|
|
|
LV.setNontemporal(/*Value=*/true);
|
|
|
|
|
}
|
2009-11-07 23:06:58 +00:00
|
|
|
return LV;
|
|
|
|
|
}
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *FD = dyn_cast<FunctionDecl>(ND))
|
2009-11-26 06:08:14 +00:00
|
|
|
return EmitFunctionDeclLValue(*this, E, FD);
|
|
|
|
|
|
2011-09-23 05:06:16 +00:00
|
|
|
llvm_unreachable("Unhandled member declaration!");
|
2008-02-09 08:50:58 +00:00
|
|
|
}
|
2007-10-23 20:28:39 +00:00
|
|
|
|
2013-05-03 07:33:41 +00:00
|
|
|
/// Given that we are currently emitting a lambda, emit an l-value for
|
|
|
|
|
/// one of its members.
|
|
|
|
|
LValue CodeGenFunction::EmitLValueForLambdaField(const FieldDecl *Field) {
|
|
|
|
|
assert(cast<CXXMethodDecl>(CurCodeDecl)->getParent()->isLambda());
|
|
|
|
|
assert(cast<CXXMethodDecl>(CurCodeDecl)->getParent() == Field->getParent());
|
|
|
|
|
QualType LambdaTagType =
|
|
|
|
|
getContext().getTagDeclType(Field->getParent());
|
|
|
|
|
LValue LambdaLV = MakeNaturalAlignAddrLValue(CXXABIThisValue, LambdaTagType);
|
|
|
|
|
return EmitLValueForField(LambdaLV, Field);
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-16 17:24:33 +00:00
|
|
|
/// Get the field index in the debug info. The debug info structure/union
|
|
|
|
|
/// will ignore the unnamed bitfields.
|
|
|
|
|
unsigned CodeGenFunction::getDebugInfoFIndex(const RecordDecl *Rec,
|
|
|
|
|
unsigned FieldIndex) {
|
|
|
|
|
unsigned I = 0, Skipped = 0;
|
|
|
|
|
|
|
|
|
|
for (auto F : Rec->getDefinition()->fields()) {
|
|
|
|
|
if (I == FieldIndex)
|
|
|
|
|
break;
|
|
|
|
|
if (F->isUnnamedBitfield())
|
|
|
|
|
Skipped++;
|
|
|
|
|
I++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return FieldIndex - Skipped;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-20 20:44:45 +00:00
|
|
|
/// Get the address of a zero-sized field within a record. The resulting
|
|
|
|
|
/// address doesn't necessarily have the right type.
|
|
|
|
|
static Address emitAddrOfZeroSizeField(CodeGenFunction &CGF, Address Base,
|
|
|
|
|
const FieldDecl *Field) {
|
|
|
|
|
CharUnits Offset = CGF.getContext().toCharUnitsFromBits(
|
|
|
|
|
CGF.getContext().getFieldOffset(Field));
|
|
|
|
|
if (Offset.isZero())
|
|
|
|
|
return Base;
|
|
|
|
|
Base = CGF.Builder.CreateElementBitCast(Base, CGF.Int8Ty);
|
|
|
|
|
return CGF.Builder.CreateConstInBoundsByteGEP(Base, Offset);
|
|
|
|
|
}
|
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
/// Drill down to the storage of a field without walking into
|
|
|
|
|
/// reference types.
|
|
|
|
|
///
|
|
|
|
|
/// The resulting address doesn't necessarily have the right type.
|
|
|
|
|
static Address emitAddrOfFieldStorage(CodeGenFunction &CGF, Address base,
|
|
|
|
|
const FieldDecl *field) {
|
2019-06-20 20:44:45 +00:00
|
|
|
if (field->isZeroSize(CGF.getContext()))
|
|
|
|
|
return emitAddrOfZeroSizeField(CGF, base, field);
|
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
const RecordDecl *rec = field->getParent();
|
2018-07-30 19:24:48 +00: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 08:05:57 +00:00
|
|
|
unsigned idx =
|
|
|
|
|
CGF.CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field);
|
|
|
|
|
|
2019-02-09 22:22:28 +00:00
|
|
|
return CGF.Builder.CreateStructGEP(base, idx, field->getName());
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
}
|
|
|
|
|
|
2020-02-02 14:54:16 -08:00
|
|
|
static Address emitPreserveStructAccess(CodeGenFunction &CGF, LValue base,
|
|
|
|
|
Address addr, const FieldDecl *field) {
|
[BPF] Preserve debuginfo array/union/struct type/access index
For background of BPF CO-RE project, please refer to
http://vger.kernel.org/bpfconf2019.html
In summary, BPF CO-RE intends to compile bpf programs
adjustable on struct/union layout change so the same
program can run on multiple kernels with adjustment
before loading based on native kernel structures.
In order to do this, we need keep track of GEP(getelementptr)
instruction base and result debuginfo types, so we
can adjust on the host based on kernel BTF info.
Capturing such information as an IR optimization is hard
as various optimization may have tweaked GEP and also
union is replaced by structure it is impossible to track
fieldindex for union member accesses.
Three intrinsic functions, preserve_{array,union,struct}_access_index,
are introducted.
addr = preserve_array_access_index(base, index, dimension)
addr = preserve_union_access_index(base, di_index)
addr = preserve_struct_access_index(base, gep_index, di_index)
here,
base: the base pointer for the array/union/struct access.
index: the last access index for array, the same for IR/DebugInfo layout.
dimension: the array dimension.
gep_index: the access index based on IR layout.
di_index: the access index based on user/debuginfo types.
If using these intrinsics blindly, i.e., transforming all GEPs
to these intrinsics and later on reducing them to GEPs, we have
seen up to 7% more instructions generated. To avoid such an overhead,
a clang builtin is proposed:
base = __builtin_preserve_access_index(base)
such that user wraps to-be-relocated GEPs in this builtin
and preserve_*_access_index intrinsics only apply to
those GEPs. Such a buyin will prevent performance degradation
if people do not use CO-RE, even for programs which use
bpf_probe_read().
For example, for the following example,
$ cat test.c
struct sk_buff {
int i;
int b1:1;
int b2:2;
union {
struct {
int o1;
int o2;
} o;
struct {
char flags;
char dev_id;
} dev;
int netid;
} u[10];
};
static int (*bpf_probe_read)(void *dst, int size, const void *unsafe_ptr)
= (void *) 4;
#define _(x) (__builtin_preserve_access_index(x))
int bpf_prog(struct sk_buff *ctx) {
char dev_id;
bpf_probe_read(&dev_id, sizeof(char), _(&ctx->u[5].dev.dev_id));
return dev_id;
}
$ clang -target bpf -O2 -g -emit-llvm -S -mllvm -print-before-all \
test.c >& log
The generated IR looks like below:
...
define dso_local i32 @bpf_prog(%struct.sk_buff*) #0 !dbg !15 {
%2 = alloca %struct.sk_buff*, align 8
%3 = alloca i8, align 1
store %struct.sk_buff* %0, %struct.sk_buff** %2, align 8, !tbaa !45
call void @llvm.dbg.declare(metadata %struct.sk_buff** %2, metadata !43, metadata !DIExpression()), !dbg !49
call void @llvm.lifetime.start.p0i8(i64 1, i8* %3) #4, !dbg !50
call void @llvm.dbg.declare(metadata i8* %3, metadata !44, metadata !DIExpression()), !dbg !51
%4 = load i32 (i8*, i32, i8*)*, i32 (i8*, i32, i8*)** @bpf_probe_read, align 8, !dbg !52, !tbaa !45
%5 = load %struct.sk_buff*, %struct.sk_buff** %2, align 8, !dbg !53, !tbaa !45
%6 = call [10 x %union.anon]* @llvm.preserve.struct.access.index.p0a10s_union.anons.p0s_struct.sk_buffs(
%struct.sk_buff* %5, i32 2, i32 3), !dbg !53, !llvm.preserve.access.index !19
%7 = call %union.anon* @llvm.preserve.array.access.index.p0s_union.anons.p0a10s_union.anons(
[10 x %union.anon]* %6, i32 1, i32 5), !dbg !53
%8 = call %union.anon* @llvm.preserve.union.access.index.p0s_union.anons.p0s_union.anons(
%union.anon* %7, i32 1), !dbg !53, !llvm.preserve.access.index !26
%9 = bitcast %union.anon* %8 to %struct.anon.0*, !dbg !53
%10 = call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.anon.0s(
%struct.anon.0* %9, i32 1, i32 1), !dbg !53, !llvm.preserve.access.index !34
%11 = call i32 %4(i8* %3, i32 1, i8* %10), !dbg !52
%12 = load i8, i8* %3, align 1, !dbg !54, !tbaa !55
%13 = sext i8 %12 to i32, !dbg !54
call void @llvm.lifetime.end.p0i8(i64 1, i8* %3) #4, !dbg !56
ret i32 %13, !dbg !57
}
!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "sk_buff", file: !3, line: 1, size: 704, elements: !20)
!26 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !19, file: !3, line: 5, size: 64, elements: !27)
!34 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !26, file: !3, line: 10, size: 16, elements: !35)
Note that @llvm.preserve.{struct,union}.access.index calls have metadata llvm.preserve.access.index
attached to instructions to provide struct/union debuginfo type information.
For &ctx->u[5].dev.dev_id,
. The "%6 = ..." represents struct member "u" with index 2 for IR layout and index 3 for DI layout.
. The "%7 = ..." represents array subscript "5".
. The "%8 = ..." represents union member "dev" with index 1 for DI layout.
. The "%10 = ..." represents struct member "dev_id" with index 1 for both IR and DI layout.
Basically, traversing the use-def chain recursively for the 3rd argument of bpf_probe_read() and
examining all preserve_*_access_index calls, the debuginfo struct/union/array access index
can be achieved.
The intrinsics also contain enough information to regenerate codes for IR layout.
For array and structure intrinsics, the proper GEP can be constructed.
For union intrinsics, replacing all uses of "addr" with "base" should be enough.
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D61809
llvm-svn: 365438
2019-07-09 04:21:50 +00:00
|
|
|
const RecordDecl *rec = field->getParent();
|
2020-02-02 14:54:16 -08:00
|
|
|
llvm::DIType *DbgInfo = CGF.getDebugInfo()->getOrCreateStandaloneType(
|
|
|
|
|
base.getType(), rec->getLocation());
|
[BPF] Preserve debuginfo array/union/struct type/access index
For background of BPF CO-RE project, please refer to
http://vger.kernel.org/bpfconf2019.html
In summary, BPF CO-RE intends to compile bpf programs
adjustable on struct/union layout change so the same
program can run on multiple kernels with adjustment
before loading based on native kernel structures.
In order to do this, we need keep track of GEP(getelementptr)
instruction base and result debuginfo types, so we
can adjust on the host based on kernel BTF info.
Capturing such information as an IR optimization is hard
as various optimization may have tweaked GEP and also
union is replaced by structure it is impossible to track
fieldindex for union member accesses.
Three intrinsic functions, preserve_{array,union,struct}_access_index,
are introducted.
addr = preserve_array_access_index(base, index, dimension)
addr = preserve_union_access_index(base, di_index)
addr = preserve_struct_access_index(base, gep_index, di_index)
here,
base: the base pointer for the array/union/struct access.
index: the last access index for array, the same for IR/DebugInfo layout.
dimension: the array dimension.
gep_index: the access index based on IR layout.
di_index: the access index based on user/debuginfo types.
If using these intrinsics blindly, i.e., transforming all GEPs
to these intrinsics and later on reducing them to GEPs, we have
seen up to 7% more instructions generated. To avoid such an overhead,
a clang builtin is proposed:
base = __builtin_preserve_access_index(base)
such that user wraps to-be-relocated GEPs in this builtin
and preserve_*_access_index intrinsics only apply to
those GEPs. Such a buyin will prevent performance degradation
if people do not use CO-RE, even for programs which use
bpf_probe_read().
For example, for the following example,
$ cat test.c
struct sk_buff {
int i;
int b1:1;
int b2:2;
union {
struct {
int o1;
int o2;
} o;
struct {
char flags;
char dev_id;
} dev;
int netid;
} u[10];
};
static int (*bpf_probe_read)(void *dst, int size, const void *unsafe_ptr)
= (void *) 4;
#define _(x) (__builtin_preserve_access_index(x))
int bpf_prog(struct sk_buff *ctx) {
char dev_id;
bpf_probe_read(&dev_id, sizeof(char), _(&ctx->u[5].dev.dev_id));
return dev_id;
}
$ clang -target bpf -O2 -g -emit-llvm -S -mllvm -print-before-all \
test.c >& log
The generated IR looks like below:
...
define dso_local i32 @bpf_prog(%struct.sk_buff*) #0 !dbg !15 {
%2 = alloca %struct.sk_buff*, align 8
%3 = alloca i8, align 1
store %struct.sk_buff* %0, %struct.sk_buff** %2, align 8, !tbaa !45
call void @llvm.dbg.declare(metadata %struct.sk_buff** %2, metadata !43, metadata !DIExpression()), !dbg !49
call void @llvm.lifetime.start.p0i8(i64 1, i8* %3) #4, !dbg !50
call void @llvm.dbg.declare(metadata i8* %3, metadata !44, metadata !DIExpression()), !dbg !51
%4 = load i32 (i8*, i32, i8*)*, i32 (i8*, i32, i8*)** @bpf_probe_read, align 8, !dbg !52, !tbaa !45
%5 = load %struct.sk_buff*, %struct.sk_buff** %2, align 8, !dbg !53, !tbaa !45
%6 = call [10 x %union.anon]* @llvm.preserve.struct.access.index.p0a10s_union.anons.p0s_struct.sk_buffs(
%struct.sk_buff* %5, i32 2, i32 3), !dbg !53, !llvm.preserve.access.index !19
%7 = call %union.anon* @llvm.preserve.array.access.index.p0s_union.anons.p0a10s_union.anons(
[10 x %union.anon]* %6, i32 1, i32 5), !dbg !53
%8 = call %union.anon* @llvm.preserve.union.access.index.p0s_union.anons.p0s_union.anons(
%union.anon* %7, i32 1), !dbg !53, !llvm.preserve.access.index !26
%9 = bitcast %union.anon* %8 to %struct.anon.0*, !dbg !53
%10 = call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.anon.0s(
%struct.anon.0* %9, i32 1, i32 1), !dbg !53, !llvm.preserve.access.index !34
%11 = call i32 %4(i8* %3, i32 1, i8* %10), !dbg !52
%12 = load i8, i8* %3, align 1, !dbg !54, !tbaa !55
%13 = sext i8 %12 to i32, !dbg !54
call void @llvm.lifetime.end.p0i8(i64 1, i8* %3) #4, !dbg !56
ret i32 %13, !dbg !57
}
!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "sk_buff", file: !3, line: 1, size: 704, elements: !20)
!26 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !19, file: !3, line: 5, size: 64, elements: !27)
!34 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !26, file: !3, line: 10, size: 16, elements: !35)
Note that @llvm.preserve.{struct,union}.access.index calls have metadata llvm.preserve.access.index
attached to instructions to provide struct/union debuginfo type information.
For &ctx->u[5].dev.dev_id,
. The "%6 = ..." represents struct member "u" with index 2 for IR layout and index 3 for DI layout.
. The "%7 = ..." represents array subscript "5".
. The "%8 = ..." represents union member "dev" with index 1 for DI layout.
. The "%10 = ..." represents struct member "dev_id" with index 1 for both IR and DI layout.
Basically, traversing the use-def chain recursively for the 3rd argument of bpf_probe_read() and
examining all preserve_*_access_index calls, the debuginfo struct/union/array access index
can be achieved.
The intrinsics also contain enough information to regenerate codes for IR layout.
For array and structure intrinsics, the proper GEP can be constructed.
For union intrinsics, replacing all uses of "addr" with "base" should be enough.
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D61809
llvm-svn: 365438
2019-07-09 04:21:50 +00:00
|
|
|
|
|
|
|
|
unsigned idx =
|
|
|
|
|
CGF.CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field);
|
|
|
|
|
|
|
|
|
|
return CGF.Builder.CreatePreserveStructAccessIndex(
|
2020-02-02 14:54:16 -08:00
|
|
|
addr, idx, CGF.getDebugInfoFIndex(rec, field->getFieldIndex()), DbgInfo);
|
[BPF] Preserve debuginfo array/union/struct type/access index
For background of BPF CO-RE project, please refer to
http://vger.kernel.org/bpfconf2019.html
In summary, BPF CO-RE intends to compile bpf programs
adjustable on struct/union layout change so the same
program can run on multiple kernels with adjustment
before loading based on native kernel structures.
In order to do this, we need keep track of GEP(getelementptr)
instruction base and result debuginfo types, so we
can adjust on the host based on kernel BTF info.
Capturing such information as an IR optimization is hard
as various optimization may have tweaked GEP and also
union is replaced by structure it is impossible to track
fieldindex for union member accesses.
Three intrinsic functions, preserve_{array,union,struct}_access_index,
are introducted.
addr = preserve_array_access_index(base, index, dimension)
addr = preserve_union_access_index(base, di_index)
addr = preserve_struct_access_index(base, gep_index, di_index)
here,
base: the base pointer for the array/union/struct access.
index: the last access index for array, the same for IR/DebugInfo layout.
dimension: the array dimension.
gep_index: the access index based on IR layout.
di_index: the access index based on user/debuginfo types.
If using these intrinsics blindly, i.e., transforming all GEPs
to these intrinsics and later on reducing them to GEPs, we have
seen up to 7% more instructions generated. To avoid such an overhead,
a clang builtin is proposed:
base = __builtin_preserve_access_index(base)
such that user wraps to-be-relocated GEPs in this builtin
and preserve_*_access_index intrinsics only apply to
those GEPs. Such a buyin will prevent performance degradation
if people do not use CO-RE, even for programs which use
bpf_probe_read().
For example, for the following example,
$ cat test.c
struct sk_buff {
int i;
int b1:1;
int b2:2;
union {
struct {
int o1;
int o2;
} o;
struct {
char flags;
char dev_id;
} dev;
int netid;
} u[10];
};
static int (*bpf_probe_read)(void *dst, int size, const void *unsafe_ptr)
= (void *) 4;
#define _(x) (__builtin_preserve_access_index(x))
int bpf_prog(struct sk_buff *ctx) {
char dev_id;
bpf_probe_read(&dev_id, sizeof(char), _(&ctx->u[5].dev.dev_id));
return dev_id;
}
$ clang -target bpf -O2 -g -emit-llvm -S -mllvm -print-before-all \
test.c >& log
The generated IR looks like below:
...
define dso_local i32 @bpf_prog(%struct.sk_buff*) #0 !dbg !15 {
%2 = alloca %struct.sk_buff*, align 8
%3 = alloca i8, align 1
store %struct.sk_buff* %0, %struct.sk_buff** %2, align 8, !tbaa !45
call void @llvm.dbg.declare(metadata %struct.sk_buff** %2, metadata !43, metadata !DIExpression()), !dbg !49
call void @llvm.lifetime.start.p0i8(i64 1, i8* %3) #4, !dbg !50
call void @llvm.dbg.declare(metadata i8* %3, metadata !44, metadata !DIExpression()), !dbg !51
%4 = load i32 (i8*, i32, i8*)*, i32 (i8*, i32, i8*)** @bpf_probe_read, align 8, !dbg !52, !tbaa !45
%5 = load %struct.sk_buff*, %struct.sk_buff** %2, align 8, !dbg !53, !tbaa !45
%6 = call [10 x %union.anon]* @llvm.preserve.struct.access.index.p0a10s_union.anons.p0s_struct.sk_buffs(
%struct.sk_buff* %5, i32 2, i32 3), !dbg !53, !llvm.preserve.access.index !19
%7 = call %union.anon* @llvm.preserve.array.access.index.p0s_union.anons.p0a10s_union.anons(
[10 x %union.anon]* %6, i32 1, i32 5), !dbg !53
%8 = call %union.anon* @llvm.preserve.union.access.index.p0s_union.anons.p0s_union.anons(
%union.anon* %7, i32 1), !dbg !53, !llvm.preserve.access.index !26
%9 = bitcast %union.anon* %8 to %struct.anon.0*, !dbg !53
%10 = call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.anon.0s(
%struct.anon.0* %9, i32 1, i32 1), !dbg !53, !llvm.preserve.access.index !34
%11 = call i32 %4(i8* %3, i32 1, i8* %10), !dbg !52
%12 = load i8, i8* %3, align 1, !dbg !54, !tbaa !55
%13 = sext i8 %12 to i32, !dbg !54
call void @llvm.lifetime.end.p0i8(i64 1, i8* %3) #4, !dbg !56
ret i32 %13, !dbg !57
}
!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "sk_buff", file: !3, line: 1, size: 704, elements: !20)
!26 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !19, file: !3, line: 5, size: 64, elements: !27)
!34 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !26, file: !3, line: 10, size: 16, elements: !35)
Note that @llvm.preserve.{struct,union}.access.index calls have metadata llvm.preserve.access.index
attached to instructions to provide struct/union debuginfo type information.
For &ctx->u[5].dev.dev_id,
. The "%6 = ..." represents struct member "u" with index 2 for IR layout and index 3 for DI layout.
. The "%7 = ..." represents array subscript "5".
. The "%8 = ..." represents union member "dev" with index 1 for DI layout.
. The "%10 = ..." represents struct member "dev_id" with index 1 for both IR and DI layout.
Basically, traversing the use-def chain recursively for the 3rd argument of bpf_probe_read() and
examining all preserve_*_access_index calls, the debuginfo struct/union/array access index
can be achieved.
The intrinsics also contain enough information to regenerate codes for IR layout.
For array and structure intrinsics, the proper GEP can be constructed.
For union intrinsics, replacing all uses of "addr" with "base" should be enough.
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D61809
llvm-svn: 365438
2019-07-09 04:21:50 +00:00
|
|
|
}
|
|
|
|
|
|
2017-06-01 18:39:34 +00:00
|
|
|
static bool hasAnyVptr(const QualType Type, const ASTContext &Context) {
|
|
|
|
|
const auto *RD = Type.getTypePtr()->getAsCXXRecordDecl();
|
|
|
|
|
if (!RD)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (RD->isDynamicClass())
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
for (const auto &Base : RD->bases())
|
|
|
|
|
if (hasAnyVptr(Base.getType(), Context))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
for (const FieldDecl *Field : RD->fields())
|
|
|
|
|
if (hasAnyVptr(Field->getType(), Context))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-16 03:54:45 +00:00
|
|
|
LValue CodeGenFunction::EmitLValueForField(LValue base,
|
|
|
|
|
const FieldDecl *field) {
|
2017-05-18 17:07:11 +00:00
|
|
|
LValueBaseInfo BaseInfo = base.getBaseInfo();
|
2017-05-25 12:55:47 +00:00
|
|
|
|
2012-06-27 21:19:48 +00:00
|
|
|
if (field->isBitField()) {
|
|
|
|
|
const CGRecordLayout &RL =
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
CGM.getTypes().getCGRecordLayout(field->getParent());
|
2020-01-21 15:31:33 +00:00
|
|
|
const CGBitFieldInfo &Info = RL.getBitFieldInfo(field);
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
const bool UseVolatile = isAAPCS(CGM.getTarget()) &&
|
|
|
|
|
CGM.getCodeGenOpts().AAPCSBitfieldWidth &&
|
|
|
|
|
Info.VolatileStorageSize != 0 &&
|
|
|
|
|
field->getType()
|
|
|
|
|
.withCVRQualifiers(base.getVRQualifiers())
|
|
|
|
|
.isVolatileQualified();
|
2019-12-03 15:17:01 -08:00
|
|
|
Address Addr = base.getAddress(*this);
|
2012-12-06 11:14:44 +00:00
|
|
|
unsigned Idx = RL.getLLVMFieldNo(field);
|
2019-11-01 22:16:59 -07:00
|
|
|
const RecordDecl *rec = field->getParent();
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
if (!UseVolatile) {
|
|
|
|
|
if (!IsInPreservedAIRegion &&
|
|
|
|
|
(!getDebugInfo() || !rec->hasAttr<BPFPreserveAccessIndexAttr>())) {
|
|
|
|
|
if (Idx != 0)
|
|
|
|
|
// For structs, we GEP to the field that the record layout suggests.
|
|
|
|
|
Addr = Builder.CreateStructGEP(Addr, Idx, field->getName());
|
|
|
|
|
} else {
|
|
|
|
|
llvm::DIType *DbgInfo = getDebugInfo()->getOrCreateRecordType(
|
|
|
|
|
getContext().getRecordType(rec), rec->getLocation());
|
|
|
|
|
Addr = Builder.CreatePreserveStructAccessIndex(
|
|
|
|
|
Addr, Idx, getDebugInfoFIndex(rec, field->getFieldIndex()),
|
|
|
|
|
DbgInfo);
|
|
|
|
|
}
|
[BPF] do compile-once run-everywhere relocation for bitfields
A bpf specific clang intrinsic is introduced:
u32 __builtin_preserve_field_info(member_access, info_kind)
Depending on info_kind, different information will
be returned to the program. A relocation is also
recorded for this builtin so that bpf loader can
patch the instruction on the target host.
This clang intrinsic is used to get certain information
to facilitate struct/union member relocations.
The offset relocation is extended by 4 bytes to
include relocation kind.
Currently supported relocation kinds are
enum {
FIELD_BYTE_OFFSET = 0,
FIELD_BYTE_SIZE,
FIELD_EXISTENCE,
FIELD_SIGNEDNESS,
FIELD_LSHIFT_U64,
FIELD_RSHIFT_U64,
};
for __builtin_preserve_field_info. The old
access offset relocation is covered by
FIELD_BYTE_OFFSET = 0.
An example:
struct s {
int a;
int b1:9;
int b2:4;
};
enum {
FIELD_BYTE_OFFSET = 0,
FIELD_BYTE_SIZE,
FIELD_EXISTENCE,
FIELD_SIGNEDNESS,
FIELD_LSHIFT_U64,
FIELD_RSHIFT_U64,
};
void bpf_probe_read(void *, unsigned, const void *);
int field_read(struct s *arg) {
unsigned long long ull = 0;
unsigned offset = __builtin_preserve_field_info(arg->b2, FIELD_BYTE_OFFSET);
unsigned size = __builtin_preserve_field_info(arg->b2, FIELD_BYTE_SIZE);
#ifdef USE_PROBE_READ
bpf_probe_read(&ull, size, (const void *)arg + offset);
unsigned lshift = __builtin_preserve_field_info(arg->b2, FIELD_LSHIFT_U64);
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
lshift = lshift + (size << 3) - 64;
#endif
#else
switch(size) {
case 1:
ull = *(unsigned char *)((void *)arg + offset); break;
case 2:
ull = *(unsigned short *)((void *)arg + offset); break;
case 4:
ull = *(unsigned int *)((void *)arg + offset); break;
case 8:
ull = *(unsigned long long *)((void *)arg + offset); break;
}
unsigned lshift = __builtin_preserve_field_info(arg->b2, FIELD_LSHIFT_U64);
#endif
ull <<= lshift;
if (__builtin_preserve_field_info(arg->b2, FIELD_SIGNEDNESS))
return (long long)ull >> __builtin_preserve_field_info(arg->b2, FIELD_RSHIFT_U64);
return ull >> __builtin_preserve_field_info(arg->b2, FIELD_RSHIFT_U64);
}
There is a minor overhead for bpf_probe_read() on big endian.
The code and relocation generated for field_read where bpf_probe_read() is
used to access argument data on little endian mode:
r3 = r1
r1 = 0
r1 = 4 <=== relocation (FIELD_BYTE_OFFSET)
r3 += r1
r1 = r10
r1 += -8
r2 = 4 <=== relocation (FIELD_BYTE_SIZE)
call bpf_probe_read
r2 = 51 <=== relocation (FIELD_LSHIFT_U64)
r1 = *(u64 *)(r10 - 8)
r1 <<= r2
r2 = 60 <=== relocation (FIELD_RSHIFT_U64)
r0 = r1
r0 >>= r2
r3 = 1 <=== relocation (FIELD_SIGNEDNESS)
if r3 == 0 goto LBB0_2
r1 s>>= r2
r0 = r1
LBB0_2:
exit
Compare to the above code between relocations FIELD_LSHIFT_U64 and
FIELD_LSHIFT_U64, the code with big endian mode has four more
instructions.
r1 = 41 <=== relocation (FIELD_LSHIFT_U64)
r6 += r1
r6 += -64
r6 <<= 32
r6 >>= 32
r1 = *(u64 *)(r10 - 8)
r1 <<= r6
r2 = 60 <=== relocation (FIELD_RSHIFT_U64)
The code and relocation generated when using direct load.
r2 = 0
r3 = 4
r4 = 4
if r4 s> 3 goto LBB0_3
if r4 == 1 goto LBB0_5
if r4 == 2 goto LBB0_6
goto LBB0_9
LBB0_6: # %sw.bb1
r1 += r3
r2 = *(u16 *)(r1 + 0)
goto LBB0_9
LBB0_3: # %entry
if r4 == 4 goto LBB0_7
if r4 == 8 goto LBB0_8
goto LBB0_9
LBB0_8: # %sw.bb9
r1 += r3
r2 = *(u64 *)(r1 + 0)
goto LBB0_9
LBB0_5: # %sw.bb
r1 += r3
r2 = *(u8 *)(r1 + 0)
goto LBB0_9
LBB0_7: # %sw.bb5
r1 += r3
r2 = *(u32 *)(r1 + 0)
LBB0_9: # %sw.epilog
r1 = 51
r2 <<= r1
r1 = 60
r0 = r2
r0 >>= r1
r3 = 1
if r3 == 0 goto LBB0_11
r2 s>>= r1
r0 = r2
LBB0_11: # %sw.epilog
exit
Considering verifier is able to do limited constant
propogation following branches. The following is the
code actually traversed.
r2 = 0
r3 = 4 <=== relocation
r4 = 4 <=== relocation
if r4 s> 3 goto LBB0_3
LBB0_3: # %entry
if r4 == 4 goto LBB0_7
LBB0_7: # %sw.bb5
r1 += r3
r2 = *(u32 *)(r1 + 0)
LBB0_9: # %sw.epilog
r1 = 51 <=== relocation
r2 <<= r1
r1 = 60 <=== relocation
r0 = r2
r0 >>= r1
r3 = 1
if r3 == 0 goto LBB0_11
r2 s>>= r1
r0 = r2
LBB0_11: # %sw.epilog
exit
For native load case, the load size is calculated to be the
same as the size of load width LLVM otherwise used to load
the value which is then used to extract the bitfield value.
Differential Revision: https://reviews.llvm.org/D67980
llvm-svn: 374099
2019-10-08 18:23:17 +00:00
|
|
|
}
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
const unsigned SS =
|
|
|
|
|
UseVolatile ? Info.VolatileStorageSize : Info.StorageSize;
|
2012-12-06 11:14:44 +00:00
|
|
|
// Get the access type.
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
llvm::Type *FieldIntTy = llvm::Type::getIntNTy(getLLVMContext(), SS);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
if (Addr.getElementType() != FieldIntTy)
|
|
|
|
|
Addr = Builder.CreateElementBitCast(Addr, FieldIntTy);
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
if (UseVolatile) {
|
|
|
|
|
const unsigned VolatileOffset = Info.VolatileStorageOffset.getQuantity();
|
|
|
|
|
if (VolatileOffset)
|
|
|
|
|
Addr = Builder.CreateConstInBoundsGEP(Addr, VolatileOffset);
|
|
|
|
|
}
|
2012-12-06 11:14:44 +00:00
|
|
|
|
2020-01-21 15:31:33 +00:00
|
|
|
QualType fieldType =
|
[ARM] Follow AACPS standard for volatile bit-fields access width
This patch resumes the work of D16586.
According to the AAPCS, volatile bit-fields should
be accessed using containers of the widht of their
declarative type. In such case:
```
struct S1 {
short a : 1;
}
```
should be accessed using load and stores of the width
(sizeof(short)), where now the compiler does only load
the minimum required width (char in this case).
However, as discussed in D16586,
that could overwrite non-volatile bit-fields, which
conflicted with C and C++ object models by creating
data race conditions that are not part of the bit-field,
e.g.
```
struct S2 {
short a;
int b : 16;
}
```
Accessing `S2.b` would also access `S2.a`.
The AAPCS Release 2020Q2
(https://documentation-service.arm.com/static/5efb7fbedbdee951c1ccf186?token=)
section 8.1 Data Types, page 36, "Volatile bit-fields -
preserving number and width of container accesses" has been
updated to avoid conflict with the C++ Memory Model.
Now it reads in the note:
```
This ABI does not place any restrictions on the access widths of bit-fields where the container
overlaps with a non-bit-field member or where the container overlaps with any zero length bit-field
placed between two other bit-fields. This is because the C/C++ memory model defines these as being
separate memory locations, which can be accessed by two threads simultaneously. For this reason,
compilers must be permitted to use a narrower memory access width (including splitting the access into
multiple instructions) to avoid writing to a different memory location. For example, in
struct S { int a:24; char b; }; a write to a must not also write to the location occupied by b, this requires at least two
memory accesses in all current Arm architectures. In the same way, in struct S { int a:24; int:0; int b:8; };,
writes to a or b must not overwrite each other.
```
I've updated the patch D16586 to follow such behavior by verifying that we
only change volatile bit-field access when:
- it won't overlap with any other non-bit-field member
- we only access memory inside the bounds of the record
- avoid overlapping zero-length bit-fields.
Regarding the number of memory accesses, that should be preserved, that will
be implemented by D67399.
Reviewed By: ostannard
Differential Revision: https://reviews.llvm.org/D72932
2020-09-30 14:44:27 +01:00
|
|
|
field->getType().withCVRQualifiers(base.getVRQualifiers());
|
2017-10-17 11:20:19 +00:00
|
|
|
// TODO: Support TBAA for bit fields.
|
2017-10-31 11:05:34 +00:00
|
|
|
LValueBaseInfo FieldBaseInfo(BaseInfo.getAlignmentSource());
|
2020-01-21 15:31:33 +00:00
|
|
|
return LValue::MakeBitfield(Addr, Info, fieldType, FieldBaseInfo,
|
2017-10-17 10:17:43 +00:00
|
|
|
TBAAAccessInfo());
|
2012-06-27 21:19:48 +00:00
|
|
|
}
|
2011-02-26 08:07:02 +00:00
|
|
|
|
2017-10-17 11:20:19 +00:00
|
|
|
// Fields of may-alias structures are may-alias themselves.
|
|
|
|
|
// FIXME: this should get propagated down through anonymous structs
|
|
|
|
|
// and unions.
|
|
|
|
|
QualType FieldType = field->getType();
|
|
|
|
|
const RecordDecl *rec = field->getParent();
|
|
|
|
|
AlignmentSource BaseAlignSource = BaseInfo.getAlignmentSource();
|
2017-10-31 11:05:34 +00:00
|
|
|
LValueBaseInfo FieldBaseInfo(getFieldAlignmentSource(BaseAlignSource));
|
2017-10-17 11:20:19 +00:00
|
|
|
TBAAAccessInfo FieldTBAAInfo;
|
2017-10-31 11:05:34 +00:00
|
|
|
if (base.getTBAAInfo().isMayAlias() ||
|
|
|
|
|
rec->hasAttr<MayAliasAttr>() || FieldType->isVectorType()) {
|
|
|
|
|
FieldTBAAInfo = TBAAAccessInfo::getMayAliasInfo();
|
2017-12-03 03:10:13 +00:00
|
|
|
} else if (rec->isUnion()) {
|
|
|
|
|
// TODO: Support TBAA for unions.
|
|
|
|
|
FieldTBAAInfo = TBAAAccessInfo::getMayAliasInfo();
|
2017-10-17 11:20:19 +00:00
|
|
|
} else {
|
|
|
|
|
// If no base type been assigned for the base access, then try to generate
|
|
|
|
|
// one for this base lvalue.
|
|
|
|
|
FieldTBAAInfo = base.getTBAAInfo();
|
|
|
|
|
if (!FieldTBAAInfo.BaseType) {
|
|
|
|
|
FieldTBAAInfo.BaseType = CGM.getTBAABaseTypeInfo(base.getType());
|
|
|
|
|
assert(!FieldTBAAInfo.Offset &&
|
|
|
|
|
"Nonzero offset for an access with no base type!");
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-03 03:10:13 +00:00
|
|
|
// Adjust offset to be relative to the base type.
|
|
|
|
|
const ASTRecordLayout &Layout =
|
|
|
|
|
getContext().getASTRecordLayout(field->getParent());
|
|
|
|
|
unsigned CharWidth = getContext().getCharWidth();
|
|
|
|
|
if (FieldTBAAInfo.BaseType)
|
|
|
|
|
FieldTBAAInfo.Offset +=
|
|
|
|
|
Layout.getFieldOffset(field->getFieldIndex()) / CharWidth;
|
|
|
|
|
|
2017-12-21 08:14:16 +00:00
|
|
|
// Update the final access type and size.
|
2017-12-03 03:10:13 +00:00
|
|
|
FieldTBAAInfo.AccessType = CGM.getTBAATypeInfo(FieldType);
|
2017-12-21 08:14:16 +00:00
|
|
|
FieldTBAAInfo.Size =
|
|
|
|
|
getContext().getTypeSizeInChars(FieldType).getQuantity();
|
2017-10-17 11:20:19 +00:00
|
|
|
}
|
|
|
|
|
|
2019-12-03 15:17:01 -08:00
|
|
|
Address addr = base.getAddress(*this);
|
2018-07-02 19:21:36 +00:00
|
|
|
if (auto *ClassDef = dyn_cast<CXXRecordDecl>(rec)) {
|
|
|
|
|
if (CGM.getCodeGenOpts().StrictVTablePointers &&
|
|
|
|
|
ClassDef->isDynamicClass()) {
|
|
|
|
|
// Getting to any field of dynamic object requires stripping dynamic
|
|
|
|
|
// information provided by invariant.group. This is because accessing
|
|
|
|
|
// fields may leak the real address of dynamic object, which could result
|
|
|
|
|
// in miscompilation when leaked pointer would be compared.
|
|
|
|
|
auto *stripped = Builder.CreateStripInvariantGroup(addr.getPointer());
|
|
|
|
|
addr = Address(stripped, addr.getAlignment());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-30 11:49:31 +00:00
|
|
|
unsigned RecordCVR = base.getVRQualifiers();
|
2011-02-26 08:07:02 +00:00
|
|
|
if (rec->isUnion()) {
|
2011-07-10 05:34:54 +00:00
|
|
|
// For unions, there is no pointer adjustment.
|
2017-06-01 18:39:34 +00:00
|
|
|
if (CGM.getCodeGenOpts().StrictVTablePointers &&
|
|
|
|
|
hasAnyVptr(FieldType, getContext()))
|
|
|
|
|
// Because unions can easily skip invariant.barriers, we need to add
|
|
|
|
|
// a barrier every time CXXRecord field with vptr is referenced.
|
2018-05-03 11:03:01 +00:00
|
|
|
addr = Address(Builder.CreateLaunderInvariantGroup(addr.getPointer()),
|
2017-06-01 18:39:34 +00:00
|
|
|
addr.getAlignment());
|
[BPF] Preserve debuginfo array/union/struct type/access index
For background of BPF CO-RE project, please refer to
http://vger.kernel.org/bpfconf2019.html
In summary, BPF CO-RE intends to compile bpf programs
adjustable on struct/union layout change so the same
program can run on multiple kernels with adjustment
before loading based on native kernel structures.
In order to do this, we need keep track of GEP(getelementptr)
instruction base and result debuginfo types, so we
can adjust on the host based on kernel BTF info.
Capturing such information as an IR optimization is hard
as various optimization may have tweaked GEP and also
union is replaced by structure it is impossible to track
fieldindex for union member accesses.
Three intrinsic functions, preserve_{array,union,struct}_access_index,
are introducted.
addr = preserve_array_access_index(base, index, dimension)
addr = preserve_union_access_index(base, di_index)
addr = preserve_struct_access_index(base, gep_index, di_index)
here,
base: the base pointer for the array/union/struct access.
index: the last access index for array, the same for IR/DebugInfo layout.
dimension: the array dimension.
gep_index: the access index based on IR layout.
di_index: the access index based on user/debuginfo types.
If using these intrinsics blindly, i.e., transforming all GEPs
to these intrinsics and later on reducing them to GEPs, we have
seen up to 7% more instructions generated. To avoid such an overhead,
a clang builtin is proposed:
base = __builtin_preserve_access_index(base)
such that user wraps to-be-relocated GEPs in this builtin
and preserve_*_access_index intrinsics only apply to
those GEPs. Such a buyin will prevent performance degradation
if people do not use CO-RE, even for programs which use
bpf_probe_read().
For example, for the following example,
$ cat test.c
struct sk_buff {
int i;
int b1:1;
int b2:2;
union {
struct {
int o1;
int o2;
} o;
struct {
char flags;
char dev_id;
} dev;
int netid;
} u[10];
};
static int (*bpf_probe_read)(void *dst, int size, const void *unsafe_ptr)
= (void *) 4;
#define _(x) (__builtin_preserve_access_index(x))
int bpf_prog(struct sk_buff *ctx) {
char dev_id;
bpf_probe_read(&dev_id, sizeof(char), _(&ctx->u[5].dev.dev_id));
return dev_id;
}
$ clang -target bpf -O2 -g -emit-llvm -S -mllvm -print-before-all \
test.c >& log
The generated IR looks like below:
...
define dso_local i32 @bpf_prog(%struct.sk_buff*) #0 !dbg !15 {
%2 = alloca %struct.sk_buff*, align 8
%3 = alloca i8, align 1
store %struct.sk_buff* %0, %struct.sk_buff** %2, align 8, !tbaa !45
call void @llvm.dbg.declare(metadata %struct.sk_buff** %2, metadata !43, metadata !DIExpression()), !dbg !49
call void @llvm.lifetime.start.p0i8(i64 1, i8* %3) #4, !dbg !50
call void @llvm.dbg.declare(metadata i8* %3, metadata !44, metadata !DIExpression()), !dbg !51
%4 = load i32 (i8*, i32, i8*)*, i32 (i8*, i32, i8*)** @bpf_probe_read, align 8, !dbg !52, !tbaa !45
%5 = load %struct.sk_buff*, %struct.sk_buff** %2, align 8, !dbg !53, !tbaa !45
%6 = call [10 x %union.anon]* @llvm.preserve.struct.access.index.p0a10s_union.anons.p0s_struct.sk_buffs(
%struct.sk_buff* %5, i32 2, i32 3), !dbg !53, !llvm.preserve.access.index !19
%7 = call %union.anon* @llvm.preserve.array.access.index.p0s_union.anons.p0a10s_union.anons(
[10 x %union.anon]* %6, i32 1, i32 5), !dbg !53
%8 = call %union.anon* @llvm.preserve.union.access.index.p0s_union.anons.p0s_union.anons(
%union.anon* %7, i32 1), !dbg !53, !llvm.preserve.access.index !26
%9 = bitcast %union.anon* %8 to %struct.anon.0*, !dbg !53
%10 = call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.anon.0s(
%struct.anon.0* %9, i32 1, i32 1), !dbg !53, !llvm.preserve.access.index !34
%11 = call i32 %4(i8* %3, i32 1, i8* %10), !dbg !52
%12 = load i8, i8* %3, align 1, !dbg !54, !tbaa !55
%13 = sext i8 %12 to i32, !dbg !54
call void @llvm.lifetime.end.p0i8(i64 1, i8* %3) #4, !dbg !56
ret i32 %13, !dbg !57
}
!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "sk_buff", file: !3, line: 1, size: 704, elements: !20)
!26 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !19, file: !3, line: 5, size: 64, elements: !27)
!34 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !26, file: !3, line: 10, size: 16, elements: !35)
Note that @llvm.preserve.{struct,union}.access.index calls have metadata llvm.preserve.access.index
attached to instructions to provide struct/union debuginfo type information.
For &ctx->u[5].dev.dev_id,
. The "%6 = ..." represents struct member "u" with index 2 for IR layout and index 3 for DI layout.
. The "%7 = ..." represents array subscript "5".
. The "%8 = ..." represents union member "dev" with index 1 for DI layout.
. The "%10 = ..." represents struct member "dev_id" with index 1 for both IR and DI layout.
Basically, traversing the use-def chain recursively for the 3rd argument of bpf_probe_read() and
examining all preserve_*_access_index calls, the debuginfo struct/union/array access index
can be achieved.
The intrinsics also contain enough information to regenerate codes for IR layout.
For array and structure intrinsics, the proper GEP can be constructed.
For union intrinsics, replacing all uses of "addr" with "base" should be enough.
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D61809
llvm-svn: 365438
2019-07-09 04:21:50 +00:00
|
|
|
|
2019-11-01 22:16:59 -07:00
|
|
|
if (IsInPreservedAIRegion ||
|
|
|
|
|
(getDebugInfo() && rec->hasAttr<BPFPreserveAccessIndexAttr>())) {
|
[BPF] Preserve debuginfo array/union/struct type/access index
For background of BPF CO-RE project, please refer to
http://vger.kernel.org/bpfconf2019.html
In summary, BPF CO-RE intends to compile bpf programs
adjustable on struct/union layout change so the same
program can run on multiple kernels with adjustment
before loading based on native kernel structures.
In order to do this, we need keep track of GEP(getelementptr)
instruction base and result debuginfo types, so we
can adjust on the host based on kernel BTF info.
Capturing such information as an IR optimization is hard
as various optimization may have tweaked GEP and also
union is replaced by structure it is impossible to track
fieldindex for union member accesses.
Three intrinsic functions, preserve_{array,union,struct}_access_index,
are introducted.
addr = preserve_array_access_index(base, index, dimension)
addr = preserve_union_access_index(base, di_index)
addr = preserve_struct_access_index(base, gep_index, di_index)
here,
base: the base pointer for the array/union/struct access.
index: the last access index for array, the same for IR/DebugInfo layout.
dimension: the array dimension.
gep_index: the access index based on IR layout.
di_index: the access index based on user/debuginfo types.
If using these intrinsics blindly, i.e., transforming all GEPs
to these intrinsics and later on reducing them to GEPs, we have
seen up to 7% more instructions generated. To avoid such an overhead,
a clang builtin is proposed:
base = __builtin_preserve_access_index(base)
such that user wraps to-be-relocated GEPs in this builtin
and preserve_*_access_index intrinsics only apply to
those GEPs. Such a buyin will prevent performance degradation
if people do not use CO-RE, even for programs which use
bpf_probe_read().
For example, for the following example,
$ cat test.c
struct sk_buff {
int i;
int b1:1;
int b2:2;
union {
struct {
int o1;
int o2;
} o;
struct {
char flags;
char dev_id;
} dev;
int netid;
} u[10];
};
static int (*bpf_probe_read)(void *dst, int size, const void *unsafe_ptr)
= (void *) 4;
#define _(x) (__builtin_preserve_access_index(x))
int bpf_prog(struct sk_buff *ctx) {
char dev_id;
bpf_probe_read(&dev_id, sizeof(char), _(&ctx->u[5].dev.dev_id));
return dev_id;
}
$ clang -target bpf -O2 -g -emit-llvm -S -mllvm -print-before-all \
test.c >& log
The generated IR looks like below:
...
define dso_local i32 @bpf_prog(%struct.sk_buff*) #0 !dbg !15 {
%2 = alloca %struct.sk_buff*, align 8
%3 = alloca i8, align 1
store %struct.sk_buff* %0, %struct.sk_buff** %2, align 8, !tbaa !45
call void @llvm.dbg.declare(metadata %struct.sk_buff** %2, metadata !43, metadata !DIExpression()), !dbg !49
call void @llvm.lifetime.start.p0i8(i64 1, i8* %3) #4, !dbg !50
call void @llvm.dbg.declare(metadata i8* %3, metadata !44, metadata !DIExpression()), !dbg !51
%4 = load i32 (i8*, i32, i8*)*, i32 (i8*, i32, i8*)** @bpf_probe_read, align 8, !dbg !52, !tbaa !45
%5 = load %struct.sk_buff*, %struct.sk_buff** %2, align 8, !dbg !53, !tbaa !45
%6 = call [10 x %union.anon]* @llvm.preserve.struct.access.index.p0a10s_union.anons.p0s_struct.sk_buffs(
%struct.sk_buff* %5, i32 2, i32 3), !dbg !53, !llvm.preserve.access.index !19
%7 = call %union.anon* @llvm.preserve.array.access.index.p0s_union.anons.p0a10s_union.anons(
[10 x %union.anon]* %6, i32 1, i32 5), !dbg !53
%8 = call %union.anon* @llvm.preserve.union.access.index.p0s_union.anons.p0s_union.anons(
%union.anon* %7, i32 1), !dbg !53, !llvm.preserve.access.index !26
%9 = bitcast %union.anon* %8 to %struct.anon.0*, !dbg !53
%10 = call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.anon.0s(
%struct.anon.0* %9, i32 1, i32 1), !dbg !53, !llvm.preserve.access.index !34
%11 = call i32 %4(i8* %3, i32 1, i8* %10), !dbg !52
%12 = load i8, i8* %3, align 1, !dbg !54, !tbaa !55
%13 = sext i8 %12 to i32, !dbg !54
call void @llvm.lifetime.end.p0i8(i64 1, i8* %3) #4, !dbg !56
ret i32 %13, !dbg !57
}
!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "sk_buff", file: !3, line: 1, size: 704, elements: !20)
!26 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !19, file: !3, line: 5, size: 64, elements: !27)
!34 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !26, file: !3, line: 10, size: 16, elements: !35)
Note that @llvm.preserve.{struct,union}.access.index calls have metadata llvm.preserve.access.index
attached to instructions to provide struct/union debuginfo type information.
For &ctx->u[5].dev.dev_id,
. The "%6 = ..." represents struct member "u" with index 2 for IR layout and index 3 for DI layout.
. The "%7 = ..." represents array subscript "5".
. The "%8 = ..." represents union member "dev" with index 1 for DI layout.
. The "%10 = ..." represents struct member "dev_id" with index 1 for both IR and DI layout.
Basically, traversing the use-def chain recursively for the 3rd argument of bpf_probe_read() and
examining all preserve_*_access_index calls, the debuginfo struct/union/array access index
can be achieved.
The intrinsics also contain enough information to regenerate codes for IR layout.
For array and structure intrinsics, the proper GEP can be constructed.
For union intrinsics, replacing all uses of "addr" with "base" should be enough.
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D61809
llvm-svn: 365438
2019-07-09 04:21:50 +00:00
|
|
|
// Remember the original union field index
|
2020-02-02 14:54:16 -08:00
|
|
|
llvm::DIType *DbgInfo = getDebugInfo()->getOrCreateStandaloneType(base.getType(),
|
|
|
|
|
rec->getLocation());
|
[BPF] Preserve debuginfo array/union/struct type/access index
For background of BPF CO-RE project, please refer to
http://vger.kernel.org/bpfconf2019.html
In summary, BPF CO-RE intends to compile bpf programs
adjustable on struct/union layout change so the same
program can run on multiple kernels with adjustment
before loading based on native kernel structures.
In order to do this, we need keep track of GEP(getelementptr)
instruction base and result debuginfo types, so we
can adjust on the host based on kernel BTF info.
Capturing such information as an IR optimization is hard
as various optimization may have tweaked GEP and also
union is replaced by structure it is impossible to track
fieldindex for union member accesses.
Three intrinsic functions, preserve_{array,union,struct}_access_index,
are introducted.
addr = preserve_array_access_index(base, index, dimension)
addr = preserve_union_access_index(base, di_index)
addr = preserve_struct_access_index(base, gep_index, di_index)
here,
base: the base pointer for the array/union/struct access.
index: the last access index for array, the same for IR/DebugInfo layout.
dimension: the array dimension.
gep_index: the access index based on IR layout.
di_index: the access index based on user/debuginfo types.
If using these intrinsics blindly, i.e., transforming all GEPs
to these intrinsics and later on reducing them to GEPs, we have
seen up to 7% more instructions generated. To avoid such an overhead,
a clang builtin is proposed:
base = __builtin_preserve_access_index(base)
such that user wraps to-be-relocated GEPs in this builtin
and preserve_*_access_index intrinsics only apply to
those GEPs. Such a buyin will prevent performance degradation
if people do not use CO-RE, even for programs which use
bpf_probe_read().
For example, for the following example,
$ cat test.c
struct sk_buff {
int i;
int b1:1;
int b2:2;
union {
struct {
int o1;
int o2;
} o;
struct {
char flags;
char dev_id;
} dev;
int netid;
} u[10];
};
static int (*bpf_probe_read)(void *dst, int size, const void *unsafe_ptr)
= (void *) 4;
#define _(x) (__builtin_preserve_access_index(x))
int bpf_prog(struct sk_buff *ctx) {
char dev_id;
bpf_probe_read(&dev_id, sizeof(char), _(&ctx->u[5].dev.dev_id));
return dev_id;
}
$ clang -target bpf -O2 -g -emit-llvm -S -mllvm -print-before-all \
test.c >& log
The generated IR looks like below:
...
define dso_local i32 @bpf_prog(%struct.sk_buff*) #0 !dbg !15 {
%2 = alloca %struct.sk_buff*, align 8
%3 = alloca i8, align 1
store %struct.sk_buff* %0, %struct.sk_buff** %2, align 8, !tbaa !45
call void @llvm.dbg.declare(metadata %struct.sk_buff** %2, metadata !43, metadata !DIExpression()), !dbg !49
call void @llvm.lifetime.start.p0i8(i64 1, i8* %3) #4, !dbg !50
call void @llvm.dbg.declare(metadata i8* %3, metadata !44, metadata !DIExpression()), !dbg !51
%4 = load i32 (i8*, i32, i8*)*, i32 (i8*, i32, i8*)** @bpf_probe_read, align 8, !dbg !52, !tbaa !45
%5 = load %struct.sk_buff*, %struct.sk_buff** %2, align 8, !dbg !53, !tbaa !45
%6 = call [10 x %union.anon]* @llvm.preserve.struct.access.index.p0a10s_union.anons.p0s_struct.sk_buffs(
%struct.sk_buff* %5, i32 2, i32 3), !dbg !53, !llvm.preserve.access.index !19
%7 = call %union.anon* @llvm.preserve.array.access.index.p0s_union.anons.p0a10s_union.anons(
[10 x %union.anon]* %6, i32 1, i32 5), !dbg !53
%8 = call %union.anon* @llvm.preserve.union.access.index.p0s_union.anons.p0s_union.anons(
%union.anon* %7, i32 1), !dbg !53, !llvm.preserve.access.index !26
%9 = bitcast %union.anon* %8 to %struct.anon.0*, !dbg !53
%10 = call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.anon.0s(
%struct.anon.0* %9, i32 1, i32 1), !dbg !53, !llvm.preserve.access.index !34
%11 = call i32 %4(i8* %3, i32 1, i8* %10), !dbg !52
%12 = load i8, i8* %3, align 1, !dbg !54, !tbaa !55
%13 = sext i8 %12 to i32, !dbg !54
call void @llvm.lifetime.end.p0i8(i64 1, i8* %3) #4, !dbg !56
ret i32 %13, !dbg !57
}
!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "sk_buff", file: !3, line: 1, size: 704, elements: !20)
!26 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !19, file: !3, line: 5, size: 64, elements: !27)
!34 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !26, file: !3, line: 10, size: 16, elements: !35)
Note that @llvm.preserve.{struct,union}.access.index calls have metadata llvm.preserve.access.index
attached to instructions to provide struct/union debuginfo type information.
For &ctx->u[5].dev.dev_id,
. The "%6 = ..." represents struct member "u" with index 2 for IR layout and index 3 for DI layout.
. The "%7 = ..." represents array subscript "5".
. The "%8 = ..." represents union member "dev" with index 1 for DI layout.
. The "%10 = ..." represents struct member "dev_id" with index 1 for both IR and DI layout.
Basically, traversing the use-def chain recursively for the 3rd argument of bpf_probe_read() and
examining all preserve_*_access_index calls, the debuginfo struct/union/array access index
can be achieved.
The intrinsics also contain enough information to regenerate codes for IR layout.
For array and structure intrinsics, the proper GEP can be constructed.
For union intrinsics, replacing all uses of "addr" with "base" should be enough.
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D61809
llvm-svn: 365438
2019-07-09 04:21:50 +00:00
|
|
|
addr = Address(
|
|
|
|
|
Builder.CreatePreserveUnionAccessIndex(
|
2019-07-16 17:24:33 +00:00
|
|
|
addr.getPointer(), getDebugInfoFIndex(rec, field->getFieldIndex()), DbgInfo),
|
[BPF] Preserve debuginfo array/union/struct type/access index
For background of BPF CO-RE project, please refer to
http://vger.kernel.org/bpfconf2019.html
In summary, BPF CO-RE intends to compile bpf programs
adjustable on struct/union layout change so the same
program can run on multiple kernels with adjustment
before loading based on native kernel structures.
In order to do this, we need keep track of GEP(getelementptr)
instruction base and result debuginfo types, so we
can adjust on the host based on kernel BTF info.
Capturing such information as an IR optimization is hard
as various optimization may have tweaked GEP and also
union is replaced by structure it is impossible to track
fieldindex for union member accesses.
Three intrinsic functions, preserve_{array,union,struct}_access_index,
are introducted.
addr = preserve_array_access_index(base, index, dimension)
addr = preserve_union_access_index(base, di_index)
addr = preserve_struct_access_index(base, gep_index, di_index)
here,
base: the base pointer for the array/union/struct access.
index: the last access index for array, the same for IR/DebugInfo layout.
dimension: the array dimension.
gep_index: the access index based on IR layout.
di_index: the access index based on user/debuginfo types.
If using these intrinsics blindly, i.e., transforming all GEPs
to these intrinsics and later on reducing them to GEPs, we have
seen up to 7% more instructions generated. To avoid such an overhead,
a clang builtin is proposed:
base = __builtin_preserve_access_index(base)
such that user wraps to-be-relocated GEPs in this builtin
and preserve_*_access_index intrinsics only apply to
those GEPs. Such a buyin will prevent performance degradation
if people do not use CO-RE, even for programs which use
bpf_probe_read().
For example, for the following example,
$ cat test.c
struct sk_buff {
int i;
int b1:1;
int b2:2;
union {
struct {
int o1;
int o2;
} o;
struct {
char flags;
char dev_id;
} dev;
int netid;
} u[10];
};
static int (*bpf_probe_read)(void *dst, int size, const void *unsafe_ptr)
= (void *) 4;
#define _(x) (__builtin_preserve_access_index(x))
int bpf_prog(struct sk_buff *ctx) {
char dev_id;
bpf_probe_read(&dev_id, sizeof(char), _(&ctx->u[5].dev.dev_id));
return dev_id;
}
$ clang -target bpf -O2 -g -emit-llvm -S -mllvm -print-before-all \
test.c >& log
The generated IR looks like below:
...
define dso_local i32 @bpf_prog(%struct.sk_buff*) #0 !dbg !15 {
%2 = alloca %struct.sk_buff*, align 8
%3 = alloca i8, align 1
store %struct.sk_buff* %0, %struct.sk_buff** %2, align 8, !tbaa !45
call void @llvm.dbg.declare(metadata %struct.sk_buff** %2, metadata !43, metadata !DIExpression()), !dbg !49
call void @llvm.lifetime.start.p0i8(i64 1, i8* %3) #4, !dbg !50
call void @llvm.dbg.declare(metadata i8* %3, metadata !44, metadata !DIExpression()), !dbg !51
%4 = load i32 (i8*, i32, i8*)*, i32 (i8*, i32, i8*)** @bpf_probe_read, align 8, !dbg !52, !tbaa !45
%5 = load %struct.sk_buff*, %struct.sk_buff** %2, align 8, !dbg !53, !tbaa !45
%6 = call [10 x %union.anon]* @llvm.preserve.struct.access.index.p0a10s_union.anons.p0s_struct.sk_buffs(
%struct.sk_buff* %5, i32 2, i32 3), !dbg !53, !llvm.preserve.access.index !19
%7 = call %union.anon* @llvm.preserve.array.access.index.p0s_union.anons.p0a10s_union.anons(
[10 x %union.anon]* %6, i32 1, i32 5), !dbg !53
%8 = call %union.anon* @llvm.preserve.union.access.index.p0s_union.anons.p0s_union.anons(
%union.anon* %7, i32 1), !dbg !53, !llvm.preserve.access.index !26
%9 = bitcast %union.anon* %8 to %struct.anon.0*, !dbg !53
%10 = call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.anon.0s(
%struct.anon.0* %9, i32 1, i32 1), !dbg !53, !llvm.preserve.access.index !34
%11 = call i32 %4(i8* %3, i32 1, i8* %10), !dbg !52
%12 = load i8, i8* %3, align 1, !dbg !54, !tbaa !55
%13 = sext i8 %12 to i32, !dbg !54
call void @llvm.lifetime.end.p0i8(i64 1, i8* %3) #4, !dbg !56
ret i32 %13, !dbg !57
}
!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "sk_buff", file: !3, line: 1, size: 704, elements: !20)
!26 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !19, file: !3, line: 5, size: 64, elements: !27)
!34 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !26, file: !3, line: 10, size: 16, elements: !35)
Note that @llvm.preserve.{struct,union}.access.index calls have metadata llvm.preserve.access.index
attached to instructions to provide struct/union debuginfo type information.
For &ctx->u[5].dev.dev_id,
. The "%6 = ..." represents struct member "u" with index 2 for IR layout and index 3 for DI layout.
. The "%7 = ..." represents array subscript "5".
. The "%8 = ..." represents union member "dev" with index 1 for DI layout.
. The "%10 = ..." represents struct member "dev_id" with index 1 for both IR and DI layout.
Basically, traversing the use-def chain recursively for the 3rd argument of bpf_probe_read() and
examining all preserve_*_access_index calls, the debuginfo struct/union/array access index
can be achieved.
The intrinsics also contain enough information to regenerate codes for IR layout.
For array and structure intrinsics, the proper GEP can be constructed.
For union intrinsics, replacing all uses of "addr" with "base" should be enough.
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D61809
llvm-svn: 365438
2019-07-09 04:21:50 +00:00
|
|
|
addr.getAlignment());
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-27 12:42:45 +00:00
|
|
|
if (FieldType->isReferenceType())
|
|
|
|
|
addr = Builder.CreateElementBitCast(
|
|
|
|
|
addr, CGM.getTypes().ConvertTypeForMem(FieldType), field->getName());
|
|
|
|
|
} else {
|
2019-11-01 22:16:59 -07:00
|
|
|
if (!IsInPreservedAIRegion &&
|
|
|
|
|
(!getDebugInfo() || !rec->hasAttr<BPFPreserveAccessIndexAttr>()))
|
[BPF] Preserve debuginfo array/union/struct type/access index
For background of BPF CO-RE project, please refer to
http://vger.kernel.org/bpfconf2019.html
In summary, BPF CO-RE intends to compile bpf programs
adjustable on struct/union layout change so the same
program can run on multiple kernels with adjustment
before loading based on native kernel structures.
In order to do this, we need keep track of GEP(getelementptr)
instruction base and result debuginfo types, so we
can adjust on the host based on kernel BTF info.
Capturing such information as an IR optimization is hard
as various optimization may have tweaked GEP and also
union is replaced by structure it is impossible to track
fieldindex for union member accesses.
Three intrinsic functions, preserve_{array,union,struct}_access_index,
are introducted.
addr = preserve_array_access_index(base, index, dimension)
addr = preserve_union_access_index(base, di_index)
addr = preserve_struct_access_index(base, gep_index, di_index)
here,
base: the base pointer for the array/union/struct access.
index: the last access index for array, the same for IR/DebugInfo layout.
dimension: the array dimension.
gep_index: the access index based on IR layout.
di_index: the access index based on user/debuginfo types.
If using these intrinsics blindly, i.e., transforming all GEPs
to these intrinsics and later on reducing them to GEPs, we have
seen up to 7% more instructions generated. To avoid such an overhead,
a clang builtin is proposed:
base = __builtin_preserve_access_index(base)
such that user wraps to-be-relocated GEPs in this builtin
and preserve_*_access_index intrinsics only apply to
those GEPs. Such a buyin will prevent performance degradation
if people do not use CO-RE, even for programs which use
bpf_probe_read().
For example, for the following example,
$ cat test.c
struct sk_buff {
int i;
int b1:1;
int b2:2;
union {
struct {
int o1;
int o2;
} o;
struct {
char flags;
char dev_id;
} dev;
int netid;
} u[10];
};
static int (*bpf_probe_read)(void *dst, int size, const void *unsafe_ptr)
= (void *) 4;
#define _(x) (__builtin_preserve_access_index(x))
int bpf_prog(struct sk_buff *ctx) {
char dev_id;
bpf_probe_read(&dev_id, sizeof(char), _(&ctx->u[5].dev.dev_id));
return dev_id;
}
$ clang -target bpf -O2 -g -emit-llvm -S -mllvm -print-before-all \
test.c >& log
The generated IR looks like below:
...
define dso_local i32 @bpf_prog(%struct.sk_buff*) #0 !dbg !15 {
%2 = alloca %struct.sk_buff*, align 8
%3 = alloca i8, align 1
store %struct.sk_buff* %0, %struct.sk_buff** %2, align 8, !tbaa !45
call void @llvm.dbg.declare(metadata %struct.sk_buff** %2, metadata !43, metadata !DIExpression()), !dbg !49
call void @llvm.lifetime.start.p0i8(i64 1, i8* %3) #4, !dbg !50
call void @llvm.dbg.declare(metadata i8* %3, metadata !44, metadata !DIExpression()), !dbg !51
%4 = load i32 (i8*, i32, i8*)*, i32 (i8*, i32, i8*)** @bpf_probe_read, align 8, !dbg !52, !tbaa !45
%5 = load %struct.sk_buff*, %struct.sk_buff** %2, align 8, !dbg !53, !tbaa !45
%6 = call [10 x %union.anon]* @llvm.preserve.struct.access.index.p0a10s_union.anons.p0s_struct.sk_buffs(
%struct.sk_buff* %5, i32 2, i32 3), !dbg !53, !llvm.preserve.access.index !19
%7 = call %union.anon* @llvm.preserve.array.access.index.p0s_union.anons.p0a10s_union.anons(
[10 x %union.anon]* %6, i32 1, i32 5), !dbg !53
%8 = call %union.anon* @llvm.preserve.union.access.index.p0s_union.anons.p0s_union.anons(
%union.anon* %7, i32 1), !dbg !53, !llvm.preserve.access.index !26
%9 = bitcast %union.anon* %8 to %struct.anon.0*, !dbg !53
%10 = call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.anon.0s(
%struct.anon.0* %9, i32 1, i32 1), !dbg !53, !llvm.preserve.access.index !34
%11 = call i32 %4(i8* %3, i32 1, i8* %10), !dbg !52
%12 = load i8, i8* %3, align 1, !dbg !54, !tbaa !55
%13 = sext i8 %12 to i32, !dbg !54
call void @llvm.lifetime.end.p0i8(i64 1, i8* %3) #4, !dbg !56
ret i32 %13, !dbg !57
}
!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "sk_buff", file: !3, line: 1, size: 704, elements: !20)
!26 = distinct !DICompositeType(tag: DW_TAG_union_type, scope: !19, file: !3, line: 5, size: 64, elements: !27)
!34 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !26, file: !3, line: 10, size: 16, elements: !35)
Note that @llvm.preserve.{struct,union}.access.index calls have metadata llvm.preserve.access.index
attached to instructions to provide struct/union debuginfo type information.
For &ctx->u[5].dev.dev_id,
. The "%6 = ..." represents struct member "u" with index 2 for IR layout and index 3 for DI layout.
. The "%7 = ..." represents array subscript "5".
. The "%8 = ..." represents union member "dev" with index 1 for DI layout.
. The "%10 = ..." represents struct member "dev_id" with index 1 for both IR and DI layout.
Basically, traversing the use-def chain recursively for the 3rd argument of bpf_probe_read() and
examining all preserve_*_access_index calls, the debuginfo struct/union/array access index
can be achieved.
The intrinsics also contain enough information to regenerate codes for IR layout.
For array and structure intrinsics, the proper GEP can be constructed.
For union intrinsics, replacing all uses of "addr" with "base" should be enough.
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D61809
llvm-svn: 365438
2019-07-09 04:21:50 +00:00
|
|
|
// For structs, we GEP to the field that the record layout suggests.
|
|
|
|
|
addr = emitAddrOfFieldStorage(*this, addr, field);
|
|
|
|
|
else
|
|
|
|
|
// Remember the original struct field index
|
2020-02-02 14:54:16 -08:00
|
|
|
addr = emitPreserveStructAccess(*this, base, addr, field);
|
2019-08-27 12:42:45 +00:00
|
|
|
}
|
2011-02-26 08:07:02 +00:00
|
|
|
|
2019-08-27 12:42:45 +00:00
|
|
|
// If this is a reference field, load the reference right now.
|
|
|
|
|
if (FieldType->isReferenceType()) {
|
|
|
|
|
LValue RefLVal =
|
|
|
|
|
MakeAddrLValue(addr, FieldType, FieldBaseInfo, FieldTBAAInfo);
|
|
|
|
|
if (RecordCVR & Qualifiers::Volatile)
|
|
|
|
|
RefLVal.getQuals().addVolatile();
|
|
|
|
|
addr = EmitLoadOfReference(RefLVal, &FieldBaseInfo, &FieldTBAAInfo);
|
|
|
|
|
|
|
|
|
|
// Qualifiers on the struct don't apply to the referencee.
|
|
|
|
|
RecordCVR = 0;
|
|
|
|
|
FieldType = FieldType->getPointeeType();
|
2007-10-26 19:42:18 +00:00
|
|
|
}
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2011-07-10 05:34:54 +00:00
|
|
|
// Make sure that the address is pointing to the right type. This is critical
|
|
|
|
|
// for both unions and structs. A union needs a bitcast, a struct element
|
|
|
|
|
// will need a bitcast if the LLVM type laid out doesn't match the desired
|
|
|
|
|
// type.
|
2017-10-17 11:20:19 +00:00
|
|
|
addr = Builder.CreateElementBitCast(
|
|
|
|
|
addr, CGM.getTypes().ConvertTypeForMem(FieldType), field->getName());
|
2009-09-24 19:53:00 +00:00
|
|
|
|
2011-09-09 22:41:49 +00:00
|
|
|
if (field->hasAttr<AnnotateAttr>())
|
|
|
|
|
addr = EmitFieldAnnotations(field, addr);
|
|
|
|
|
|
2017-10-17 11:20:19 +00:00
|
|
|
LValue LV = MakeAddrLValue(addr, FieldType, FieldBaseInfo, FieldTBAAInfo);
|
2017-10-30 11:49:31 +00:00
|
|
|
LV.getQuals().addCVRQualifiers(RecordCVR);
|
2017-10-06 08:17:48 +00:00
|
|
|
|
2009-09-21 18:54:29 +00:00
|
|
|
// __weak attribute on a field is ignored.
|
2010-08-21 03:44:13 +00:00
|
|
|
if (LV.getQuals().getObjCGCAttr() == Qualifiers::Weak)
|
|
|
|
|
LV.getQuals().removeObjCGCAttr();
|
2011-02-26 08:07:02 +00:00
|
|
|
|
2010-08-21 03:44:13 +00:00
|
|
|
return LV;
|
2007-10-23 20:28:39 +00:00
|
|
|
}
|
|
|
|
|
|
2013-07-26 05:59:26 +00:00
|
|
|
LValue
|
|
|
|
|
CodeGenFunction::EmitLValueForFieldInitialization(LValue Base,
|
2012-04-16 03:54:45 +00:00
|
|
|
const FieldDecl *Field) {
|
2010-01-29 05:24:29 +00:00
|
|
|
QualType FieldType = Field->getType();
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2010-01-29 05:24:29 +00:00
|
|
|
if (!FieldType->isReferenceType())
|
2012-04-16 03:54:45 +00:00
|
|
|
return EmitLValueForField(Base, Field);
|
2010-01-29 05:24:29 +00:00
|
|
|
|
2019-12-03 15:17:01 -08:00
|
|
|
Address V = emitAddrOfFieldStorage(*this, Base.getAddress(*this), Field);
|
2010-01-29 05:24:29 +00: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 08:05:57 +00:00
|
|
|
// Make sure that the address is pointing to the right type.
|
2011-07-18 04:24:23 +00:00
|
|
|
llvm::Type *llvmType = ConvertTypeForMem(FieldType);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
V = Builder.CreateElementBitCast(V, llvmType, Field->getName());
|
2012-04-16 03:54:45 +00:00
|
|
|
|
2017-10-31 11:05:34 +00:00
|
|
|
// TODO: Generate TBAA information that describes this access as a structure
|
|
|
|
|
// member access and not just an access to an object of the field's type. This
|
|
|
|
|
// should be similar to what we do in EmitLValueForField().
|
2017-05-18 17:07:11 +00:00
|
|
|
LValueBaseInfo BaseInfo = Base.getBaseInfo();
|
2017-10-31 11:05:34 +00:00
|
|
|
AlignmentSource FieldAlignSource = BaseInfo.getAlignmentSource();
|
|
|
|
|
LValueBaseInfo FieldBaseInfo(getFieldAlignmentSource(FieldAlignSource));
|
2017-10-12 11:29:46 +00:00
|
|
|
return MakeAddrLValue(V, FieldType, FieldBaseInfo,
|
2017-10-31 11:05:34 +00:00
|
|
|
CGM.getTBAAInfoForSubobject(Base, FieldType));
|
2010-01-29 05:24:29 +00:00
|
|
|
}
|
|
|
|
|
|
2010-09-06 00:11:41 +00:00
|
|
|
LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){
|
2011-11-22 22:48:32 +00:00
|
|
|
if (E->isFileScope()) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
ConstantAddress GlobalPtr = CGM.GetAddrOfConstantCompoundLiteral(E);
|
2017-10-10 09:39:32 +00:00
|
|
|
return MakeAddrLValue(GlobalPtr, E->getType(), AlignmentSource::Decl);
|
2011-11-22 22:48:32 +00:00
|
|
|
}
|
2012-06-07 18:15:55 +00:00
|
|
|
if (E->getType()->isVariablyModifiedType())
|
|
|
|
|
// make sure to emit the VLA size.
|
|
|
|
|
EmitVariablyModifiedType(E->getType());
|
2013-07-26 05:59:26 +00: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 08:05:57 +00:00
|
|
|
Address DeclPtr = CreateMemTemp(E->getType(), ".compoundliteral");
|
2010-09-06 00:11:41 +00:00
|
|
|
const Expr *InitExpr = E->getInitializer();
|
2017-10-10 09:39:32 +00:00
|
|
|
LValue Result = MakeAddrLValue(DeclPtr, E->getType(), AlignmentSource::Decl);
|
2008-05-13 23:18:27 +00:00
|
|
|
|
2012-03-29 17:37:10 +00:00
|
|
|
EmitAnyExprToMem(InitExpr, DeclPtr, E->getType().getQualifiers(),
|
|
|
|
|
/*Init*/ true);
|
2008-05-13 23:18:27 +00:00
|
|
|
|
2020-03-10 14:06:25 -07:00
|
|
|
// Block-scope compound literals are destroyed at the end of the enclosing
|
|
|
|
|
// scope in C.
|
|
|
|
|
if (!getLangOpts().CPlusPlus)
|
|
|
|
|
if (QualType::DestructionKind DtorKind = E->getType().isDestructedType())
|
|
|
|
|
pushLifetimeExtendedDestroy(getCleanupKind(DtorKind), DeclPtr,
|
|
|
|
|
E->getType(), getDestroyer(DtorKind),
|
|
|
|
|
DtorKind & EHCleanup);
|
|
|
|
|
|
2008-05-13 23:18:27 +00:00
|
|
|
return Result;
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-14 21:57:21 +00:00
|
|
|
LValue CodeGenFunction::EmitInitListLValue(const InitListExpr *E) {
|
|
|
|
|
if (!E->isGLValue())
|
|
|
|
|
// Initializing an aggregate temporary in C++11: T{...}.
|
|
|
|
|
return EmitAggExprToLValue(E);
|
|
|
|
|
|
|
|
|
|
// An lvalue initializer list must be initializing a reference.
|
2016-12-06 23:52:28 +00:00
|
|
|
assert(E->isTransparent() && "non-transparent glvalue init list");
|
2012-05-14 21:57:21 +00:00
|
|
|
return EmitLValue(E->getInit(0));
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-20 18:43:47 +00:00
|
|
|
/// Emit the operand of a glvalue conditional operator. This is either a glvalue
|
|
|
|
|
/// or a (possibly-parenthesized) throw-expression. If this is a throw, no
|
|
|
|
|
/// LValue is returned and the current block has been terminated.
|
|
|
|
|
static Optional<LValue> EmitLValueOrThrowExpression(CodeGenFunction &CGF,
|
|
|
|
|
const Expr *Operand) {
|
|
|
|
|
if (auto *ThrowExpr = dyn_cast<CXXThrowExpr>(Operand->IgnoreParens())) {
|
|
|
|
|
CGF.EmitCXXThrowExpr(ThrowExpr, /*KeepInsertionPoint*/false);
|
|
|
|
|
return None;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return CGF.EmitLValue(Operand);
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-17 10:25:35 +00:00
|
|
|
LValue CodeGenFunction::
|
|
|
|
|
EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) {
|
|
|
|
|
if (!expr->isGLValue()) {
|
2011-01-26 19:21:13 +00:00
|
|
|
// ?: here should be an aggregate.
|
2013-03-07 21:37:08 +00:00
|
|
|
assert(hasAggregateEvaluationKind(expr->getType()) &&
|
2011-01-26 19:21:13 +00:00
|
|
|
"Unexpected conditional operator!");
|
2011-02-17 10:25:35 +00:00
|
|
|
return EmitAggExprToLValue(expr);
|
2011-01-26 19:21:13 +00:00
|
|
|
}
|
2009-12-25 05:29:40 +00:00
|
|
|
|
2012-01-25 05:04:17 +00:00
|
|
|
OpaqueValueMapping binding(*this, expr);
|
|
|
|
|
|
2011-02-17 10:25:35 +00:00
|
|
|
const Expr *condExpr = expr->getCond();
|
2011-02-27 23:02:32 +00:00
|
|
|
bool CondExprBool;
|
|
|
|
|
if (ConstantFoldsToSimpleInteger(condExpr, CondExprBool)) {
|
2011-02-17 10:25:35 +00:00
|
|
|
const Expr *live = expr->getTrueExpr(), *dead = expr->getFalseExpr();
|
2011-02-27 23:02:32 +00:00
|
|
|
if (!CondExprBool) std::swap(live, dead);
|
2011-02-17 10:25:35 +00:00
|
|
|
|
2014-01-06 22:27:43 +00:00
|
|
|
if (!ContainsLabel(dead)) {
|
2014-01-07 00:20:28 +00:00
|
|
|
// If the true case is live, we need to track its region.
|
2014-01-06 22:27:43 +00:00
|
|
|
if (CondExprBool)
|
2015-04-23 23:06:47 +00:00
|
|
|
incrementProfileCounter(expr);
|
2020-04-08 12:05:49 -07:00
|
|
|
// If a throw expression we emit it and return an undefined lvalue
|
|
|
|
|
// because it can't be used.
|
|
|
|
|
if (auto *ThrowExpr = dyn_cast<CXXThrowExpr>(live->IgnoreParens())) {
|
|
|
|
|
EmitCXXThrowExpr(ThrowExpr);
|
|
|
|
|
llvm::Type *Ty =
|
|
|
|
|
llvm::PointerType::getUnqual(ConvertType(dead->getType()));
|
|
|
|
|
return MakeAddrLValue(
|
|
|
|
|
Address(llvm::UndefValue::get(Ty), CharUnits::One()),
|
|
|
|
|
dead->getType());
|
|
|
|
|
}
|
2011-02-17 10:25:35 +00:00
|
|
|
return EmitLValue(live);
|
2014-01-06 22:27:43 +00:00
|
|
|
}
|
2011-01-26 19:21:13 +00:00
|
|
|
}
|
|
|
|
|
|
2011-02-17 10:25:35 +00:00
|
|
|
llvm::BasicBlock *lhsBlock = createBasicBlock("cond.true");
|
|
|
|
|
llvm::BasicBlock *rhsBlock = createBasicBlock("cond.false");
|
|
|
|
|
llvm::BasicBlock *contBlock = createBasicBlock("cond.end");
|
2011-01-26 04:00:11 +00:00
|
|
|
|
2011-01-26 19:21:13 +00:00
|
|
|
ConditionalEvaluation eval(*this);
|
2015-04-23 23:06:47 +00:00
|
|
|
EmitBranchOnBoolExpr(condExpr, lhsBlock, rhsBlock, getProfileCount(expr));
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2011-01-26 19:21:13 +00:00
|
|
|
// Any temporaries created here are conditional.
|
2011-02-17 10:25:35 +00:00
|
|
|
EmitBlock(lhsBlock);
|
2015-04-23 23:06:47 +00:00
|
|
|
incrementProfileCounter(expr);
|
2011-01-26 19:21:13 +00:00
|
|
|
eval.begin(*this);
|
2014-06-20 18:43:47 +00:00
|
|
|
Optional<LValue> lhs =
|
|
|
|
|
EmitLValueOrThrowExpression(*this, expr->getTrueExpr());
|
2011-01-26 19:21:13 +00:00
|
|
|
eval.end(*this);
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2014-06-20 18:43:47 +00:00
|
|
|
if (lhs && !lhs->isSimple())
|
2011-02-17 10:25:35 +00:00
|
|
|
return EmitUnsupportedLValue(expr, "conditional operator");
|
2009-09-15 16:35:24 +00:00
|
|
|
|
2011-02-17 10:25:35 +00:00
|
|
|
lhsBlock = Builder.GetInsertBlock();
|
2014-06-20 18:43:47 +00:00
|
|
|
if (lhs)
|
|
|
|
|
Builder.CreateBr(contBlock);
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2011-01-26 19:21:13 +00:00
|
|
|
// Any temporaries created here are conditional.
|
2011-02-17 10:25:35 +00:00
|
|
|
EmitBlock(rhsBlock);
|
2011-01-26 19:21:13 +00:00
|
|
|
eval.begin(*this);
|
2014-06-20 18:43:47 +00:00
|
|
|
Optional<LValue> rhs =
|
|
|
|
|
EmitLValueOrThrowExpression(*this, expr->getFalseExpr());
|
2011-01-26 19:21:13 +00:00
|
|
|
eval.end(*this);
|
2014-06-20 18:43:47 +00:00
|
|
|
if (rhs && !rhs->isSimple())
|
2011-02-17 10:25:35 +00:00
|
|
|
return EmitUnsupportedLValue(expr, "conditional operator");
|
|
|
|
|
rhsBlock = Builder.GetInsertBlock();
|
2011-01-26 19:21:13 +00:00
|
|
|
|
2011-02-17 10:25:35 +00:00
|
|
|
EmitBlock(contBlock);
|
2011-01-26 19:21:13 +00:00
|
|
|
|
2014-06-20 18:43:47 +00:00
|
|
|
if (lhs && rhs) {
|
2019-12-03 15:17:01 -08:00
|
|
|
llvm::PHINode *phi =
|
|
|
|
|
Builder.CreatePHI(lhs->getPointer(*this)->getType(), 2, "cond-lvalue");
|
|
|
|
|
phi->addIncoming(lhs->getPointer(*this), lhsBlock);
|
|
|
|
|
phi->addIncoming(rhs->getPointer(*this), rhsBlock);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Address result(phi, std::min(lhs->getAlignment(), rhs->getAlignment()));
|
|
|
|
|
AlignmentSource alignSource =
|
2017-05-18 17:07:11 +00:00
|
|
|
std::max(lhs->getBaseInfo().getAlignmentSource(),
|
|
|
|
|
rhs->getBaseInfo().getAlignmentSource());
|
2017-10-31 11:05:34 +00:00
|
|
|
TBAAAccessInfo TBAAInfo = CGM.mergeTBAAInfoForConditionalOperator(
|
|
|
|
|
lhs->getTBAAInfo(), rhs->getTBAAInfo());
|
|
|
|
|
return MakeAddrLValue(result, expr->getType(), LValueBaseInfo(alignSource),
|
|
|
|
|
TBAAInfo);
|
2014-06-20 18:43:47 +00:00
|
|
|
} else {
|
|
|
|
|
assert((lhs || rhs) &&
|
|
|
|
|
"both operands of glvalue conditional are throw-expressions?");
|
|
|
|
|
return lhs ? *lhs : *rhs;
|
|
|
|
|
}
|
2009-03-24 02:38:23 +00:00
|
|
|
}
|
|
|
|
|
|
2012-05-14 21:57:21 +00:00
|
|
|
/// EmitCastLValue - Casts are never lvalues unless that cast is to a reference
|
|
|
|
|
/// type. If the cast is to a reference, we can have the usual lvalue result,
|
2009-11-16 06:50:58 +00:00
|
|
|
/// otherwise if a cast is needed by the code generator in an lvalue context,
|
|
|
|
|
/// then it must mean that we need the address of an aggregate in order to
|
2012-05-14 21:57:21 +00:00
|
|
|
/// access one of its members. This can happen for all the reasons that casts
|
2009-11-16 06:50:58 +00:00
|
|
|
/// are permitted with aggregate result, including noop aggregate casts, and
|
|
|
|
|
/// cast from scalar to union.
|
2009-03-18 18:28:57 +00:00
|
|
|
LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
|
2009-09-12 16:16:49 +00:00
|
|
|
switch (E->getCastKind()) {
|
2010-08-25 11:45:40 +00:00
|
|
|
case CK_ToVoid:
|
|
|
|
|
case CK_BitCast:
|
2019-07-02 18:28:13 +00:00
|
|
|
case CK_LValueToRValueBitCast:
|
2010-08-25 11:45:40 +00:00
|
|
|
case CK_ArrayToPointerDecay:
|
|
|
|
|
case CK_FunctionToPointerDecay:
|
|
|
|
|
case CK_NullToMemberPointer:
|
2010-11-13 01:35:44 +00:00
|
|
|
case CK_NullToPointer:
|
2010-08-25 11:45:40 +00:00
|
|
|
case CK_IntegralToPointer:
|
|
|
|
|
case CK_PointerToIntegral:
|
2010-11-15 09:13:47 +00:00
|
|
|
case CK_PointerToBoolean:
|
2010-08-25 11:45:40 +00:00
|
|
|
case CK_VectorSplat:
|
|
|
|
|
case CK_IntegralCast:
|
2016-01-13 01:52:39 +00:00
|
|
|
case CK_BooleanToSignedIntegral:
|
2010-11-15 09:13:47 +00:00
|
|
|
case CK_IntegralToBoolean:
|
2010-08-25 11:45:40 +00:00
|
|
|
case CK_IntegralToFloating:
|
|
|
|
|
case CK_FloatingToIntegral:
|
2010-11-15 09:13:47 +00:00
|
|
|
case CK_FloatingToBoolean:
|
2010-08-25 11:45:40 +00:00
|
|
|
case CK_FloatingCast:
|
2010-11-13 09:02:35 +00:00
|
|
|
case CK_FloatingRealToComplex:
|
2010-11-14 08:17:51 +00:00
|
|
|
case CK_FloatingComplexToReal:
|
|
|
|
|
case CK_FloatingComplexToBoolean:
|
2010-11-13 09:02:35 +00:00
|
|
|
case CK_FloatingComplexCast:
|
2010-11-14 08:17:51 +00:00
|
|
|
case CK_FloatingComplexToIntegralComplex:
|
2010-11-13 09:02:35 +00:00
|
|
|
case CK_IntegralRealToComplex:
|
2010-11-14 08:17:51 +00:00
|
|
|
case CK_IntegralComplexToReal:
|
|
|
|
|
case CK_IntegralComplexToBoolean:
|
2010-11-13 09:02:35 +00:00
|
|
|
case CK_IntegralComplexCast:
|
2010-11-14 08:17:51 +00:00
|
|
|
case CK_IntegralComplexToFloatingComplex:
|
2010-08-25 11:45:40 +00:00
|
|
|
case CK_DerivedToBaseMemberPointer:
|
|
|
|
|
case CK_BaseToDerivedMemberPointer:
|
|
|
|
|
case CK_MemberPointerToBoolean:
|
2012-02-15 01:22:51 +00:00
|
|
|
case CK_ReinterpretMemberPointer:
|
2011-06-15 23:02:42 +00:00
|
|
|
case CK_AnyPointerToBlockPointerCast:
|
2011-09-10 06:18:15 +00:00
|
|
|
case CK_ARCProduceObject:
|
|
|
|
|
case CK_ARCConsumeObject:
|
|
|
|
|
case CK_ARCReclaimReturnedObject:
|
2013-07-26 05:59:26 +00:00
|
|
|
case CK_ARCExtendBlockObject:
|
2013-06-28 00:23:34 +00:00
|
|
|
case CK_CopyAndAutoreleaseBlockObject:
|
2016-07-28 19:26:30 +00:00
|
|
|
case CK_IntToOCLSampler:
|
2020-08-26 16:46:57 +02:00
|
|
|
case CK_FloatingToFixedPoint:
|
|
|
|
|
case CK_FixedPointToFloating:
|
2018-10-15 16:07:02 +00:00
|
|
|
case CK_FixedPointCast:
|
2018-10-23 17:55:35 +00:00
|
|
|
case CK_FixedPointToBoolean:
|
2019-03-06 00:28:43 +00:00
|
|
|
case CK_FixedPointToIntegral:
|
|
|
|
|
case CK_IntegralToFixedPoint:
|
2013-06-28 00:23:34 +00:00
|
|
|
return EmitUnsupportedLValue(E, "unexpected cast lvalue");
|
|
|
|
|
|
|
|
|
|
case CK_Dependent:
|
|
|
|
|
llvm_unreachable("dependent cast kind in IR gen!");
|
|
|
|
|
|
|
|
|
|
case CK_BuiltinFnToFnPtr:
|
|
|
|
|
llvm_unreachable("builtin functions are handled elsewhere");
|
|
|
|
|
|
2013-07-11 01:32:21 +00:00
|
|
|
// These are never l-values; just use the aggregate emission code.
|
2013-06-28 00:23:34 +00:00
|
|
|
case CK_NonAtomicToAtomic:
|
|
|
|
|
case CK_AtomicToNonAtomic:
|
2013-07-11 01:32:21 +00:00
|
|
|
return EmitAggExprToLValue(E);
|
2009-11-16 05:48:01 +00:00
|
|
|
|
2011-04-11 02:03:26 +00:00
|
|
|
case CK_Dynamic: {
|
2009-11-16 06:50:58 +00:00
|
|
|
LValue LV = EmitLValue(E->getSubExpr());
|
2019-12-03 15:17:01 -08:00
|
|
|
Address V = LV.getAddress(*this);
|
2014-05-09 00:08:36 +00:00
|
|
|
const auto *DCE = cast<CXXDynamicCastExpr>(E);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
return MakeNaturalAlignAddrLValue(EmitDynamicCast(V, DCE), E->getType());
|
2009-11-16 06:50:58 +00:00
|
|
|
}
|
|
|
|
|
|
2010-08-25 11:45:40 +00:00
|
|
|
case CK_ConstructorConversion:
|
|
|
|
|
case CK_UserDefinedConversion:
|
2011-09-09 05:25:32 +00:00
|
|
|
case CK_CPointerToObjCPointerCast:
|
|
|
|
|
case CK_BlockPointerToObjCPointerCast:
|
2013-06-28 00:23:34 +00:00
|
|
|
case CK_NoOp:
|
|
|
|
|
case CK_LValueToRValue:
|
2009-03-18 18:28:57 +00:00
|
|
|
return EmitLValue(E->getSubExpr());
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2010-08-25 11:45:40 +00:00
|
|
|
case CK_UncheckedDerivedToBase:
|
|
|
|
|
case CK_DerivedToBase: {
|
2020-01-11 15:33:25 +00:00
|
|
|
const auto *DerivedClassTy =
|
|
|
|
|
E->getSubExpr()->getType()->castAs<RecordType>();
|
2014-05-09 00:08:36 +00:00
|
|
|
auto *DerivedClassDecl = cast<CXXRecordDecl>(DerivedClassTy->getDecl());
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2009-09-12 16:16:49 +00:00
|
|
|
LValue LV = EmitLValue(E->getSubExpr());
|
2019-12-03 15:17:01 -08:00
|
|
|
Address This = LV.getAddress(*this);
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2009-09-12 16:16:49 +00:00
|
|
|
// Perform the derived-to-base conversion
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Address Base = GetAddressOfBaseClass(
|
2014-10-13 23:59:00 +00:00
|
|
|
This, DerivedClassDecl, E->path_begin(), E->path_end(),
|
|
|
|
|
/*NullCheckValue=*/false, E->getExprLoc());
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2017-10-31 11:05:34 +00:00
|
|
|
// TODO: Support accesses to members of base classes in TBAA. For now, we
|
|
|
|
|
// conservatively pretend that the complete object is of the base class
|
|
|
|
|
// type.
|
2017-10-12 11:29:46 +00:00
|
|
|
return MakeAddrLValue(Base, E->getType(), LV.getBaseInfo(),
|
2017-10-31 11:05:34 +00:00
|
|
|
CGM.getTBAAInfoForSubobject(LV, E->getType()));
|
2009-09-12 16:16:49 +00:00
|
|
|
}
|
2010-08-25 11:45:40 +00:00
|
|
|
case CK_ToUnion:
|
2010-02-05 20:02:42 +00:00
|
|
|
return EmitAggExprToLValue(E);
|
2010-08-25 11:45:40 +00:00
|
|
|
case CK_BaseToDerived: {
|
2020-01-11 15:33:25 +00:00
|
|
|
const auto *DerivedClassTy = E->getType()->castAs<RecordType>();
|
2014-05-09 00:08:36 +00:00
|
|
|
auto *DerivedClassDecl = cast<CXXRecordDecl>(DerivedClassTy->getDecl());
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2009-11-23 17:57:54 +00:00
|
|
|
LValue LV = EmitLValue(E->getSubExpr());
|
2013-02-13 21:18:23 +00:00
|
|
|
|
2009-11-23 17:57:54 +00:00
|
|
|
// Perform the base-to-derived conversion
|
2019-12-03 15:17:01 -08:00
|
|
|
Address Derived = GetAddressOfDerivedClass(
|
|
|
|
|
LV.getAddress(*this), DerivedClassDecl, E->path_begin(), E->path_end(),
|
|
|
|
|
/*NullCheckValue=*/false);
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2013-08-08 01:08:17 +00:00
|
|
|
// C++11 [expr.static.cast]p2: Behavior is undefined if a downcast is
|
|
|
|
|
// performed and the object is not of the derived type.
|
2014-07-07 23:59:57 +00:00
|
|
|
if (sanitizePerformTypeCheck())
|
2013-08-08 01:08:17 +00:00
|
|
|
EmitTypeCheck(TCK_DowncastReference, E->getExprLoc(),
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Derived.getPointer(), E->getType());
|
2013-08-08 01:08:17 +00:00
|
|
|
|
2015-03-14 02:42:25 +00:00
|
|
|
if (SanOpts.has(SanitizerKind::CFIDerivedCast))
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
EmitVTablePtrCheckForCast(E->getType(), Derived.getPointer(),
|
2018-08-09 21:08:08 +00:00
|
|
|
/*MayBeNull=*/false, CFITCK_DerivedCast,
|
|
|
|
|
E->getBeginLoc());
|
2015-03-14 02:42:25 +00:00
|
|
|
|
2017-10-12 11:29:46 +00:00
|
|
|
return MakeAddrLValue(Derived, E->getType(), LV.getBaseInfo(),
|
2017-10-31 11:05:34 +00:00
|
|
|
CGM.getTBAAInfoForSubobject(LV, E->getType()));
|
2009-11-16 05:48:01 +00:00
|
|
|
}
|
2010-08-25 11:45:40 +00:00
|
|
|
case CK_LValueBitCast: {
|
2009-11-16 05:48:01 +00:00
|
|
|
// This must be a reinterpret_cast (or c-style equivalent).
|
2014-05-09 00:08:36 +00:00
|
|
|
const auto *CE = cast<ExplicitCastExpr>(E);
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2015-10-20 04:24:12 +00:00
|
|
|
CGM.EmitExplicitCastExprType(CE, this);
|
2009-11-14 21:21:42 +00:00
|
|
|
LValue LV = EmitLValue(E->getSubExpr());
|
2019-12-03 15:17:01 -08:00
|
|
|
Address V = Builder.CreateBitCast(LV.getAddress(*this),
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
ConvertType(CE->getTypeAsWritten()));
|
2015-03-14 02:42:25 +00:00
|
|
|
|
|
|
|
|
if (SanOpts.has(SanitizerKind::CFIUnrelatedCast))
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
EmitVTablePtrCheckForCast(E->getType(), V.getPointer(),
|
2018-08-09 21:08:08 +00:00
|
|
|
/*MayBeNull=*/false, CFITCK_UnrelatedCast,
|
|
|
|
|
E->getBeginLoc());
|
2015-03-14 02:42:25 +00:00
|
|
|
|
2017-10-12 11:29:46 +00:00
|
|
|
return MakeAddrLValue(V, E->getType(), LV.getBaseInfo(),
|
2017-10-31 11:05:34 +00:00
|
|
|
CGM.getTBAAInfoForSubobject(LV, E->getType()));
|
2009-11-14 21:21:42 +00:00
|
|
|
}
|
2018-11-16 16:22:56 +00:00
|
|
|
case CK_AddressSpaceConversion: {
|
|
|
|
|
LValue LV = EmitLValue(E->getSubExpr());
|
|
|
|
|
QualType DestTy = getContext().getPointerType(E->getType());
|
|
|
|
|
llvm::Value *V = getTargetHooks().performAddrSpaceCast(
|
2019-12-03 15:17:01 -08:00
|
|
|
*this, LV.getPointer(*this),
|
|
|
|
|
E->getSubExpr()->getType().getAddressSpace(),
|
2018-12-12 09:51:23 +00:00
|
|
|
E->getType().getAddressSpace(), ConvertType(DestTy));
|
2019-12-03 15:17:01 -08:00
|
|
|
return MakeAddrLValue(Address(V, LV.getAddress(*this).getAlignment()),
|
2018-12-12 09:51:23 +00:00
|
|
|
E->getType(), LV.getBaseInfo(), LV.getTBAAInfo());
|
2018-11-16 16:22:56 +00:00
|
|
|
}
|
2010-08-25 11:45:40 +00:00
|
|
|
case CK_ObjCObjectLValueCast: {
|
2010-08-07 11:51:51 +00:00
|
|
|
LValue LV = EmitLValue(E->getSubExpr());
|
2019-12-03 15:17:01 -08:00
|
|
|
Address V = Builder.CreateElementBitCast(LV.getAddress(*this),
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
ConvertType(E->getType()));
|
2017-10-12 11:29:46 +00:00
|
|
|
return MakeAddrLValue(V, E->getType(), LV.getBaseInfo(),
|
2017-10-31 11:05:34 +00:00
|
|
|
CGM.getTBAAInfoForSubobject(LV, E->getType()));
|
2010-08-07 11:51:51 +00:00
|
|
|
}
|
2018-10-23 15:19:20 +00:00
|
|
|
case CK_ZeroToOCLOpaqueType:
|
|
|
|
|
llvm_unreachable("NULL to OpenCL opaque type lvalue cast is not valid");
|
2009-09-12 16:16:49 +00:00
|
|
|
}
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2010-07-15 18:58:16 +00:00
|
|
|
llvm_unreachable("Unhandled lvalue cast kind?");
|
2009-03-18 18:28:57 +00:00
|
|
|
}
|
|
|
|
|
|
2011-02-16 08:02:54 +00:00
|
|
|
LValue CodeGenFunction::EmitOpaqueValueLValue(const OpaqueValueExpr *e) {
|
2011-11-08 22:54:08 +00:00
|
|
|
assert(OpaqueValueMappingData::shouldBindAsLValue(e));
|
2018-03-20 01:47:58 +00:00
|
|
|
return getOrCreateOpaqueLValueMapping(e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LValue
|
|
|
|
|
CodeGenFunction::getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e) {
|
|
|
|
|
assert(OpaqueValueMapping::shouldBindAsLValue(e));
|
|
|
|
|
|
|
|
|
|
llvm::DenseMap<const OpaqueValueExpr*,LValue>::iterator
|
|
|
|
|
it = OpaqueLValues.find(e);
|
|
|
|
|
|
|
|
|
|
if (it != OpaqueLValues.end())
|
|
|
|
|
return it->second;
|
|
|
|
|
|
|
|
|
|
assert(e->isUnique() && "LValue for a nonunique OVE hasn't been emitted");
|
|
|
|
|
return EmitLValue(e->getSourceExpr());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RValue
|
|
|
|
|
CodeGenFunction::getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e) {
|
|
|
|
|
assert(!OpaqueValueMapping::shouldBindAsLValue(e));
|
|
|
|
|
|
|
|
|
|
llvm::DenseMap<const OpaqueValueExpr*,RValue>::iterator
|
|
|
|
|
it = OpaqueRValues.find(e);
|
|
|
|
|
|
|
|
|
|
if (it != OpaqueRValues.end())
|
|
|
|
|
return it->second;
|
|
|
|
|
|
|
|
|
|
assert(e->isUnique() && "RValue for a nonunique OVE hasn't been emitted");
|
|
|
|
|
return EmitAnyExpr(e->getSourceExpr());
|
2011-02-16 08:02:54 +00:00
|
|
|
}
|
|
|
|
|
|
2012-04-16 03:54:45 +00:00
|
|
|
RValue CodeGenFunction::EmitRValueForField(LValue LV,
|
2013-10-02 02:29:49 +00:00
|
|
|
const FieldDecl *FD,
|
|
|
|
|
SourceLocation Loc) {
|
2012-04-13 11:22:00 +00:00
|
|
|
QualType FT = FD->getType();
|
2012-04-16 03:54:45 +00:00
|
|
|
LValue FieldLV = EmitLValueForField(LV, FD);
|
2013-03-07 21:37:08 +00:00
|
|
|
switch (getEvaluationKind(FT)) {
|
|
|
|
|
case TEK_Complex:
|
2013-10-02 02:29:49 +00:00
|
|
|
return RValue::getComplex(EmitLoadOfComplex(FieldLV, Loc));
|
2013-03-07 21:37:08 +00:00
|
|
|
case TEK_Aggregate:
|
2019-12-03 15:17:01 -08:00
|
|
|
return FieldLV.asAggregateRValue(*this);
|
2013-03-07 21:37:08 +00:00
|
|
|
case TEK_Scalar:
|
2016-05-02 22:42:34 +00:00
|
|
|
// This routine is used to load fields one-by-one to perform a copy, so
|
|
|
|
|
// don't load reference fields.
|
|
|
|
|
if (FD->getType()->isReferenceType())
|
2019-12-03 15:17:01 -08:00
|
|
|
return RValue::get(FieldLV.getPointer(*this));
|
2019-11-29 09:56:02 -08:00
|
|
|
// Call EmitLoadOfScalar except when the lvalue is a bitfield to emit a
|
|
|
|
|
// primitive load.
|
|
|
|
|
if (FieldLV.isBitField())
|
|
|
|
|
return EmitLoadOfLValue(FieldLV, Loc);
|
|
|
|
|
return RValue::get(EmitLoadOfScalar(FieldLV, Loc));
|
2013-03-07 21:37:08 +00:00
|
|
|
}
|
|
|
|
|
llvm_unreachable("bad evaluation kind");
|
2012-04-13 11:22:00 +00:00
|
|
|
}
|
2011-06-21 17:03:29 +00:00
|
|
|
|
2007-06-01 18:02:12 +00:00
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
// Expression Emission
|
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
|
2013-07-26 05:59:26 +00:00
|
|
|
RValue CodeGenFunction::EmitCallExpr(const CallExpr *E,
|
2009-12-24 20:40:36 +00:00
|
|
|
ReturnValueSlot ReturnValue) {
|
2009-02-20 18:06:48 +00:00
|
|
|
// Builtins never have block type.
|
|
|
|
|
if (E->getCallee()->getType()->isBlockPointerType())
|
2009-12-24 21:13:40 +00:00
|
|
|
return EmitBlockCallExpr(E, ReturnValue);
|
2009-02-20 18:06:48 +00:00
|
|
|
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *CE = dyn_cast<CXXMemberCallExpr>(E))
|
2009-12-24 21:13:40 +00:00
|
|
|
return EmitCXXMemberCallExpr(CE, ReturnValue);
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *CE = dyn_cast<CUDAKernelCallExpr>(E))
|
2011-10-06 18:29:37 +00:00
|
|
|
return EmitCUDAKernelCallExpr(CE, ReturnValue);
|
|
|
|
|
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *CE = dyn_cast<CXXOperatorCallExpr>(E))
|
2016-10-26 23:46:34 +00:00
|
|
|
if (const CXXMethodDecl *MD =
|
|
|
|
|
dyn_cast_or_null<CXXMethodDecl>(CE->getCalleeDecl()))
|
2009-12-24 21:13:40 +00:00
|
|
|
return EmitCXXOperatorMemberCallExpr(CE, MD, ReturnValue);
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2016-10-26 23:46:34 +00:00
|
|
|
CGCallee callee = EmitCallee(E->getCallee());
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2016-10-26 23:46:34 +00:00
|
|
|
if (callee.isBuiltin()) {
|
|
|
|
|
return EmitBuiltinExpr(callee.getBuiltinDecl(), callee.getBuiltinID(),
|
|
|
|
|
E, ReturnValue);
|
|
|
|
|
}
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2016-10-26 23:46:34 +00:00
|
|
|
if (callee.isPseudoDestructor()) {
|
|
|
|
|
return EmitCXXPseudoDestructorExpr(callee.getPseudoDestructorExpr());
|
|
|
|
|
}
|
2011-06-15 23:02:42 +00:00
|
|
|
|
2016-10-26 23:46:34 +00:00
|
|
|
return EmitCall(E->getCallee()->getType(), callee, E, ReturnValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Emit a CallExpr without considering whether it might be a subclass.
|
|
|
|
|
RValue CodeGenFunction::EmitSimpleCallExpr(const CallExpr *E,
|
|
|
|
|
ReturnValueSlot ReturnValue) {
|
|
|
|
|
CGCallee Callee = EmitCallee(E->getCallee());
|
|
|
|
|
return EmitCall(E->getCallee()->getType(), Callee, E, ReturnValue);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-05 12:02:13 -05:00
|
|
|
static CGCallee EmitDirectCallee(CodeGenFunction &CGF, GlobalDecl GD) {
|
|
|
|
|
const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
|
2020-01-16 19:54:38 +01:00
|
|
|
|
2016-10-26 23:46:34 +00:00
|
|
|
if (auto builtinID = FD->getBuiltinID()) {
|
2020-01-16 19:54:38 +01:00
|
|
|
// Replaceable builtin provide their own implementation of a builtin. Unless
|
|
|
|
|
// we are in the builtin implementation itself, don't call the actual
|
|
|
|
|
// builtin. If we are in the builtin implementation, avoid trivial infinite
|
|
|
|
|
// recursion.
|
|
|
|
|
if (!FD->isInlineBuiltinDeclaration() ||
|
|
|
|
|
CGF.CurFn->getName() == FD->getName())
|
|
|
|
|
return CGCallee::forBuiltin(builtinID, FD);
|
2016-10-26 23:46:34 +00:00
|
|
|
}
|
|
|
|
|
|
2020-03-05 12:02:13 -05:00
|
|
|
llvm::Constant *calleePtr = EmitFunctionDeclPointer(CGF.CGM, GD);
|
|
|
|
|
return CGCallee::forDirect(calleePtr, GD);
|
2016-10-26 23:46:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CGCallee CodeGenFunction::EmitCallee(const Expr *E) {
|
|
|
|
|
E = E->IgnoreParens();
|
|
|
|
|
|
|
|
|
|
// Look through function-to-pointer decay.
|
|
|
|
|
if (auto ICE = dyn_cast<ImplicitCastExpr>(E)) {
|
|
|
|
|
if (ICE->getCastKind() == CK_FunctionToPointerDecay ||
|
|
|
|
|
ICE->getCastKind() == CK_BuiltinFnToFnPtr) {
|
|
|
|
|
return EmitCallee(ICE->getSubExpr());
|
2011-06-15 23:02:42 +00:00
|
|
|
}
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2016-10-26 23:46:34 +00:00
|
|
|
// Resolve direct calls.
|
|
|
|
|
} else if (auto DRE = dyn_cast<DeclRefExpr>(E)) {
|
|
|
|
|
if (auto FD = dyn_cast<FunctionDecl>(DRE->getDecl())) {
|
2020-03-18 01:43:20 -04:00
|
|
|
return EmitDirectCallee(*this, FD);
|
2016-10-26 23:46:34 +00:00
|
|
|
}
|
|
|
|
|
} else if (auto ME = dyn_cast<MemberExpr>(E)) {
|
|
|
|
|
if (auto FD = dyn_cast<FunctionDecl>(ME->getMemberDecl())) {
|
|
|
|
|
EmitIgnoredExpr(ME->getBase());
|
2020-03-18 01:43:20 -04:00
|
|
|
return EmitDirectCallee(*this, FD);
|
2016-10-26 23:46:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Look through template substitutions.
|
|
|
|
|
} else if (auto NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
|
|
|
|
|
return EmitCallee(NTTP->getReplacement());
|
|
|
|
|
|
|
|
|
|
// Treat pseudo-destructor calls differently.
|
|
|
|
|
} else if (auto PDE = dyn_cast<CXXPseudoDestructorExpr>(E)) {
|
|
|
|
|
return CGCallee::forPseudoDestructor(PDE);
|
2009-09-04 17:36:40 +00:00
|
|
|
}
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2016-10-26 23:46:34 +00:00
|
|
|
// Otherwise, we have an indirect reference.
|
|
|
|
|
llvm::Value *calleePtr;
|
|
|
|
|
QualType functionType;
|
|
|
|
|
if (auto ptrType = E->getType()->getAs<PointerType>()) {
|
|
|
|
|
calleePtr = EmitScalarExpr(E);
|
|
|
|
|
functionType = ptrType->getPointeeType();
|
|
|
|
|
} else {
|
|
|
|
|
functionType = E->getType();
|
2019-12-03 15:17:01 -08:00
|
|
|
calleePtr = EmitLValue(E).getPointer(*this);
|
2016-10-26 23:46:34 +00:00
|
|
|
}
|
|
|
|
|
assert(functionType->isFunctionType());
|
2018-11-13 15:48:08 +00:00
|
|
|
|
|
|
|
|
GlobalDecl GD;
|
|
|
|
|
if (const auto *VD =
|
|
|
|
|
dyn_cast_or_null<VarDecl>(E->getReferencedDeclOfCallee()))
|
|
|
|
|
GD = GlobalDecl(VD);
|
|
|
|
|
|
|
|
|
|
CGCalleeInfo calleeInfo(functionType->getAs<FunctionProtoType>(), GD);
|
2016-10-26 23:46:34 +00:00
|
|
|
CGCallee callee(calleeInfo, calleePtr);
|
|
|
|
|
return callee;
|
2007-08-31 04:44:06 +00:00
|
|
|
}
|
|
|
|
|
|
2008-09-04 03:20:13 +00:00
|
|
|
LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
|
2009-05-12 21:28:12 +00:00
|
|
|
// Comma expressions just emit their LHS then their RHS as an l-value.
|
2010-08-25 11:45:40 +00:00
|
|
|
if (E->getOpcode() == BO_Comma) {
|
2010-12-05 02:00:02 +00:00
|
|
|
EmitIgnoredExpr(E->getLHS());
|
2009-12-07 20:18:11 +00:00
|
|
|
EnsureInsertPoint();
|
2009-05-12 21:28:12 +00:00
|
|
|
return EmitLValue(E->getRHS());
|
|
|
|
|
}
|
2009-09-09 13:00:44 +00:00
|
|
|
|
2010-08-25 11:45:40 +00:00
|
|
|
if (E->getOpcode() == BO_PtrMemD ||
|
|
|
|
|
E->getOpcode() == BO_PtrMemI)
|
2009-10-22 22:57:31 +00:00
|
|
|
return EmitPointerToDataMemberBinaryExpr(E);
|
2008-09-04 03:20:13 +00:00
|
|
|
|
2010-12-05 02:00:02 +00:00
|
|
|
assert(E->getOpcode() == BO_Assign && "unexpected binary l-value");
|
2011-06-15 23:02:42 +00:00
|
|
|
|
|
|
|
|
// Note that in all of these cases, __block variables need the RHS
|
|
|
|
|
// evaluated first just in case the variable gets moved by the RHS.
|
2013-03-07 21:37:08 +00:00
|
|
|
|
|
|
|
|
switch (getEvaluationKind(E->getType())) {
|
|
|
|
|
case TEK_Scalar: {
|
2011-06-15 23:02:42 +00:00
|
|
|
switch (E->getLHS()->getType().getObjCLifetime()) {
|
|
|
|
|
case Qualifiers::OCL_Strong:
|
|
|
|
|
return EmitARCStoreStrong(E, /*ignored*/ false).first;
|
|
|
|
|
|
|
|
|
|
case Qualifiers::OCL_Autoreleasing:
|
|
|
|
|
return EmitARCStoreAutoreleasing(E).first;
|
|
|
|
|
|
|
|
|
|
// No reason to do any of these differently.
|
|
|
|
|
case Qualifiers::OCL_None:
|
|
|
|
|
case Qualifiers::OCL_ExplicitNone:
|
|
|
|
|
case Qualifiers::OCL_Weak:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2010-12-06 06:10:02 +00:00
|
|
|
RValue RV = EmitAnyExpr(E->getRHS());
|
2012-10-09 19:52:38 +00:00
|
|
|
LValue LV = EmitCheckedLValue(E->getLHS(), TCK_Store);
|
2017-04-26 21:55:17 +00:00
|
|
|
if (RV.isScalar())
|
|
|
|
|
EmitNullabilityCheck(LV, RV.getScalarVal(), E->getExprLoc());
|
2011-06-25 02:11:03 +00:00
|
|
|
EmitStoreThroughLValue(RV, LV);
|
2019-12-27 09:44:43 -05:00
|
|
|
if (getLangOpts().OpenMP)
|
|
|
|
|
CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*this,
|
|
|
|
|
E->getLHS());
|
2009-10-19 18:28:22 +00:00
|
|
|
return LV;
|
|
|
|
|
}
|
2010-11-16 23:07:28 +00:00
|
|
|
|
2013-03-07 21:37:08 +00:00
|
|
|
case TEK_Complex:
|
2010-11-16 23:07:28 +00:00
|
|
|
return EmitComplexAssignmentLValue(E);
|
|
|
|
|
|
2013-03-07 21:37:08 +00:00
|
|
|
case TEK_Aggregate:
|
|
|
|
|
return EmitAggExprToLValue(E);
|
|
|
|
|
}
|
|
|
|
|
llvm_unreachable("bad evaluation kind");
|
2008-09-04 03:20:13 +00:00
|
|
|
}
|
|
|
|
|
|
2007-12-29 05:02:41 +00:00
|
|
|
LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E) {
|
|
|
|
|
RValue RV = EmitCallExpr(E);
|
2009-05-27 01:45:47 +00:00
|
|
|
|
2009-10-28 17:39:19 +00:00
|
|
|
if (!RV.isScalar())
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
return MakeAddrLValue(RV.getAggregateAddress(), E->getType(),
|
2017-10-10 09:39:32 +00:00
|
|
|
AlignmentSource::Decl);
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2015-02-25 17:36:15 +00:00
|
|
|
assert(E->getCallReturnType(getContext())->isReferenceType() &&
|
2009-10-28 17:39:19 +00:00
|
|
|
"Can't have a scalar return unless the return type is a "
|
|
|
|
|
"reference type!");
|
2009-09-09 13:00:44 +00: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 08:05:57 +00:00
|
|
|
return MakeNaturalAlignPointeeAddrLValue(RV.getScalarVal(), E->getType());
|
2007-12-29 05:02:41 +00:00
|
|
|
}
|
|
|
|
|
|
2009-02-11 20:59:32 +00:00
|
|
|
LValue CodeGenFunction::EmitVAArgExprLValue(const VAArgExpr *E) {
|
|
|
|
|
// FIXME: This shouldn't require another copy.
|
2010-02-05 19:38:31 +00:00
|
|
|
return EmitAggExprToLValue(E);
|
2009-02-11 20:59:32 +00:00
|
|
|
}
|
|
|
|
|
|
2009-05-30 23:23:33 +00:00
|
|
|
LValue CodeGenFunction::EmitCXXConstructLValue(const CXXConstructExpr *E) {
|
2010-09-18 00:58:34 +00:00
|
|
|
assert(E->getType()->getAsCXXRecordDecl()->hasTrivialDestructor()
|
|
|
|
|
&& "binding l-value to type which needs a temporary");
|
2011-09-27 21:06:10 +00:00
|
|
|
AggValueSlot Slot = CreateAggTemp(E->getType());
|
2010-09-15 10:14:12 +00:00
|
|
|
EmitCXXConstructExpr(E, Slot);
|
2017-10-10 09:39:32 +00:00
|
|
|
return MakeAddrLValue(Slot.getAddress(), E->getType(), AlignmentSource::Decl);
|
2009-05-30 23:23:33 +00:00
|
|
|
}
|
|
|
|
|
|
2009-11-15 08:09:41 +00:00
|
|
|
LValue
|
|
|
|
|
CodeGenFunction::EmitCXXTypeidLValue(const CXXTypeidExpr *E) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
return MakeNaturalAlignAddrLValue(EmitCXXTypeidExpr(E), E->getType());
|
2009-11-15 08:09:41 +00: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 08:05:57 +00:00
|
|
|
Address CodeGenFunction::EmitCXXUuidofExpr(const CXXUuidofExpr *E) {
|
Rework how UuidAttr, CXXUuidofExpr, and GUID template arguments and constants are represented.
Summary:
Previously, we treated CXXUuidofExpr as quite a special case: it was the
only kind of expression that could be a canonical template argument, it
could be a constant lvalue base object, and so on. In addition, we
represented the UUID value as a string, whose source form we did not
preserve faithfully, and that we partially parsed in multiple different
places.
With this patch, we create an MSGuidDecl object to represent the
implicit object of type 'struct _GUID' created by a UuidAttr. Each
UuidAttr holds a pointer to its 'struct _GUID' and its original
(as-written) UUID string. A non-value-dependent CXXUuidofExpr behaves
like a DeclRefExpr denoting that MSGuidDecl object. We cache an APValue
representation of the GUID on the MSGuidDecl and use it from constant
evaluation where needed.
This allows removing a lot of the special-case logic to handle these
expressions. Unfortunately, many parts of Clang assume there are only
a couple of interesting kinds of ValueDecl, so the total amount of
special-case logic is not really reduced very much.
This fixes a few bugs and issues:
* PR38490: we now support reading from GUID objects returned from
__uuidof during constant evaluation.
* Our Itanium mangling for a non-instantiation-dependent template
argument involving __uuidof no longer depends on which CXXUuidofExpr
template argument we happened to see first.
* We now predeclare ::_GUID, and permit use of __uuidof without
any header inclusion, better matching MSVC's behavior. We do not
predefine ::__s_GUID, though; that seems like a step too far.
* Our IR representation for GUID constants now uses the correct IR type
wherever possible. We will still fall back to using the
{i32, i16, i16, [8 x i8]}
layout if a definition of struct _GUID is not available. This is not
ideal: in principle the two layouts could have different padding.
Reviewers: rnk, jdoerfert
Subscribers: arphaman, cfe-commits, aeubanks
Tags: #clang
Differential Revision: https://reviews.llvm.org/D78171
2020-04-11 22:15:29 -07:00
|
|
|
return Builder.CreateElementBitCast(CGM.GetAddrOfMSGuidDecl(E->getGuidDecl()),
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
ConvertType(E->getType()));
|
2012-10-11 10:13:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LValue CodeGenFunction::EmitCXXUuidofLValue(const CXXUuidofExpr *E) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
return MakeAddrLValue(EmitCXXUuidofExpr(E), E->getType(),
|
2017-10-10 09:39:32 +00:00
|
|
|
AlignmentSource::Decl);
|
2012-10-11 10:13:44 +00:00
|
|
|
}
|
|
|
|
|
|
2009-05-30 23:30:54 +00:00
|
|
|
LValue
|
|
|
|
|
CodeGenFunction::EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E) {
|
2010-09-18 00:58:34 +00:00
|
|
|
AggValueSlot Slot = CreateAggTemp(E->getType(), "temp.lvalue");
|
2011-08-26 08:02:37 +00:00
|
|
|
Slot.setExternallyDestructed();
|
2010-09-18 00:58:34 +00:00
|
|
|
EmitAggExpr(E->getSubExpr(), Slot);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
EmitCXXTemporary(E->getTemporary(), E->getType(), Slot.getAddress());
|
2017-10-10 09:39:32 +00:00
|
|
|
return MakeAddrLValue(Slot.getAddress(), E->getType(), AlignmentSource::Decl);
|
2012-02-08 05:34:55 +00:00
|
|
|
}
|
|
|
|
|
|
2008-08-23 10:51:21 +00:00
|
|
|
LValue CodeGenFunction::EmitObjCMessageExprLValue(const ObjCMessageExpr *E) {
|
|
|
|
|
RValue RV = EmitObjCMessageExpr(E);
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2010-06-21 20:59:55 +00:00
|
|
|
if (!RV.isScalar())
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
return MakeAddrLValue(RV.getAggregateAddress(), E->getType(),
|
2017-10-10 09:39:32 +00:00
|
|
|
AlignmentSource::Decl);
|
2013-07-26 05:59:26 +00:00
|
|
|
|
2014-01-25 16:55:45 +00:00
|
|
|
assert(E->getMethodDecl()->getReturnType()->isReferenceType() &&
|
2010-06-21 20:59:55 +00:00
|
|
|
"Can't have a scalar return unless the return type is a "
|
|
|
|
|
"reference type!");
|
2013-07-26 05:59:26 +00: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 08:05:57 +00:00
|
|
|
return MakeNaturalAlignPointeeAddrLValue(RV.getScalarVal(), E->getType());
|
2008-08-23 10:51:21 +00:00
|
|
|
}
|
|
|
|
|
|
2010-06-17 19:56:20 +00:00
|
|
|
LValue CodeGenFunction::EmitObjCSelectorLValue(const ObjCSelectorExpr *E) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Address V =
|
|
|
|
|
CGM.getObjCRuntime().GetAddrOfSelector(*this, E->getSelector());
|
2017-10-10 09:39:32 +00:00
|
|
|
return MakeAddrLValue(V, E->getType(), AlignmentSource::Decl);
|
2010-06-17 19:56:20 +00:00
|
|
|
}
|
|
|
|
|
|
2009-04-22 05:08:15 +00:00
|
|
|
llvm::Value *CodeGenFunction::EmitIvarOffset(const ObjCInterfaceDecl *Interface,
|
2008-09-24 04:00:38 +00:00
|
|
|
const ObjCIvarDecl *Ivar) {
|
2009-02-10 19:02:04 +00:00
|
|
|
return CGM.getObjCRuntime().EmitIvarOffset(*this, Interface, Ivar);
|
2008-09-24 04:00:38 +00:00
|
|
|
}
|
2008-08-25 01:53:23 +00:00
|
|
|
|
2009-02-03 00:09:52 +00:00
|
|
|
LValue CodeGenFunction::EmitLValueForIvar(QualType ObjectTy,
|
|
|
|
|
llvm::Value *BaseValue,
|
2008-09-24 04:00:38 +00:00
|
|
|
const ObjCIvarDecl *Ivar,
|
|
|
|
|
unsigned CVRQualifiers) {
|
2009-04-17 17:44:48 +00:00
|
|
|
return CGM.getObjCRuntime().EmitObjCValueForIvar(*this, ObjectTy, BaseValue,
|
2009-04-21 01:19:28 +00:00
|
|
|
Ivar, CVRQualifiers);
|
2008-09-24 04:00:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) {
|
2008-08-25 01:53:23 +00:00
|
|
|
// FIXME: A lot of the code below could be shared with EmitMemberExpr.
|
2014-05-21 05:09:00 +00:00
|
|
|
llvm::Value *BaseValue = nullptr;
|
2008-08-25 01:53:23 +00:00
|
|
|
const Expr *BaseExpr = E->getBase();
|
2009-09-24 19:53:00 +00:00
|
|
|
Qualifiers BaseQuals;
|
2009-02-03 00:09:52 +00:00
|
|
|
QualType ObjectTy;
|
2008-08-25 01:53:23 +00:00
|
|
|
if (E->isArrow()) {
|
|
|
|
|
BaseValue = EmitScalarExpr(BaseExpr);
|
2009-07-10 23:34:53 +00:00
|
|
|
ObjectTy = BaseExpr->getType()->getPointeeType();
|
2009-09-24 19:53:00 +00:00
|
|
|
BaseQuals = ObjectTy.getQualifiers();
|
2008-08-25 01:53:23 +00:00
|
|
|
} else {
|
|
|
|
|
LValue BaseLV = EmitLValue(BaseExpr);
|
2019-12-03 15:17:01 -08:00
|
|
|
BaseValue = BaseLV.getPointer(*this);
|
2009-02-03 00:09:52 +00:00
|
|
|
ObjectTy = BaseExpr->getType();
|
2009-09-24 19:53:00 +00:00
|
|
|
BaseQuals = ObjectTy.getQualifiers();
|
2008-08-25 01:53:23 +00:00
|
|
|
}
|
2008-09-24 04:00:38 +00:00
|
|
|
|
2013-07-26 05:59:26 +00:00
|
|
|
LValue LV =
|
2009-09-24 19:53:00 +00:00
|
|
|
EmitLValueForIvar(ObjectTy, BaseValue, E->getDecl(),
|
|
|
|
|
BaseQuals.getCVRQualifiers());
|
2009-09-16 23:11:23 +00:00
|
|
|
setObjCGCLValueClass(getContext(), E, LV);
|
|
|
|
|
return LV;
|
2008-03-30 23:03:07 +00:00
|
|
|
}
|
|
|
|
|
|
2009-04-25 19:35:26 +00:00
|
|
|
LValue CodeGenFunction::EmitStmtExprLValue(const StmtExpr *E) {
|
|
|
|
|
// Can only get l-value for message expression returning aggregate type
|
|
|
|
|
RValue RV = EmitAnyExprToTemp(E);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
return MakeAddrLValue(RV.getAggregateAddress(), E->getType(),
|
2017-10-10 09:39:32 +00:00
|
|
|
AlignmentSource::Decl);
|
2009-04-25 19:35:26 +00:00
|
|
|
}
|
|
|
|
|
|
2016-10-26 23:46:34 +00:00
|
|
|
RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee,
|
2014-08-21 20:26:47 +00:00
|
|
|
const CallExpr *E, ReturnValueSlot ReturnValue,
|
2016-10-26 23:46:34 +00:00
|
|
|
llvm::Value *Chain) {
|
2009-09-09 13:00:44 +00:00
|
|
|
// Get the actual function type. The callee type will always be a pointer to
|
|
|
|
|
// function type or a block pointer type.
|
|
|
|
|
assert(CalleeType->isFunctionPointerType() &&
|
2009-04-07 18:53:02 +00:00
|
|
|
"Call must have function pointer type!");
|
|
|
|
|
|
2018-11-13 15:48:08 +00:00
|
|
|
const Decl *TargetDecl =
|
|
|
|
|
OrigCallee.getAbstractInfo().getCalleeDecl().getDecl();
|
2015-11-23 22:04:44 +00:00
|
|
|
|
2009-10-23 08:22:42 +00:00
|
|
|
CalleeType = getContext().getCanonicalType(CalleeType);
|
|
|
|
|
|
2018-01-05 07:57:12 +00:00
|
|
|
auto PointeeType = cast<PointerType>(CalleeType)->getPointeeType();
|
2008-08-30 03:02:31 +00:00
|
|
|
|
2016-10-26 23:46:34 +00:00
|
|
|
CGCallee Callee = OrigCallee;
|
|
|
|
|
|
2014-11-07 22:29:38 +00:00
|
|
|
if (getLangOpts().CPlusPlus && SanOpts.has(SanitizerKind::Function) &&
|
2013-10-20 21:29:19 +00:00
|
|
|
(!TargetDecl || !isa<FunctionDecl>(TargetDecl))) {
|
|
|
|
|
if (llvm::Constant *PrefixSig =
|
|
|
|
|
CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) {
|
2014-07-17 18:46:27 +00:00
|
|
|
SanitizerScope SanScope(this);
|
2018-01-05 07:57:12 +00:00
|
|
|
// Remove any (C++17) exception specifications, to allow calling e.g. a
|
|
|
|
|
// noexcept function through a non-noexcept pointer.
|
|
|
|
|
auto ProtoTy =
|
|
|
|
|
getContext().getFunctionTypeWithExceptionSpec(PointeeType, EST_None);
|
2013-10-20 21:29:19 +00:00
|
|
|
llvm::Constant *FTRTTIConst =
|
2018-01-05 07:57:12 +00:00
|
|
|
CGM.GetAddrOfRTTIDescriptor(ProtoTy, /*ForEH=*/true);
|
2017-09-13 00:04:35 +00:00
|
|
|
llvm::Type *PrefixStructTyElems[] = {PrefixSig->getType(), Int32Ty};
|
2013-10-20 21:29:19 +00:00
|
|
|
llvm::StructType *PrefixStructTy = llvm::StructType::get(
|
|
|
|
|
CGM.getLLVMContext(), PrefixStructTyElems, /*isPacked=*/true);
|
|
|
|
|
|
2016-10-26 23:46:34 +00:00
|
|
|
llvm::Value *CalleePtr = Callee.getFunctionPointer();
|
|
|
|
|
|
2013-10-20 21:29:19 +00:00
|
|
|
llvm::Value *CalleePrefixStruct = Builder.CreateBitCast(
|
2016-10-26 23:46:34 +00:00
|
|
|
CalleePtr, llvm::PointerType::getUnqual(PrefixStructTy));
|
2013-10-20 21:29:19 +00:00
|
|
|
llvm::Value *CalleeSigPtr =
|
2015-04-04 21:07:17 +00:00
|
|
|
Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, 0, 0);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
llvm::Value *CalleeSig =
|
|
|
|
|
Builder.CreateAlignedLoad(CalleeSigPtr, getIntAlign());
|
2013-10-20 21:29:19 +00:00
|
|
|
llvm::Value *CalleeSigMatch = Builder.CreateICmpEQ(CalleeSig, PrefixSig);
|
|
|
|
|
|
|
|
|
|
llvm::BasicBlock *Cont = createBasicBlock("cont");
|
|
|
|
|
llvm::BasicBlock *TypeCheck = createBasicBlock("typecheck");
|
|
|
|
|
Builder.CreateCondBr(CalleeSigMatch, TypeCheck, Cont);
|
|
|
|
|
|
|
|
|
|
EmitBlock(TypeCheck);
|
|
|
|
|
llvm::Value *CalleeRTTIPtr =
|
2015-04-04 21:07:17 +00:00
|
|
|
Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, 0, 1);
|
2017-09-13 00:04:35 +00:00
|
|
|
llvm::Value *CalleeRTTIEncoded =
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Builder.CreateAlignedLoad(CalleeRTTIPtr, getPointerAlign());
|
2017-09-13 00:04:35 +00:00
|
|
|
llvm::Value *CalleeRTTI =
|
|
|
|
|
DecodeAddrUsedInPrologue(CalleePtr, CalleeRTTIEncoded);
|
2013-10-20 21:29:19 +00:00
|
|
|
llvm::Value *CalleeRTTIMatch =
|
|
|
|
|
Builder.CreateICmpEQ(CalleeRTTI, FTRTTIConst);
|
2018-08-09 21:08:08 +00:00
|
|
|
llvm::Constant *StaticData[] = {EmitCheckSourceLocation(E->getBeginLoc()),
|
|
|
|
|
EmitCheckTypeDescriptor(CalleeType)};
|
2014-11-11 22:03:54 +00:00
|
|
|
EmitCheck(std::make_pair(CalleeRTTIMatch, SanitizerKind::Function),
|
2019-05-02 06:40:33 +00:00
|
|
|
SanitizerHandler::FunctionTypeMismatch, StaticData,
|
|
|
|
|
{CalleePtr, CalleeRTTI, FTRTTIConst});
|
2013-10-20 21:29:19 +00:00
|
|
|
|
|
|
|
|
Builder.CreateBr(Cont);
|
|
|
|
|
EmitBlock(Cont);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-05 07:57:12 +00:00
|
|
|
const auto *FnType = cast<FunctionType>(PointeeType);
|
|
|
|
|
|
2015-09-10 02:17:40 +00:00
|
|
|
// If we are checking indirect calls and this call is indirect, check that the
|
|
|
|
|
// function pointer is a member of the bit set for the function type.
|
|
|
|
|
if (SanOpts.has(SanitizerKind::CFIICall) &&
|
|
|
|
|
(!TargetDecl || !isa<FunctionDecl>(TargetDecl))) {
|
|
|
|
|
SanitizerScope SanScope(this);
|
2016-01-16 00:31:22 +00:00
|
|
|
EmitSanitizerStatReport(llvm::SanStat_CFI_ICall);
|
2015-09-10 02:17:40 +00:00
|
|
|
|
2017-10-31 22:39:44 +00:00
|
|
|
llvm::Metadata *MD;
|
|
|
|
|
if (CGM.getCodeGenOpts().SanitizeCfiICallGeneralizePointers)
|
|
|
|
|
MD = CGM.CreateMetadataIdentifierGeneralized(QualType(FnType, 0));
|
|
|
|
|
else
|
|
|
|
|
MD = CGM.CreateMetadataIdentifierForType(QualType(FnType, 0));
|
|
|
|
|
|
2016-06-24 21:21:46 +00:00
|
|
|
llvm::Value *TypeId = llvm::MetadataAsValue::get(getLLVMContext(), MD);
|
2015-09-10 02:17:40 +00:00
|
|
|
|
2016-10-26 23:46:34 +00:00
|
|
|
llvm::Value *CalleePtr = Callee.getFunctionPointer();
|
|
|
|
|
llvm::Value *CastedCallee = Builder.CreateBitCast(CalleePtr, Int8PtrTy);
|
2016-06-24 21:21:46 +00:00
|
|
|
llvm::Value *TypeTest = Builder.CreateCall(
|
|
|
|
|
CGM.getIntrinsic(llvm::Intrinsic::type_test), {CastedCallee, TypeId});
|
2015-09-10 02:17:40 +00:00
|
|
|
|
2016-06-24 21:21:46 +00:00
|
|
|
auto CrossDsoTypeId = CGM.CreateCrossDsoCfiTypeId(MD);
|
2016-01-25 23:34:52 +00:00
|
|
|
llvm::Constant *StaticData[] = {
|
|
|
|
|
llvm::ConstantInt::get(Int8Ty, CFITCK_ICall),
|
2018-08-09 21:08:08 +00:00
|
|
|
EmitCheckSourceLocation(E->getBeginLoc()),
|
2016-01-25 23:34:52 +00:00
|
|
|
EmitCheckTypeDescriptor(QualType(FnType, 0)),
|
|
|
|
|
};
|
2016-06-24 21:21:46 +00:00
|
|
|
if (CGM.getCodeGenOpts().SanitizeCfiCrossDso && CrossDsoTypeId) {
|
|
|
|
|
EmitCfiSlowPathCheck(SanitizerKind::CFIICall, TypeTest, CrossDsoTypeId,
|
2016-01-25 23:34:52 +00:00
|
|
|
CastedCallee, StaticData);
|
2015-12-15 23:00:20 +00:00
|
|
|
} else {
|
2016-06-24 21:21:46 +00:00
|
|
|
EmitCheck(std::make_pair(TypeTest, SanitizerKind::CFIICall),
|
2016-12-12 16:18:40 +00:00
|
|
|
SanitizerHandler::CFICheckFail, StaticData,
|
2016-02-03 22:18:55 +00:00
|
|
|
{CastedCallee, llvm::UndefValue::get(IntPtrTy)});
|
2015-12-15 23:00:20 +00:00
|
|
|
}
|
2015-09-10 02:17:40 +00:00
|
|
|
}
|
|
|
|
|
|
2008-08-30 03:02:31 +00:00
|
|
|
CallArgList Args;
|
2014-12-12 23:41:25 +00:00
|
|
|
if (Chain)
|
|
|
|
|
Args.add(RValue::get(Builder.CreateBitCast(Chain, CGM.VoidPtrTy)),
|
|
|
|
|
CGM.getContext().VoidPtrTy);
|
2016-09-28 19:09:10 +00:00
|
|
|
|
|
|
|
|
// C++17 requires that we evaluate arguments to a call using assignment syntax
|
Switch to a different workaround for unimplementability of P0145R3 in MS ABIs.
Instead of ignoring the evaluation order rule, ignore the "destroy parameters
in reverse construction order" rule for the small number of problematic cases.
This only causes incorrect behavior in the rare case where both parameters to
an overloaded operator <<, >>, ->*, &&, ||, or comma are of class type with
non-trivial destructor, and the program is depending on those parameters being
destroyed in reverse construction order.
We could do a little better here by reversing the order of parameter
destruction for those functions (and reversing the argument evaluation order
for all direct calls, not just those with operator syntax), but that is not a
complete solution to the problem, as the same situation can be reached by an
indirect function call.
Approach reviewed off-line by rnk.
llvm-svn: 282777
2016-09-29 21:30:12 +00:00
|
|
|
// right-to-left, and that we evaluate arguments to certain other operators
|
|
|
|
|
// left-to-right. Note that we allow this to override the order dictated by
|
|
|
|
|
// the calling convention on the MS ABI, which means that parameter
|
|
|
|
|
// destruction order is not necessarily reverse construction order.
|
|
|
|
|
// FIXME: Revisit this based on C++ committee response to unimplementability.
|
|
|
|
|
EvaluationOrder Order = EvaluationOrder::Default;
|
|
|
|
|
if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
|
|
|
|
|
if (OCE->isAssignmentOp())
|
|
|
|
|
Order = EvaluationOrder::ForceRightToLeft;
|
|
|
|
|
else {
|
|
|
|
|
switch (OCE->getOperator()) {
|
|
|
|
|
case OO_LessLess:
|
|
|
|
|
case OO_GreaterGreater:
|
|
|
|
|
case OO_AmpAmp:
|
|
|
|
|
case OO_PipePipe:
|
|
|
|
|
case OO_Comma:
|
|
|
|
|
case OO_ArrowStar:
|
|
|
|
|
Order = EvaluationOrder::ForceLeftToRight;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-09-28 19:09:10 +00:00
|
|
|
|
2015-07-21 18:37:18 +00:00
|
|
|
EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), E->arguments(),
|
Switch to a different workaround for unimplementability of P0145R3 in MS ABIs.
Instead of ignoring the evaluation order rule, ignore the "destroy parameters
in reverse construction order" rule for the small number of problematic cases.
This only causes incorrect behavior in the rare case where both parameters to
an overloaded operator <<, >>, ->*, &&, ||, or comma are of class type with
non-trivial destructor, and the program is depending on those parameters being
destroyed in reverse construction order.
We could do a little better here by reversing the order of parameter
destruction for those functions (and reversing the argument evaluation order
for all direct calls, not just those with operator syntax), but that is not a
complete solution to the problem, as the same situation can be reached by an
indirect function call.
Approach reviewed off-line by rnk.
llvm-svn: 282777
2016-09-29 21:30:12 +00:00
|
|
|
E->getDirectCallee(), /*ParamsToSkip*/ 0, Order);
|
2008-08-30 03:02:31 +00:00
|
|
|
|
2014-12-12 23:41:25 +00:00
|
|
|
const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeFreeFunctionCall(
|
2019-07-16 04:46:31 +00:00
|
|
|
Args, FnType, /*ChainCall=*/Chain);
|
2011-09-21 08:08:30 +00:00
|
|
|
|
|
|
|
|
// C99 6.5.2.2p6:
|
|
|
|
|
// If the expression that denotes the called function has a type
|
|
|
|
|
// that does not include a prototype, [the default argument
|
|
|
|
|
// promotions are performed]. If the number of arguments does not
|
|
|
|
|
// equal the number of parameters, the behavior is undefined. If
|
|
|
|
|
// the function is defined with a type that includes a prototype,
|
|
|
|
|
// and either the prototype ends with an ellipsis (, ...) or the
|
|
|
|
|
// types of the arguments after promotion are not compatible with
|
|
|
|
|
// the types of the parameters, the behavior is undefined. If the
|
|
|
|
|
// function is defined with a type that does not include a
|
|
|
|
|
// prototype, and the types of the arguments after promotion are
|
|
|
|
|
// not compatible with those of the parameters after promotion,
|
|
|
|
|
// the behavior is undefined [except in some trivial cases].
|
|
|
|
|
// That is, in the general case, we should assume that a call
|
|
|
|
|
// through an unprototyped function type works like a *non-variadic*
|
|
|
|
|
// call. The way we make this work is to cast to the exact type
|
|
|
|
|
// of the promoted arguments.
|
2014-12-12 23:41:25 +00:00
|
|
|
//
|
|
|
|
|
// Chain calls use this same code path to add the invisible chain parameter
|
|
|
|
|
// to the function type.
|
|
|
|
|
if (isa<FunctionNoProtoType>(FnType) || Chain) {
|
2012-02-17 03:33:10 +00:00
|
|
|
llvm::Type *CalleeTy = getTypes().GetFunctionType(FnInfo);
|
2020-04-14 18:13:41 +02:00
|
|
|
int AS = Callee.getFunctionPointer()->getType()->getPointerAddressSpace();
|
|
|
|
|
CalleeTy = CalleeTy->getPointerTo(AS);
|
2016-10-26 23:46:34 +00:00
|
|
|
|
|
|
|
|
llvm::Value *CalleePtr = Callee.getFunctionPointer();
|
|
|
|
|
CalleePtr = Builder.CreateBitCast(CalleePtr, CalleeTy, "callee.knr.cast");
|
|
|
|
|
Callee.setFunctionPointer(CalleePtr);
|
2011-09-21 08:08:30 +00:00
|
|
|
}
|
|
|
|
|
|
2019-06-27 06:44:44 +00:00
|
|
|
llvm::CallBase *CallOrInvoke = nullptr;
|
|
|
|
|
RValue Call = EmitCall(FnInfo, Callee, ReturnValue, Args, &CallOrInvoke,
|
|
|
|
|
E->getExprLoc());
|
|
|
|
|
|
|
|
|
|
// Generate function declaration DISuprogram in order to be used
|
|
|
|
|
// in debug info about call sites.
|
|
|
|
|
if (CGDebugInfo *DI = getDebugInfo()) {
|
|
|
|
|
if (auto *CalleeDecl = dyn_cast_or_null<FunctionDecl>(TargetDecl))
|
|
|
|
|
DI->EmitFuncDeclForCallSite(CallOrInvoke, QualType(FnType, 0),
|
|
|
|
|
CalleeDecl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Call;
|
2008-08-23 03:46:30 +00:00
|
|
|
}
|
2009-10-22 22:57:31 +00:00
|
|
|
|
2009-10-28 17:39:19 +00:00
|
|
|
LValue CodeGenFunction::
|
|
|
|
|
EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E) {
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Address BaseAddr = Address::invalid();
|
|
|
|
|
if (E->getOpcode() == BO_PtrMemI) {
|
|
|
|
|
BaseAddr = EmitPointerWithAlignment(E->getLHS());
|
|
|
|
|
} else {
|
2019-12-03 15:17:01 -08:00
|
|
|
BaseAddr = EmitLValue(E->getLHS()).getAddress(*this);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
}
|
2010-08-31 21:07:20 +00:00
|
|
|
|
2009-11-18 05:01:17 +00:00
|
|
|
llvm::Value *OffsetV = EmitScalarExpr(E->getRHS());
|
2020-01-11 15:33:25 +00:00
|
|
|
const auto *MPT = E->getRHS()->getType()->castAs<MemberPointerType>();
|
2010-08-31 21:07:20 +00:00
|
|
|
|
2017-05-18 17:07:11 +00:00
|
|
|
LValueBaseInfo BaseInfo;
|
2017-10-13 16:38:32 +00:00
|
|
|
TBAAAccessInfo TBAAInfo;
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
Address MemberAddr =
|
2017-10-13 16:38:32 +00:00
|
|
|
EmitCXXMemberDataPointerAddress(E, BaseAddr, OffsetV, MPT, &BaseInfo,
|
|
|
|
|
&TBAAInfo);
|
2010-08-31 21:07:20 +00:00
|
|
|
|
2017-10-13 16:38:32 +00:00
|
|
|
return MakeAddrLValue(MemberAddr, MPT->getPointeeType(), BaseInfo, TBAAInfo);
|
2009-10-22 22:57:31 +00:00
|
|
|
}
|
2011-10-11 02:20:01 +00:00
|
|
|
|
2013-03-07 21:37:08 +00:00
|
|
|
/// Given the address of a temporary variable, produce an r-value of
|
|
|
|
|
/// its 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 08:05:57 +00:00
|
|
|
RValue CodeGenFunction::convertTempToRValue(Address addr,
|
2013-10-02 02:29:49 +00:00
|
|
|
QualType type,
|
|
|
|
|
SourceLocation loc) {
|
2017-10-10 09:39:32 +00:00
|
|
|
LValue lvalue = MakeAddrLValue(addr, type, AlignmentSource::Decl);
|
2013-03-07 21:37:08 +00:00
|
|
|
switch (getEvaluationKind(type)) {
|
|
|
|
|
case TEK_Complex:
|
2013-10-02 02:29:49 +00:00
|
|
|
return RValue::getComplex(EmitLoadOfComplex(lvalue, loc));
|
2013-03-07 21:37:08 +00:00
|
|
|
case TEK_Aggregate:
|
2019-12-03 15:17:01 -08:00
|
|
|
return lvalue.asAggregateRValue(*this);
|
2013-03-07 21:37:08 +00:00
|
|
|
case TEK_Scalar:
|
2013-10-02 02:29:49 +00:00
|
|
|
return RValue::get(EmitLoadOfScalar(lvalue, loc));
|
2013-03-07 21:37:08 +00:00
|
|
|
}
|
|
|
|
|
llvm_unreachable("bad evaluation kind");
|
2011-10-11 02:20:01 +00:00
|
|
|
}
|
|
|
|
|
|
2012-04-10 08:23:07 +00:00
|
|
|
void CodeGenFunction::SetFPAccuracy(llvm::Value *Val, float Accuracy) {
|
2011-10-27 19:19:51 +00:00
|
|
|
assert(Val->getType()->isFPOrFPVectorTy());
|
2012-04-10 08:23:07 +00:00
|
|
|
if (Accuracy == 0.0 || !isa<llvm::Instruction>(Val))
|
2011-10-27 19:19:51 +00:00
|
|
|
return;
|
|
|
|
|
|
2012-04-16 16:29:47 +00:00
|
|
|
llvm::MDBuilder MDHelper(getLLVMContext());
|
|
|
|
|
llvm::MDNode *Node = MDHelper.createFPMath(Accuracy);
|
2011-10-27 19:19:51 +00:00
|
|
|
|
2012-04-14 12:37:26 +00:00
|
|
|
cast<llvm::Instruction>(Val)->setMetadata(llvm::LLVMContext::MD_fpmath, Node);
|
2011-10-27 19:19:51 +00:00
|
|
|
}
|
2011-11-06 09:01:30 +00:00
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
struct LValueOrRValue {
|
|
|
|
|
LValue LV;
|
|
|
|
|
RValue RV;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static LValueOrRValue emitPseudoObjectExpr(CodeGenFunction &CGF,
|
|
|
|
|
const PseudoObjectExpr *E,
|
|
|
|
|
bool forLValue,
|
|
|
|
|
AggValueSlot slot) {
|
2013-01-12 19:30:44 +00:00
|
|
|
SmallVector<CodeGenFunction::OpaqueValueMappingData, 4> opaques;
|
2011-11-06 09:01:30 +00:00
|
|
|
|
|
|
|
|
// Find the result expression, if any.
|
|
|
|
|
const Expr *resultExpr = E->getResultExpr();
|
|
|
|
|
LValueOrRValue result;
|
|
|
|
|
|
|
|
|
|
for (PseudoObjectExpr::const_semantics_iterator
|
|
|
|
|
i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
|
|
|
|
|
const Expr *semantic = *i;
|
|
|
|
|
|
|
|
|
|
// If this semantic expression is an opaque value, bind it
|
|
|
|
|
// to the result of its source expression.
|
2014-05-09 00:08:36 +00:00
|
|
|
if (const auto *ov = dyn_cast<OpaqueValueExpr>(semantic)) {
|
2018-03-20 01:47:58 +00:00
|
|
|
// Skip unique OVEs.
|
|
|
|
|
if (ov->isUnique()) {
|
|
|
|
|
assert(ov != resultExpr &&
|
|
|
|
|
"A unique OVE cannot be used as the result expression");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2011-11-06 09:01:30 +00:00
|
|
|
|
|
|
|
|
// If this is the result expression, we may need to evaluate
|
|
|
|
|
// directly into the slot.
|
|
|
|
|
typedef CodeGenFunction::OpaqueValueMappingData OVMA;
|
|
|
|
|
OVMA opaqueData;
|
|
|
|
|
if (ov == resultExpr && ov->isRValue() && !forLValue &&
|
2013-03-07 21:37:08 +00:00
|
|
|
CodeGenFunction::hasAggregateEvaluationKind(ov->getType())) {
|
2011-11-06 09:01:30 +00:00
|
|
|
CGF.EmitAggExpr(ov->getSourceExpr(), slot);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 08:05:57 +00:00
|
|
|
LValue LV = CGF.MakeAddrLValue(slot.getAddress(), ov->getType(),
|
2017-10-10 09:39:32 +00:00
|
|
|
AlignmentSource::Decl);
|
2011-11-06 09:01:30 +00:00
|
|
|
opaqueData = OVMA::bind(CGF, ov, LV);
|
|
|
|
|
result.RV = slot.asRValue();
|
|
|
|
|
|
|
|
|
|
// Otherwise, emit as normal.
|
|
|
|
|
} else {
|
|
|
|
|
opaqueData = OVMA::bind(CGF, ov, ov->getSourceExpr());
|
|
|
|
|
|
|
|
|
|
// If this is the result, also evaluate the result now.
|
|
|
|
|
if (ov == resultExpr) {
|
|
|
|
|
if (forLValue)
|
|
|
|
|
result.LV = CGF.EmitLValue(ov);
|
|
|
|
|
else
|
|
|
|
|
result.RV = CGF.EmitAnyExpr(ov, slot);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
opaques.push_back(opaqueData);
|
|
|
|
|
|
|
|
|
|
// Otherwise, if the expression is the result, evaluate it
|
|
|
|
|
// and remember the result.
|
|
|
|
|
} else if (semantic == resultExpr) {
|
|
|
|
|
if (forLValue)
|
|
|
|
|
result.LV = CGF.EmitLValue(semantic);
|
|
|
|
|
else
|
|
|
|
|
result.RV = CGF.EmitAnyExpr(semantic, slot);
|
|
|
|
|
|
|
|
|
|
// Otherwise, evaluate the expression in an ignored context.
|
|
|
|
|
} else {
|
|
|
|
|
CGF.EmitIgnoredExpr(semantic);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Unbind all the opaques now.
|
|
|
|
|
for (unsigned i = 0, e = opaques.size(); i != e; ++i)
|
|
|
|
|
opaques[i].unbind(CGF);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RValue CodeGenFunction::EmitPseudoObjectRValue(const PseudoObjectExpr *E,
|
|
|
|
|
AggValueSlot slot) {
|
|
|
|
|
return emitPseudoObjectExpr(*this, E, false, slot).RV;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LValue CodeGenFunction::EmitPseudoObjectLValue(const PseudoObjectExpr *E) {
|
|
|
|
|
return emitPseudoObjectExpr(*this, E, true, AggValueSlot::ignored()).LV;
|
|
|
|
|
}
|