| |
@@ -0,0 +1,138 @@
|
| |
+ From f2ccdd2700174c717dc55a0f4c3f5a91ae73ff42 Mon Sep 17 00:00:00 2001
|
| |
+ From: Yonghong Song <yhs@fb.com>
|
| |
+ Date: Fri, 2 Aug 2019 21:28:28 +0000
|
| |
+ Subject: [PATCH] [BPF] annotate DIType metadata for builtin
|
| |
+ preseve_array_access_index()
|
| |
+
|
| |
+ Previously, debuginfo types are annotated to
|
| |
+ IR builtin preserve_struct_access_index() and
|
| |
+ preserve_union_access_index(), but not
|
| |
+ preserve_array_access_index(). The debug info
|
| |
+ is useful to identify the root type name which
|
| |
+ later will be used for type comparison.
|
| |
+
|
| |
+ For user access without explicit type conversions,
|
| |
+ the previous scheme works as we can ignore intermediate
|
| |
+ compiler generated type conversions (e.g., from union types to
|
| |
+ union members) and still generate correct access index string.
|
| |
+
|
| |
+ The issue comes with user explicit type conversions, e.g.,
|
| |
+ converting an array to a structure like below:
|
| |
+ struct t { int a; char b[40]; };
|
| |
+ struct p { int c; int d; };
|
| |
+ struct t *var = ...;
|
| |
+ ... __builtin_preserve_access_index(&(((struct p *)&(var->b[0]))->d)) ...
|
| |
+ Although BPF backend can derive the type of &(var->b[0]),
|
| |
+ explicit type annotation make checking more consistent
|
| |
+ and less error prone.
|
| |
+
|
| |
+ Another benefit is for multiple dimension array handling.
|
| |
+ For example,
|
| |
+ struct p { int c; int d; } g[8][9][10];
|
| |
+ ... __builtin_preserve_access_index(&g[2][3][4].d) ...
|
| |
+ It would be possible to calculate the number of "struct p"'s
|
| |
+ before accessing its member "d" if array debug info is
|
| |
+ available as it contains each dimension range.
|
| |
+
|
| |
+ This patch enables to annotate IR builtin preserve_array_access_index()
|
| |
+ with proper debuginfo type. The unit test case and language reference
|
| |
+ is updated as well.
|
| |
+
|
| |
+ Signed-off-by: Yonghong Song <yhs@fb.com>
|
| |
+
|
| |
+ Differential Revision: https://reviews.llvm.org/D65664
|
| |
+
|
| |
+ llvm-svn: 367724
|
| |
+ (cherry picked from commit d0ea05d5eff475a27a5d3bbe4d9fd389935f9cb2)
|
| |
+
|
| |
+ Also added back
|
| |
+ Value *CreatePreserveArrayAccessIndex(Value *Base, unsigned Dimension,
|
| |
+ unsigned LastIndex);
|
| |
+
|
| |
+ To avoid breaking the ABI.
|
| |
+ ---
|
| |
+ clang/lib/CodeGen/CGExpr.cpp | 12 ++++++++---
|
| |
+ .../CodeGen/builtin-preserve-access-index-array.c | 18 +++++++++++++++++
|
| |
+ clang/test/CodeGen/builtin-preserve-access-index.c | 23 +++++++++++-----------
|
| |
+ llvm/docs/LangRef.rst | 4 ++++
|
| |
+ llvm/include/llvm/IR/IRBuilder.h | 13 ++++++++++--
|
| |
+ llvm/test/CodeGen/BPF/CORE/intrinsic-array.ll | 2 +-
|
| |
+ 6 files changed, 55 insertions(+), 17 deletions(-)
|
| |
+ create mode 100644 clang/test/CodeGen/builtin-preserve-access-index-array.c
|
| |
+
|
| |
+ diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
|
| |
+ index 87e8a55..b63e3af 100644
|
| |
+ --- a/llvm/docs/LangRef.rst
|
| |
+ +++ b/llvm/docs/LangRef.rst
|
| |
+ @@ -17349,6 +17349,10 @@ based on array base ``base``, array dimension ``dim`` and the last access index
|
| |
+ into the array. The return type ``ret_type`` is a pointer type to the array element.
|
| |
+ The array ``dim`` and ``index`` are preserved which is more robust than
|
| |
+ getelementptr instruction which may be subject to compiler transformation.
|
| |
+ +The ``llvm.preserve.access.index`` type of metadata is attached to this call instruction
|
| |
+ +to provide array or pointer debuginfo type.
|
| |
+ +The metadata is a ``DICompositeType`` or ``DIDerivedType`` representing the
|
| |
+ +debuginfo version of ``type``.
|
| |
+
|
| |
+ Arguments:
|
| |
+ """"""""""
|
| |
+ diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h
|
| |
+ index a74364d..c2fa9a3 100644
|
| |
+ --- a/llvm/include/llvm/IR/IRBuilder.h
|
| |
+ +++ b/llvm/include/llvm/IR/IRBuilder.h
|
| |
+ @@ -2455,6 +2455,11 @@ public:
|
| |
+
|
| |
+ Value *CreatePreserveArrayAccessIndex(Value *Base, unsigned Dimension,
|
| |
+ unsigned LastIndex) {
|
| |
+ + return CreatePreserveArrayAccessIndex(Base, Dimension, LastIndex, nullptr);
|
| |
+ + }
|
| |
+ +
|
| |
+ + Value *CreatePreserveArrayAccessIndex(Value *Base, unsigned Dimension,
|
| |
+ + unsigned LastIndex, MDNode *DbgInfo) {
|
| |
+ assert(isa<PointerType>(Base->getType()) &&
|
| |
+ "Invalid Base ptr type for preserve.array.access.index.");
|
| |
+ auto *BaseType = Base->getType();
|
| |
+ @@ -2476,6 +2481,8 @@ public:
|
| |
+ Value *DimV = getInt32(Dimension);
|
| |
+ CallInst *Fn =
|
| |
+ CreateCall(FnPreserveArrayAccessIndex, {Base, DimV, LastIndexV});
|
| |
+ + if (DbgInfo)
|
| |
+ + Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo);
|
| |
+
|
| |
+ return Fn;
|
| |
+ }
|
| |
+ @@ -2493,7 +2500,8 @@ public:
|
| |
+ Value *DIIndex = getInt32(FieldIndex);
|
| |
+ CallInst *Fn =
|
| |
+ CreateCall(FnPreserveUnionAccessIndex, {Base, DIIndex});
|
| |
+ - Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo);
|
| |
+ + if (DbgInfo)
|
| |
+ + Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo);
|
| |
+
|
| |
+ return Fn;
|
| |
+ }
|
| |
+ @@ -2516,7 +2524,8 @@ public:
|
| |
+ Value *DIIndex = getInt32(FieldIndex);
|
| |
+ CallInst *Fn = CreateCall(FnPreserveStructAccessIndex,
|
| |
+ {Base, GEPIndex, DIIndex});
|
| |
+ - Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo);
|
| |
+ + if (DbgInfo)
|
| |
+ + Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo);
|
| |
+
|
| |
+ return Fn;
|
| |
+ }
|
| |
+ diff --git a/llvm/test/CodeGen/BPF/CORE/intrinsic-array.ll b/llvm/test/CodeGen/BPF/CORE/intrinsic-array.ll
|
| |
+ index adbcb9f..fe2c196 100644
|
| |
+ --- a/llvm/test/CodeGen/BPF/CORE/intrinsic-array.ll
|
| |
+ +++ b/llvm/test/CodeGen/BPF/CORE/intrinsic-array.ll
|
| |
+ @@ -14,7 +14,7 @@
|
| |
+ define dso_local i32 @test(%struct.s* %arg) local_unnamed_addr #0 !dbg !7 {
|
| |
+ entry:
|
| |
+ call void @llvm.dbg.value(metadata %struct.s* %arg, metadata !17, metadata !DIExpression()), !dbg !18
|
| |
+ - %0 = tail call %struct.s* @llvm.preserve.array.access.index.p0s_struct.ss.p0s_struct.ss(%struct.s* %arg, i32 0, i32 2), !dbg !19
|
| |
+ + %0 = tail call %struct.s* @llvm.preserve.array.access.index.p0s_struct.ss.p0s_struct.ss(%struct.s* %arg, i32 0, i32 2), !dbg !19, !llvm.preserve.access.index !11
|
| |
+ %1 = tail call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.ss(%struct.s* %0, i32 1, i32 1), !dbg !19, !llvm.preserve.access.index !12
|
| |
+ %2 = bitcast i32* %1 to i8*, !dbg !19
|
| |
+ %call = tail call i32 @get_value(i8* %2) #4, !dbg !20
|
| |
+ --
|
| |
+ 1.8.3.1
|
| |
+
|
| |