[clang] 6c412b6 - [BPF] Add a few new insns under cpu=v4

2023-07-26 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2023-07-26T08:37:30-07:00
New Revision: 6c412b6c6faa2dabd8602d35d3f5e796fb1daf80

URL: 
https://github.com/llvm/llvm-project/commit/6c412b6c6faa2dabd8602d35d3f5e796fb1daf80
DIFF: 
https://github.com/llvm/llvm-project/commit/6c412b6c6faa2dabd8602d35d3f5e796fb1daf80.diff

LOG: [BPF] Add a few new insns under cpu=v4

In [1], a few new insns are proposed to expand BPF ISA to
  . fixing the limitation of existing insn (e.g., 16bit jmp offset)
  . adding new insns which may improve code quality
(sign_ext_ld, sign_ext_mov, st)
  . feature complete (sdiv, smod)
  . better user experience (bswap)

This patch implemented insn encoding for
  . sign-extended load
  . sign-extended mov
  . sdiv/smod
  . bswap insns
  . unconditional jump with 32bit offset

The new bswap insns are generated under cpu=v4 for __builtin_bswap.
For cpu=v3 or earlier, for __builtin_bswap, be or le insns are generated
which is not intuitive for the user.

To support 32-bit branch offset, a 32-bit ja (JMPL) insn is implemented.
For conditional branch which is beyond 16-bit offset, llvm will do
some transformation 'cond_jmp' -> 'cond_jmp + jmpl' to simulate 32bit
conditional jmp. See BPFMIPeephole.cpp for details. The algorithm is
hueristic based. I have tested bpf selftest pyperf600 with unroll account
600 which can indeed generate 32-bit jump insn, e.g.,
13:   06 00 00 00 9b cd 00 00 gotol +0xcd9b 

Eduard is working on to add 'st' insn to cpu=v4.

A list of llc flags:
  disable-ldsx, disable-movsx, disable-bswap,
  disable-sdiv-smod, disable-gotol
can be used to disable a particular insn for cpu v4.
For example, user can do:
  llc -march=bpf -mcpu=v4 -disable-movsx t.ll
to enable cpu v4 without movsx insns.

References:
  [1] https://lore.kernel.org/bpf/4bfe98be-5333-1c7e-2f6d-42486c8ec...@meta.com/

Differential Revision: https://reviews.llvm.org/D144829

Added: 
llvm/lib/Target/BPF/MCTargetDesc/BPFMCFixups.h
llvm/test/CodeGen/BPF/assembler-disassembler-v4.s
llvm/test/CodeGen/BPF/bswap.ll
llvm/test/CodeGen/BPF/gotol.ll
llvm/test/CodeGen/BPF/ldsx.ll
llvm/test/CodeGen/BPF/movsx.ll
llvm/test/CodeGen/BPF/sdiv_smod.ll

Modified: 
clang/lib/Basic/Targets/BPF.cpp
clang/lib/Basic/Targets/BPF.h
clang/test/Misc/target-invalid-cpu-note.c
llvm/lib/Target/BPF/AsmParser/BPFAsmParser.cpp
llvm/lib/Target/BPF/BPF.td
llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp
llvm/lib/Target/BPF/BPFISelLowering.cpp
llvm/lib/Target/BPF/BPFISelLowering.h
llvm/lib/Target/BPF/BPFInstrFormats.td
llvm/lib/Target/BPF/BPFInstrInfo.td
llvm/lib/Target/BPF/BPFMIPeephole.cpp
llvm/lib/Target/BPF/BPFMISimplifyPatchable.cpp
llvm/lib/Target/BPF/BPFSubtarget.cpp
llvm/lib/Target/BPF/BPFSubtarget.h
llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp
llvm/lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp
llvm/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.cpp
llvm/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp
llvm/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp

Removed: 




diff  --git a/clang/lib/Basic/Targets/BPF.cpp b/clang/lib/Basic/Targets/BPF.cpp
index c9095c28aec274..d6288d2e0d0e17 100644
--- a/clang/lib/Basic/Targets/BPF.cpp
+++ b/clang/lib/Basic/Targets/BPF.cpp
@@ -32,7 +32,7 @@ void BPFTargetInfo::getTargetDefines(const LangOptions ,
 }
 
 static constexpr llvm::StringLiteral ValidCPUNames[] = {"generic", "v1", "v2",
-"v3", "probe"};
+"v3", "v4", "probe"};
 
 bool BPFTargetInfo::isValidCPUName(StringRef Name) const {
   return llvm::is_contained(ValidCPUNames, Name);

diff  --git a/clang/lib/Basic/Targets/BPF.h b/clang/lib/Basic/Targets/BPF.h
index 8a9227bca34c69..489f29fc4fead3 100644
--- a/clang/lib/Basic/Targets/BPF.h
+++ b/clang/lib/Basic/Targets/BPF.h
@@ -106,7 +106,7 @@ class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public 
TargetInfo {
   void fillValidCPUList(SmallVectorImpl ) const override;
 
   bool setCPU(const std::string ) override {
-if (Name == "v3") {
+if (Name == "v3" || Name == "v4") {
   HasAlu32 = true;
 }
 

diff  --git a/clang/test/Misc/target-invalid-cpu-note.c 
b/clang/test/Misc/target-invalid-cpu-note.c
index cd1b0bc157cc9f..5782ae9e4a0a40 100644
--- a/clang/test/Misc/target-invalid-cpu-note.c
+++ b/clang/test/Misc/target-invalid-cpu-note.c
@@ -73,7 +73,7 @@
 
 // RUN: not %clang_cc1 -triple bpf--- -target-cpu not-a-cpu -fsyntax-only %s 
2>&1 | FileCheck %s --check-prefix BPF
 // BPF: error: unknown target CPU 'not-a-cpu'
-// BPF-NEXT: note: valid target CPU values are: generic, v1, v2, v3, probe{{$}}
+// BPF-NEXT: note: valid target CPU values are: generic, v1, v2, v3, v4, 
probe{{$}}
 
 // RUN: not %clang_cc1 -triple avr--- -target-cpu not-a-cpu -fsyntax-only %s 
2>&1 | FileCheck %s --check-prefix AVR
 // 

[clang] 3060304 - [Clang][BPF] Type print btf_type_tag properly

2023-05-08 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2023-05-08T07:41:27-07:00
New Revision: 3060304906f08f933672f0a30cc57d5f09766444

URL: 
https://github.com/llvm/llvm-project/commit/3060304906f08f933672f0a30cc57d5f09766444
DIFF: 
https://github.com/llvm/llvm-project/commit/3060304906f08f933672f0a30cc57d5f09766444.diff

LOG: [Clang][BPF] Type print btf_type_tag properly

When running bcc tool execsnoop ([1]) which is built with latest llvm,
I hit the following error:
  $ sudo ./execsnoop.py
  /virtual/main.c:99:157: error: expected ')'
data.ppid = ({ typeof(pid_t) _val; __builtin_memset(&_val, 0, 
sizeof(_val)); bpf_probe_read(&_val, sizeof(_val),
   (void *)&({ typeof(struct task_struct  btf_type_tag(rcu)*) _val; 
__builtin_memset(&_val, 0, sizeof(_val));
  ^
bpf_probe_read(&_val, sizeof(_val), (void *)>real_parent); _val; 
})->tgid); _val; });

The failure reason is due to that the bcc rewriter printed type like
  struct task_struct  btf_type_tag(rcu)*
where the compiler cannot recognize what 'btf_type_tag(rcu)' is.

The above type is printed in [2] by UnaryOperator->getType().getAsString() 
(from clang)
in function ProbeVisitor::VisitUnaryOperator.

The original source type looks like ([3])
  struct task_struct {
...
struct task_struct __rcu*real_parent;
...
  }
  where '__rcu' is a macro expanding to '__attribute__((btf_type_tag("rcu")))'.

Let us print btf_type_tag properly in clang so bcc tools and broader type 
printing
will work properly.

With this patch, the above rewrited source code looks like
data.ppid = ({ typeof(pid_t) _val; __builtin_memset(&_val, 0, 
sizeof(_val)); bpf_probe_read(&_val, sizeof(_val),
   (void *)&({ typeof(struct task_struct  
__attribute__((btf_type_tag("rcu")))*) _val; __builtin_memset(&_val, 0, 
sizeof(_val));
bpf_probe_read(&_val, sizeof(_val), (void *)>real_parent); _val; 
})->tgid); _val; });

and execsnoop.py tool can run properly.

  [1] https://github.com/iovisor/bcc/blob/master/tools/exitsnoop.py
  [2] 
https://github.com/iovisor/bcc/blob/master/src/cc/frontends/clang/b_frontend_action.cc
  [3] https://github.com/torvalds/linux/blob/master/include/linux/sched.h

Differential Revision: https://reviews.llvm.org/D150017

Added: 
clang/test/AST/ast-dump-bpf-attr.c

Modified: 
clang/lib/AST/TypePrinter.cpp
clang/test/Sema/attr-btf_type_tag.c
clang/test/SemaCXX/sugar-common-types.cpp

Removed: 




diff  --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 408c7caa16c93..02e0793f5cb16 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1845,7 +1845,7 @@ void TypePrinter::printAttributedAfter(const 
AttributedType *T,
 void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T,
   raw_ostream ) {
   printBefore(T->getWrappedType(), OS);
-  OS << " btf_type_tag(" << T->getAttr()->getBTFTypeTag() << ")";
+  OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << 
"\")))";
 }
 
 void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,

diff  --git a/clang/test/AST/ast-dump-bpf-attr.c 
b/clang/test/AST/ast-dump-bpf-attr.c
new file mode 100644
index 0..8899cecbb6e9f
--- /dev/null
+++ b/clang/test/AST/ast-dump-bpf-attr.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -triple bpf-pc-linux-gnu -ast-dump  %s \
+// RUN: | FileCheck --strict-whitespace %s
+
+int __attribute__((btf_type_tag("rcu"))) * g;
+// CHECK: VarDecl{{.*}}g 'int  __attribute__((btf_type_tag("rcu")))*'

diff  --git a/clang/test/Sema/attr-btf_type_tag.c 
b/clang/test/Sema/attr-btf_type_tag.c
index f7ba29b0aa657..a3ef404f38238 100644
--- a/clang/test/Sema/attr-btf_type_tag.c
+++ b/clang/test/Sema/attr-btf_type_tag.c
@@ -28,8 +28,8 @@ int __tag4 * __tag5 * __tag6 *foo1(struct t __tag1 * __tag2 * 
__tag3 *a1) {
 int g1 = _Generic((int *)0, int __tag1 *: 0);
 int g2 = _Generic((int __tag1 *)0, int *: 0);
 int g3 = _Generic(0,
-  int __tag1 * : 0, // expected-note {{compatible type 'int  
btf_type_tag(tag1)*' (aka 'int *') specified here}}
-  int * : 0, // expected-error {{type 'int *' in generic 
association compatible with previously specified type 'int  
btf_type_tag(tag1)*' (aka 'int *')}}
+  int __tag1 * : 0, // expected-note {{compatible type 'int  
__attribute__((btf_type_tag("tag1")))*' (aka 'int *') specified here}}
+  int * : 0, // expected-error {{type 'int *' in generic 
association compatible with previously specified type 'int  
__attribute__((btf_type_tag("tag1")))*' (aka 'int *')}}
   default : 0);
 
 // The btf_type_tag attribute will be ignored during overloadable type matching

diff  --git a/clang/test/SemaCXX/sugar-common-types.cpp 
b/clang/test/SemaCXX/sugar-common-types.cpp
index 

[clang] 183d075 - [BPF][Clang] Fix func argument pattern in bpf-stack-protector test

2023-01-21 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2023-01-21T22:33:15-08:00
New Revision: 183d075055c591dedead7ece972f1bdea611aa3b

URL: 
https://github.com/llvm/llvm-project/commit/183d075055c591dedead7ece972f1bdea611aa3b
DIFF: 
https://github.com/llvm/llvm-project/commit/183d075055c591dedead7ece972f1bdea611aa3b.diff

LOG: [BPF][Clang] Fix func argument pattern in bpf-stack-protector test

Commit 56b038f887f3("[BPF][clang] Ignore stack protector options for BPF
target") added a test for its corresponding functionality.
Douglas Yung found that the test will fail with the release build
buildbot due to different func argument patterns (from %msg
to %0). This patch fixed the issue by using pattern [0-9a-z]+
which allows both %msg and %0.

Added: 


Modified: 
clang/test/CodeGen/bpf-stack-protector.c

Removed: 




diff  --git a/clang/test/CodeGen/bpf-stack-protector.c 
b/clang/test/CodeGen/bpf-stack-protector.c
index a005bb96ff1ed..c17af890eac23 100644
--- a/clang/test/CodeGen/bpf-stack-protector.c
+++ b/clang/test/CodeGen/bpf-stack-protector.c
@@ -24,7 +24,7 @@ char *strcpy(char *s1, const char *s2);
 //  STRONG: warning: ignoring '-fstack-protector-strong'
 // COMMON-SAME: option as it is not currently supported for target 'bpf'
 
-// COMMON: define {{.*}}void @test1(ptr noundef %msg) #[[A:.*]] {
+// COMMON: define {{.*}}void @test1(ptr noundef %{{[0-9a-z]+}}) #[[A:.*]] {
 void test1(const char *msg) {
   char a[strlen(msg) + 1];
   strcpy(a, msg);



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 56b038f - [BPF][clang] Ignore stack protector options for BPF target

2023-01-20 Thread Yonghong Song via cfe-commits

Author: Eduard Zingerman
Date: 2023-01-20T15:12:43-08:00
New Revision: 56b038f887f37f69afac2d3abe02b46dcb9305ec

URL: 
https://github.com/llvm/llvm-project/commit/56b038f887f37f69afac2d3abe02b46dcb9305ec
DIFF: 
https://github.com/llvm/llvm-project/commit/56b038f887f37f69afac2d3abe02b46dcb9305ec.diff

LOG: [BPF][clang] Ignore stack protector options for BPF target

Stack protector builtin functions are not implemented for BPF target,
thus compiling programs with one of the following options would result
in an error:
  -fstack-protector
  -fstack-protector-all
  -fstack-protector-strong

This commit adds logic to ignore these options for BPF target.
Searching through DiagnosticDriverKinds.td shows that all messages for
such kind of behavior are implemented as warnings, this commit follows
the suit.

Here is an example of the diagnostic message:
  clang-16: warning: ignoring '-fstack-protector' option as it is not currently 
supported for target 'bpf' [-Woption-ignored]

Differential Revision: https://reviews.llvm.org/D142046

Added: 
clang/test/CodeGen/bpf-stack-protector.c

Modified: 
clang/lib/Driver/ToolChains/Clang.cpp

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index d4a0772d61499..3d40e19c83a5e 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3239,6 +3239,12 @@ static void RenderSSPOptions(const Driver , const 
ToolChain ,
   StackProtectorLevel = LangOptions::SSPStrong;
 else if (A->getOption().matches(options::OPT_fstack_protector_all))
   StackProtectorLevel = LangOptions::SSPReq;
+
+if (EffectiveTriple.isBPF() && StackProtectorLevel != LangOptions::SSPOff) 
{
+  D.Diag(diag::warn_drv_unsupported_option_for_target)
+  << A->getSpelling() << EffectiveTriple.getTriple();
+  StackProtectorLevel = DefaultStackProtectorLevel;
+}
   } else {
 StackProtectorLevel = DefaultStackProtectorLevel;
   }

diff  --git a/clang/test/CodeGen/bpf-stack-protector.c 
b/clang/test/CodeGen/bpf-stack-protector.c
new file mode 100644
index 0..a005bb96ff1ed
--- /dev/null
+++ b/clang/test/CodeGen/bpf-stack-protector.c
@@ -0,0 +1,34 @@
+// REQUIRES: bpf-registered-target
+
+// RUN %clang -target bpf -S -emit-llvm -o - %s -fno-stack-protector 2>&1 \
+// RUN| FileCheck -check-prefix=OFF -check-prefix=COMMON %s
+
+// RUN: %clang -target bpf -S -emit-llvm -o - %s -fstack-protector 2>&1 \
+// RUN:| FileCheck -check-prefix=ON -check-prefix=COMMON %s
+
+// RUN: %clang -target bpf -S -emit-llvm -o - %s -fstack-protector-all 2>&1 \
+// RUN:| FileCheck -check-prefix=ALL -check-prefix=COMMON %s
+
+// RUN: %clang -target bpf -S -emit-llvm -o - %s -fstack-protector-strong 2>&1 
\
+// RUN:| FileCheck -check-prefix=STRONG -check-prefix=COMMON %s
+
+typedef __SIZE_TYPE__ size_t;
+
+int printf(const char * _Format, ...);
+size_t strlen(const char *s);
+char *strcpy(char *s1, const char *s2);
+
+// OFF-NOT: warning
+//  ON: warning: ignoring '-fstack-protector'
+// ALL: warning: ignoring '-fstack-protector-all'
+//  STRONG: warning: ignoring '-fstack-protector-strong'
+// COMMON-SAME: option as it is not currently supported for target 'bpf'
+
+// COMMON: define {{.*}}void @test1(ptr noundef %msg) #[[A:.*]] {
+void test1(const char *msg) {
+  char a[strlen(msg) + 1];
+  strcpy(a, msg);
+  printf("%s\n", a);
+}
+
+// COMMON-NOT: attributes #[[A]] = {{.*}} ssp



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 58bdf8f - [BPF] preserve btf_decl_tag for parameters of extern functions

2023-01-06 Thread Yonghong Song via cfe-commits

Author: Eduard Zingerman
Date: 2023-01-06T22:48:52-08:00
New Revision: 58bdf8f9a8c3331c6c4d5f631395fb6f786d1e9c

URL: 
https://github.com/llvm/llvm-project/commit/58bdf8f9a8c3331c6c4d5f631395fb6f786d1e9c
DIFF: 
https://github.com/llvm/llvm-project/commit/58bdf8f9a8c3331c6c4d5f631395fb6f786d1e9c.diff

LOG: [BPF] preserve btf_decl_tag for parameters of extern functions

Generate DILocalVariable entries for parameters of extern functions,
the "annotations" field of DILocalVariable is used to link
"btf_decl_tag" annotation with the parameter.

Do this only for BPF backend as there are no other users for this
information. Final DWARF is valid as "Appendix A" is very much lax in
what is allowed as attributes for "DW_TAG_formal_parameter":

DWARF does not in general require that a given debugging information
entry contain a particular attribute or set of attributes. Instead,
a DWARF producer is free to generate any, all, or none of the
attributes ... other attributes ... may also appear in a given
debugging information entry.

DWARF Debugging Information Format Version 5,
Appendix A: Attributes by Tag Value (Informative)
Page 251, Line 3.

Differential Revision: https://reviews.llvm.org/D140970

Added: 
clang/test/CodeGen/bpf-decl-tag-extern-func-args.c

Modified: 
clang/lib/CodeGen/CGDebugInfo.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 62ea222fade67..6096c92d3a452 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -4206,10 +4206,28 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, 
SourceLocation Loc,
 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
 
   llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(D);
-  llvm::DISubprogram *SP = DBuilder.createFunction(
-  FDContext, Name, LinkageName, Unit, LineNo,
-  getOrCreateFunctionType(D, FnType, Unit), ScopeLine, Flags, SPFlags,
-  TParamsArray.get(), getFunctionDeclaration(D), nullptr, Annotations);
+  llvm::DISubroutineType *STy = getOrCreateFunctionType(D, FnType, Unit);
+  llvm::DISubprogram *SP =
+  DBuilder.createFunction(FDContext, Name, LinkageName, Unit, LineNo, STy,
+  ScopeLine, Flags, SPFlags, TParamsArray.get(),
+  getFunctionDeclaration(D), nullptr, Annotations);
+
+  // Preserve btf_decl_tag attributes for parameters of extern functions
+  // for BPF target. The parameters created in this loop are attached as
+  // DISubprogram's retainedNodes in the subsequent finalizeSubprogram call.
+  if (IsDeclForCallSite && CGM.getTarget().getTriple().isBPF()) {
+if (auto *FD = dyn_cast(D)) {
+  llvm::DITypeRefArray ParamTypes = STy->getTypeArray();
+  unsigned ArgNo = 1;
+  for (ParmVarDecl *PD : FD->parameters()) {
+llvm::DINodeArray ParamAnnotations = CollectBTFDeclTagAnnotations(PD);
+DBuilder.createParameterVariable(
+SP, PD->getName(), ArgNo, Unit, LineNo, ParamTypes[ArgNo], true,
+llvm::DINode::FlagZero, ParamAnnotations);
+++ArgNo;
+  }
+}
+  }
 
   if (IsDeclForCallSite)
 Fn->setSubprogram(SP);

diff  --git a/clang/test/CodeGen/bpf-decl-tag-extern-func-args.c 
b/clang/test/CodeGen/bpf-decl-tag-extern-func-args.c
new file mode 100644
index 0..370352df9680e
--- /dev/null
+++ b/clang/test/CodeGen/bpf-decl-tag-extern-func-args.c
@@ -0,0 +1,38 @@
+// REQUIRES: bpf-registered-target
+// RUN: %clang -target bpf -S -emit-llvm -g -O2 -o - %s  | FileCheck %s
+
+#define __decl_tag(x) __attribute__((btf_decl_tag(x)))
+
+extern void foo(int aa __decl_tag("aa_tag"), long bb __decl_tag("bb_tag"));
+extern void bar(char cc __decl_tag("cc_tag"));
+extern void buz(int __decl_tag("buz_arg_tag"));
+
+void root(void) {
+  foo(0, 1);
+  bar(0);
+  buz(0);
+}
+// CHECK: [[foo:![0-9]+]] = !DISubprogram(name: "foo", {{.*}}, retainedNodes: 
[[foo_nodes:![0-9]+]])
+// CHECK: [[foo_nodes]] = !{[[aa:![0-9]+]], [[bb:![0-9]+]]}
+
+// CHECK: [[aa]] = !DILocalVariable(name: "aa", arg: 1, scope: [[foo]], 
{{.*}}, annotations: [[aa_annot:![0-9]+]])
+// CHECK: [[aa_annot]] = !{[[aa_tag:![0-9]+]]}
+// CHECK: [[aa_tag]] = !{!"btf_decl_tag", !"aa_tag"}
+
+// CHECK: [[bb]] = !DILocalVariable(name: "bb", arg: 2, scope: [[foo]], 
{{.*}}, annotations: [[bb_annot:![0-9]+]])
+// CHECK: [[bb_annot]] = !{[[bb_tag:![0-9]+]]}
+// CHECK: [[bb_tag]] = !{!"btf_decl_tag", !"bb_tag"}
+
+// CHECK: [[bar:![0-9]+]] = !DISubprogram(name: "bar", {{.*}}, retainedNodes: 
[[bar_nodes:![0-9]+]])
+// CHECK: [[bar_nodes]] = !{[[cc:![0-9]+]]}
+
+// CHECK: [[cc]] = !DILocalVariable(name: "cc", arg: 1, scope: [[bar]], 
{{.*}}, annotations: [[cc_annot:![0-9]+]])
+// CHECK: [[cc_annot]] = !{[[cc_tag:![0-9]+]]}
+// CHECK: [[cc_tag]] = !{!"btf_decl_tag", !"cc_tag"}
+
+// CHECK: [[buz:![0-9]+]] = !DISubprogram(name: "buz", {{.*}}, 

[clang] 2f047b5 - [clang][Sema] Fix a clang crash with btf_type_tag

2022-11-01 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2022-11-01T08:07:13-07:00
New Revision: 2f047b56ba0e4830b617999a386f6fea79c16c91

URL: 
https://github.com/llvm/llvm-project/commit/2f047b56ba0e4830b617999a386f6fea79c16c91
DIFF: 
https://github.com/llvm/llvm-project/commit/2f047b56ba0e4830b617999a386f6fea79c16c91.diff

LOG: [clang][Sema] Fix a clang crash with btf_type_tag

For the following program,
  $ cat t.c
  struct t {
   int (__attribute__((btf_type_tag("rcu"))) *f)();
   int a;
  };
  int foo(struct t *arg) {
return arg->a;
  }
Compiling with 'clang -g -O2 -S t.c' will cause a failure like below:
  clang: /home/yhs/work/llvm-project/clang/lib/Sema/SemaType.cpp:6391: void 
{anonymous}::DeclaratorLocFiller::VisitParenTypeLoc(clang::ParenTypeLoc):
 Assertion `Chunk.Kind == DeclaratorChunk::Paren' failed.
  PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ 
and include the crash backtrace, preprocessed source, and associated run script.
  Stack dump:
  ..
  #5 0x7f89e4280ea5 abort (/lib64/libc.so.6+0x21ea5)
  #6 0x7f89e4280d79 _nl_load_domain.cold.0 (/lib64/libc.so.6+0x21d79)
  #7 0x7f89e42a6456 (/lib64/libc.so.6+0x47456)
  #8 0x045c2596 GetTypeSourceInfoForDeclarator((anonymous 
namespace)::TypeProcessingState&, clang::QualType, clang::TypeSourceInfo*) 
SemaType.cpp:0:0
  #9 0x045ccfa5 GetFullTypeForDeclarator((anonymous 
namespace)::TypeProcessingState&, clang::QualType, clang::TypeSourceInfo*) 
SemaType.cpp:0:0
  ..

The reason of the failure is due to the mismatch of TypeLoc and 
D.getTypeObject().Kind. For example,
the TypeLoc is
  BTFTagAttributedType 0x88614e0 'int  btf_type_tag(rcu)()' sugar
  |-ParenType 0x8861480 'int ()' sugar
  | `-FunctionNoProtoType 0x8861450 'int ()' cdecl
  |   `-BuiltinType 0x87fd500 'int'
while corresponding D.getTypeObject().Kind points to DeclaratorChunk::Paren, and
this will cause later assertion.

To fix the issue, similar to AttributedTypeLoc, let us skip 
BTFTagAttributedTypeLoc in
GetTypeSourceInfoForDeclarator().

Differential Revision: https://reviews.llvm.org/D136807

Added: 
clang/test/CodeGen/attr-btf_type_tag-func-ptr.c

Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaType.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f751f96d29e9d..aac52bfc6e8fa 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -268,6 +268,8 @@ Bug Fixes
   functions. `Issue 56154 `_
 - Fix handling of unexpanded packs in template argument expressions.
   `Issue 58679 `_
+- Fix a crash when a ``btf_type_tag`` attribute is applied to the pointee of
+  a function pointer.
 
 Improvements to Clang's diagnostics
 ^^^

diff  --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 9b2a5c7ef8e27..b05e33e855dc0 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6515,6 +6515,9 @@ GetTypeSourceInfoForDeclarator(TypeProcessingState ,
   CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
 }
 
+while (BTFTagAttributedTypeLoc TL = 
CurrTL.getAs())
+  CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
+
 while (DependentAddressSpaceTypeLoc TL =
CurrTL.getAs()) {
   fillDependentAddressSpaceTypeLoc(TL, D.getTypeObject(i).getAttrs());

diff  --git a/clang/test/CodeGen/attr-btf_type_tag-func-ptr.c 
b/clang/test/CodeGen/attr-btf_type_tag-func-ptr.c
new file mode 100644
index 0..29ca5f58e4b81
--- /dev/null
+++ b/clang/test/CodeGen/attr-btf_type_tag-func-ptr.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -debug-info-kind=limited -S 
-emit-llvm -o - %s | FileCheck %s
+
+struct t {
+ int (__attribute__((btf_type_tag("rcu"))) *f)();
+ int a;
+};
+int foo(struct t *arg) {
+  return arg->a;
+}
+
+// CHECK:  !DIDerivedType(tag: DW_TAG_member, name: "f"
+// CHECK-SAME: baseType: ![[L18:[0-9]+]]
+// CHECK:  ![[L18]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: 
![[#]], size: [[#]], annotations: ![[L21:[0-9]+]])
+// CHECK:  ![[L21]] = !{![[L22:[0-9]+]]}
+// CHECK:  ![[L22]] = !{!"btf_type_tag", !"rcu"}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 524c640 - [clang][DebugInfo] Emit DISubprogram for extern functions with reserved names

2022-10-28 Thread Yonghong Song via cfe-commits

Author: Eduard Zingerman
Date: 2022-10-28T08:07:54-07:00
New Revision: 524c640090a8463305acbafd7606f1db3c1256e2

URL: 
https://github.com/llvm/llvm-project/commit/524c640090a8463305acbafd7606f1db3c1256e2
DIFF: 
https://github.com/llvm/llvm-project/commit/524c640090a8463305acbafd7606f1db3c1256e2.diff

LOG: [clang][DebugInfo] Emit DISubprogram for extern functions with reserved 
names

Callsite `DISubprogram` entries are not generated for:
- builtin functions;
- external functions with reserved names (e.g. names starting from "__").

This limitation was added by the commit [1] as a workaround for the
situation described in [2] that triggered the IR verifier error.
The goal of the present commit is to lift this limitation by adjusting
the IR verifier logic.

The logic behind [1] is to avoid the following situation:
- a `DISubprogram` is added for some builtin function;
- there is some location where this builtin is also emitted by a
  transformation (w/o debug location);
- the `Verifier::visitCallBase` sees a call to a function with
  `DISubprogram` but w/o debug location and emits an error.

Here is an updated example of such situation taken from [2]:

```
extern "C" int memcmp(void *, void *, long);

struct a { int b; int c; int d; };

struct e { int f[1000]; };

bool foo(e g, e ) {
  // DISubprogram for memcmp is created here when [1] is commented out
  return memcmp(, , sizeof(e));
}

bool bar(a , a ) {
  // memcmp might be generated here by MergeICmps
  return g.b == h.b && g.c == h.c && g.d == h.d;
}
```

This triggers the verifier error when:
- compiled for AArch64:
  `clang++ -c -g -Oz -target aarch64-unknown-linux-android21 test.cpp`;
- [1] check is commented out.

Instead of forbidding generation of `DISubprogram` entries as in [1]
one can instead adjust the verifier to additionally check if callee
has a body. Functions w/o bodies cannot be inlined and thus verifier
warning is not necessary.

E.g. `llvm::InlineFunction` requires functions for which
`GlobalValue::isDeclaration() == false`.

[1] 568db780bb7267651a902da8e85bc59fc89aea70
[2] https://bugs.chromium.org/p/chromium/issues/detail?id=1022296

Differential Revision: https://reviews.llvm.org/D136041

Added: 


Modified: 
clang/lib/CodeGen/CGDebugInfo.cpp
clang/test/CodeGen/debug-info-extern-call.c
llvm/lib/IR/Verifier.cpp
llvm/test/Verifier/callsite-dbgloc.ll

Removed: 




diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index aa02821aa971..4b56e155022a 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -4228,17 +4228,11 @@ void 
CGDebugInfo::EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke,
   if (Func->getSubprogram())
 return;
 
-  // Do not emit a declaration subprogram for a builtin, a function with 
nodebug
-  // attribute, or if call site info isn't required. Also, elide declarations
-  // for functions with reserved names, as call site-related features aren't
-  // interesting in this case (& also, the compiler may emit calls to these
-  // functions without debug locations, which makes the verifier complain).
-  if (CalleeDecl->getBuiltinID() != 0 || CalleeDecl->hasAttr() ||
+  // Do not emit a declaration subprogram for a function with nodebug
+  // attribute, or if call site info isn't required.
+  if (CalleeDecl->hasAttr() ||
   getCallSiteRelatedAttrs() == llvm::DINode::FlagZero)
 return;
-  if (CalleeDecl->isReserved(CGM.getLangOpts()) !=
-  ReservedIdentifierStatus::NotReserved)
-return;
 
   // If there is no DISubprogram attached to the function being called,
   // create the one describing the function in order to have complete

diff  --git a/clang/test/CodeGen/debug-info-extern-call.c 
b/clang/test/CodeGen/debug-info-extern-call.c
index fad52d0df0b3..0d18dc436040 100644
--- a/clang/test/CodeGen/debug-info-extern-call.c
+++ b/clang/test/CodeGen/debug-info-extern-call.c
@@ -29,8 +29,8 @@
 // DECLS-FOR-EXTERN: [[FN1_TYPES]] = !{[[X_TYPE:![0-9]+]],
 // DECLS-FOR-EXTERN: [[X_TYPE]] = !DIDerivedType(tag: DW_TAG_typedef, name: 
"x",
 // DECLS-FOR-EXTERN-SAME: baseType: [[INT_TYPE]])
-// DECLS-FOR-EXTERN-NOT: !DISubprogram(name: "memcmp"
-// DECLS-FOR-EXTERN-NOT: !DISubprogram(name: "__some_reserved_name"
+// DECLS-FOR-EXTERN: !DISubprogram(name: "memcmp"
+// DECLS-FOR-EXTERN: !DISubprogram(name: "__some_reserved_name"
 
 // NO-DECLS-FOR-EXTERN-NOT: !DISubprogram(name: "fn1"
 // NO-DECLS-FOR-EXTERN-NOT: !DISubprogram(name: "memcmp"

diff  --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 06f03164c19e..0614f206981a 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -3468,9 +3468,11 @@ void Verifier::visitCallBase(CallBase ) {
   // Verify that each inlinable callsite of a debug-info-bearing function in a
   // debug-info-bearing function has a debug location attached to it. Failure 
to
   // do 

[clang] 75be048 - [clang][DebugInfo] Emit debuginfo for non-constant case value

2022-09-28 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2022-09-28T12:10:48-07:00
New Revision: 75be0482a2e2a78fae83f1ca604f4ee20d673796

URL: 
https://github.com/llvm/llvm-project/commit/75be0482a2e2a78fae83f1ca604f4ee20d673796
DIFF: 
https://github.com/llvm/llvm-project/commit/75be0482a2e2a78fae83f1ca604f4ee20d673796.diff

LOG: [clang][DebugInfo] Emit debuginfo for non-constant case value

Currently, clang does not emit debuginfo for the switch stmt
case value if it is an enum value. For example,
  $ cat test.c
  enum { AA = 1, BB = 2 };
  int func1(int a) {
switch(a) {
case AA: return 10;
case BB: return 11;
default: break;
}
return 0;
  }
  $ llvm-dwarfdump test.o | grep AA
  $
Note that gcc does emit debuginfo for the same test case.

This patch added such a support with similar implementation
to CodeGenFunction::EmitDeclRefExprDbgValue(). With this patch,
  $ clang -g -c test.c
  $ llvm-dwarfdump test.o | grep AA
  DW_AT_name("AA")
  $

Differential Revision: https://reviews.llvm.org/D134705

Added: 
clang/test/CodeGen/debug-info-enum-case-val.c

Modified: 
clang/lib/CodeGen/CGStmt.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 481438de0e53a..9935fcc0d3ea2 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -1509,6 +1509,21 @@ void CodeGenFunction::EmitCaseStmt(const CaseStmt ,
 
   llvm::ConstantInt *CaseVal =
 Builder.getInt(S.getLHS()->EvaluateKnownConstInt(getContext()));
+
+  // Emit debuginfo for the case value if it is an enum value.
+  const ConstantExpr *CE;
+  if (auto ICE = dyn_cast(S.getLHS()))
+CE = dyn_cast(ICE->getSubExpr());
+  else
+CE = dyn_cast(S.getLHS());
+  if (CE) {
+if (auto DE = dyn_cast(CE->getSubExpr()))
+  if (CGDebugInfo *Dbg = getDebugInfo())
+if (CGM.getCodeGenOpts().hasReducedDebugInfo())
+  Dbg->EmitGlobalVariable(DE->getDecl(),
+  APValue(llvm::APSInt(CaseVal->getValue(;
+  }
+
   if (SwitchLikelihood)
 SwitchLikelihood->push_back(Stmt::getLikelihood(Attrs));
 

diff  --git a/clang/test/CodeGen/debug-info-enum-case-val.c 
b/clang/test/CodeGen/debug-info-enum-case-val.c
new file mode 100644
index 0..f39de0d732375
--- /dev/null
+++ b/clang/test/CodeGen/debug-info-enum-case-val.c
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s
+
+enum { A = 1 };
+int func1(int a) {
+  switch(a) {
+  case A: return 10;
+  default: break;
+  }
+  return 0;
+}
+// CHECK:   !DICompositeType(tag: DW_TAG_enumeration_type
+// CHECK-SAME:  elements: [[TEST1_ENUMS:![0-9]*]]
+// CHECK:   [[TEST1_ENUMS]] = !{[[TEST1_E:![0-9]*]]}
+// CHECK:   [[TEST1_E]] = !DIEnumerator(name: "A", value: 1)
+
+// Test ImplicitCast of switch case enum value
+enum { B = 2 };
+typedef unsigned long long __t1;
+typedef __t1 __t2;
+int func2(__t2 a) {
+  switch(a) {
+  case B: return 10;
+  default: break;
+  }
+  return 0;
+}
+// CHECK:   !DICompositeType(tag: DW_TAG_enumeration_type
+// CHECK-SAME:  elements: [[TEST2_ENUMS:![0-9]*]]
+// CHECK:   [[TEST2_ENUMS]] = !{[[TEST2_E:![0-9]*]]}
+// CHECK:   [[TEST2_E]] = !DIEnumerator(name: "B", value: 2)



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 481d67d - [Clang][BPF] Support record argument with direct values

2022-08-18 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2022-08-18T19:11:50-07:00
New Revision: 481d67d310a7a4213da72f838d6bafaa52ed01d3

URL: 
https://github.com/llvm/llvm-project/commit/481d67d310a7a4213da72f838d6bafaa52ed01d3
DIFF: 
https://github.com/llvm/llvm-project/commit/481d67d310a7a4213da72f838d6bafaa52ed01d3.diff

LOG: [Clang][BPF] Support record argument with direct values

Currently, record arguments are always passed by reference by allocating
space for record values in the caller. This is less efficient for
small records which may take one or two registers. For example,
for x86_64 and aarch64, for a record size up to 16 bytes, the record
values can be passed by values directly on the registers.

This patch added BPF support of record argument with direct values
for up to 16 byte record size. If record size is 0, that record
will not take any register, which is the same behavior for x86_64
and aarch64. If the record size is greater than 16 bytes, the
record argument will be passed by reference.

Differential Revision: https://reviews.llvm.org/D132144

Added: 
clang/test/CodeGen/bpf-struct-argument.c
clang/test/CodeGen/bpf-union-argument.c
llvm/test/CodeGen/BPF/struct-arg-inline.ll
llvm/test/CodeGen/BPF/struct-arg.ll

Modified: 
clang/lib/CodeGen/TargetInfo.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/TargetInfo.cpp 
b/clang/lib/CodeGen/TargetInfo.cpp
index 2790c665c6dd2..39871b0907ede 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -11509,6 +11509,42 @@ class BPFABIInfo : public DefaultABIInfo {
 public:
   BPFABIInfo(CodeGenTypes ) : DefaultABIInfo(CGT) {}
 
+  ABIArgInfo classifyArgumentType(QualType Ty) const {
+Ty = useFirstFieldIfTransparentUnion(Ty);
+
+if (isAggregateTypeForABI(Ty)) {
+  uint64_t Bits = getContext().getTypeSize(Ty);
+  if (Bits == 0)
+return ABIArgInfo::getIgnore();
+
+  // If the aggregate needs 1 or 2 registers, do not use reference.
+  if (Bits <= 128) {
+llvm::Type *CoerceTy;
+if (Bits <= 64) {
+  CoerceTy =
+  llvm::IntegerType::get(getVMContext(), llvm::alignTo(Bits, 8));
+} else {
+  llvm::Type *RegTy = llvm::IntegerType::get(getVMContext(), 64);
+  CoerceTy = llvm::ArrayType::get(RegTy, 2);
+}
+return ABIArgInfo::getDirect(CoerceTy);
+  } else {
+return getNaturalAlignIndirect(Ty);
+  }
+}
+
+if (const EnumType *EnumTy = Ty->getAs())
+  Ty = EnumTy->getDecl()->getIntegerType();
+
+ASTContext  = getContext();
+if (const auto *EIT = Ty->getAs())
+  if (EIT->getNumBits() > Context.getTypeSize(Context.Int128Ty))
+return getNaturalAlignIndirect(Ty);
+
+return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
+  : ABIArgInfo::getDirect());
+  }
+
   ABIArgInfo classifyReturnType(QualType RetTy) const {
 if (RetTy->isVoidType())
   return ABIArgInfo::getIgnore();

diff  --git a/clang/test/CodeGen/bpf-struct-argument.c 
b/clang/test/CodeGen/bpf-struct-argument.c
new file mode 100644
index 0..d4fcf16af2e28
--- /dev/null
+++ b/clang/test/CodeGen/bpf-struct-argument.c
@@ -0,0 +1,36 @@
+// REQUIRES: bpf-registered-target
+// RUN: %clang_cc1 -triple bpf -O2 -emit-llvm -disable-llvm-passes %s -o - | 
FileCheck %s
+
+struct t1 {};
+struct t2 {
+  int a;
+};
+struct t3 {
+  int a;
+  long b;
+};
+struct t4 {
+  long a;
+  long b;
+  long c;
+};
+
+int foo1(struct t1 arg1, struct t2 arg2) {
+// CHECK: define dso_local i32 @foo1(i32 %arg2.coerce)
+  return arg2.a;
+}
+
+int foo2(struct t3 arg1, struct t4 arg2) {
+// CHECK: define dso_local i32 @foo2([2 x i64] %arg1.coerce, ptr noundef 
byval(%struct.t4) align 8 %arg2)
+  return arg1.a + arg2.a;
+}
+
+int foo3(void) {
+  struct t1 tmp1 = {};
+  struct t2 tmp2 = {};
+  struct t3 tmp3 = {};
+  struct t4 tmp4 = {};
+  return foo1(tmp1, tmp2) + foo2(tmp3, tmp4);
+// CHECK: call i32 @foo1(i32 %{{[a-zA-Z0-9]+}})
+// CHECK: call i32 @foo2([2 x i64] %{{[a-zA-Z0-9]+}}, ptr noundef 
byval(%struct.t4) align 8 %tmp4)
+}

diff  --git a/clang/test/CodeGen/bpf-union-argument.c 
b/clang/test/CodeGen/bpf-union-argument.c
new file mode 100644
index 0..5f3a0bc5a9261
--- /dev/null
+++ b/clang/test/CodeGen/bpf-union-argument.c
@@ -0,0 +1,44 @@
+// REQUIRES: bpf-registered-target
+// RUN: %clang_cc1 -triple bpf -O2 -emit-llvm -disable-llvm-passes %s -o - | 
FileCheck %s
+
+union t1 {};
+union t2 {
+  int a;
+  long b;
+};
+union t3 {
+  struct {
+int a;
+long b;
+  };
+  long c;
+};
+union t4 {
+  struct {
+long a;
+long b;
+long c;
+  };
+  long d;
+};
+
+int foo1(union t1 arg1, union t2 arg2) {
+// CHECK: define dso_local i32 @foo1(i64 %arg2.coerce)
+  return arg2.a;
+}
+
+int foo2(union t3 arg1, union t4 arg2) {
+// CHECK: define dso_local i32 @foo2([2 x i64] 

[clang] d9198f6 - [Clang][BPF]: Force sign/zero extension for return values in caller

2022-08-16 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2022-08-16T16:08:01-07:00
New Revision: d9198f64d9be149acdad109cd053b6acdd9635d2

URL: 
https://github.com/llvm/llvm-project/commit/d9198f64d9be149acdad109cd053b6acdd9635d2
DIFF: 
https://github.com/llvm/llvm-project/commit/d9198f64d9be149acdad109cd053b6acdd9635d2.diff

LOG: [Clang][BPF]: Force sign/zero extension for return values in caller

Currently bpf supports calling kernel functions (x86_64, arm64, etc.)
in bpf programs. Tejun discovered a problem where the x86_64 func
return value (a unsigned char type) is stored in 8-bit subregister %al
and the other 56-bits in %rax might be garbage. But based on current
bpf ABI, the bpf program assumes the whole %rax holds the correct value
as the callee is supposed to do necessary sign/zero extension.
This mismatch between bpf and x86_64 caused the incorrect results.

To resolve this problem, this patch forced caller to do needed
sign/zero extension for 8/16-bit return values as well. Note that
32-bit return values already had sign/zero extension even without
this patch.

For example, for the test case attached to this patch:

  $  cat t.c
  _Bool bar_bool(void);
  unsigned char bar_char(void);
  short bar_short(void);
  int bar_int(void);
  int foo_bool(void) {
if (bar_bool() != 1) return 0; else return 1;
  }
  int foo_char(void) {
if (bar_char() != 10) return 0; else return 1;
  }
  int foo_short(void) {
if (bar_short() != 10) return 0; else return 1;
  }
  int foo_int(void) {
if (bar_int() != 10) return 0; else return 1;
  }

Without this patch, generated call insns in IR looks like:
%call = call zeroext i1 @bar_bool()
%call = call zeroext i8 @bar_char()
%call = call signext i16 @bar_short()
%call = call i32 @bar_int()
So it is assumed that zero extension has been done for return values of
bar_bool()and bar_char(). Sign extension has been done for the return
value of bar_short(). The return value of bar_int() does not have any
assumption so caller needs to do necessary shifting to get correct
32bit values.

With this patch, generated call insns in IR looks like:
%call = call i1 @bar_bool()
%call = call i8 @bar_char()
%call = call i16 @bar_short()
%call = call i32 @bar_int()
There are no assumptions for return values of the above four function calls,
so necessary shifting is necessary for all of them.

The following is the objdump file difference for function foo_char().
Without this patch:
  0010 :
   2:   85 10 00 00 ff ff ff ff call -1
   3:   bf 01 00 00 00 00 00 00 r1 = r0
   4:   b7 00 00 00 01 00 00 00 r0 = 1
   5:   15 01 01 00 0a 00 00 00 if r1 == 10 goto +1 
   6:   b7 00 00 00 00 00 00 00 r0 = 0
  0038 :
   7:   95 00 00 00 00 00 00 00 exit

With this patch:
  0018 :
   3:   85 10 00 00 ff ff ff ff call -1
   4:   bf 01 00 00 00 00 00 00 r1 = r0
   5:   57 01 00 00 ff 00 00 00 r1 &= 255
   6:   b7 00 00 00 01 00 00 00 r0 = 1
   7:   15 01 01 00 0a 00 00 00 if r1 == 10 goto +1 
   8:   b7 00 00 00 00 00 00 00 r0 = 0
  0048 :
   9:   95 00 00 00 00 00 00 00 exit
The zero extension of the return 'char' value is done here.

Differential Revision: https://reviews.llvm.org/D131598

Added: 
clang/test/CodeGen/bpf-abiinfo.c

Modified: 
clang/lib/CodeGen/TargetInfo.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/TargetInfo.cpp 
b/clang/lib/CodeGen/TargetInfo.cpp
index bbc40ad3a50a..2790c665c6dd 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -11499,6 +11499,56 @@ class CSKYTargetCodeGenInfo : public TargetCodeGenInfo 
{
 };
 } // end anonymous namespace
 
+//===--===//
+// BPF ABI Implementation
+//===--===//
+
+namespace {
+
+class BPFABIInfo : public DefaultABIInfo {
+public:
+  BPFABIInfo(CodeGenTypes ) : DefaultABIInfo(CGT) {}
+
+  ABIArgInfo classifyReturnType(QualType RetTy) const {
+if (RetTy->isVoidType())
+  return ABIArgInfo::getIgnore();
+
+if (isAggregateTypeForABI(RetTy))
+  return getNaturalAlignIndirect(RetTy);
+
+// Treat an enum type as its underlying type.
+if (const EnumType *EnumTy = RetTy->getAs())
+  RetTy = EnumTy->getDecl()->getIntegerType();
+
+ASTContext  = getContext();
+if (const auto *EIT = RetTy->getAs())
+  if (EIT->getNumBits() > Context.getTypeSize(Context.Int128Ty))
+return getNaturalAlignIndirect(RetTy);
+
+// Caller will do necessary sign/zero extension.
+return ABIArgInfo::getDirect();
+  }
+
+  void computeInfo(CGFunctionInfo ) const override {
+FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+for (auto  : FI.arguments())
+  I.info = 

[clang] 70557eb - [clang][BPF] Update comment to include TYPE_MATCH

2022-06-29 Thread Yonghong Song via cfe-commits

Author: Daniel Müller
Date: 2022-06-29T18:32:06-07:00
New Revision: 70557eb3938a0bdc784c9ae14e84e9ad9914ebdc

URL: 
https://github.com/llvm/llvm-project/commit/70557eb3938a0bdc784c9ae14e84e9ad9914ebdc
DIFF: 
https://github.com/llvm/llvm-project/commit/70557eb3938a0bdc784c9ae14e84e9ad9914ebdc.diff

LOG: [clang][BPF] Update comment to include TYPE_MATCH

D126838 added support for the TYPE_MATCH compile-once run-everywhere
relocation to LLVM proper. On the clang side no changes are necessary,
other than the adjustment of a comment to mention this relocation as well.
This change takes care of that.

Differential Revision: https://reviews.llvm.org/D126839

Added: 


Modified: 
clang/lib/Sema/SemaChecking.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 9ebd42bf4e35e..79420cc276995 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3254,7 +3254,7 @@ static bool isValidBPFPreserveTypeInfoArg(Expr *Arg) {
   if (ArgType->getAsPlaceholderType())
 return false;
 
-  // for TYPE_EXISTENCE/TYPE_SIZEOF reloc type
+  // for TYPE_EXISTENCE/TYPE_MATCH/TYPE_SIZEOF reloc type
   // format:
   //   1. __builtin_preserve_type_info(*( *)0, flag);
   //   2.  var;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] bdf69f6 - [Clang] Fix an unused-but-set-variable warning with volatile variable

2022-03-21 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2022-03-21T14:59:03-07:00
New Revision: bdf69f63df2cf4c9e3cd1af5cfcd503bc8e2869b

URL: 
https://github.com/llvm/llvm-project/commit/bdf69f63df2cf4c9e3cd1af5cfcd503bc8e2869b
DIFF: 
https://github.com/llvm/llvm-project/commit/bdf69f63df2cf4c9e3cd1af5cfcd503bc8e2869b.diff

LOG: [Clang] Fix an unused-but-set-variable warning with volatile variable

For the following code,
void test() {
volatile int j = 0;
for (int i = 0; i < 1000; i++)
j += 1;
return;
}
If compiled with
clang -g -Wall -Werror -S -emit-llvm test.c
we will see the following error:
test.c:2:6: error: variable 'j' set but not used 
[-Werror,-Wunused-but-set-variable]
volatile int j = 0;
 ^

This is not quite right since 'j' is indeed used due to '+=' operator.
gcc doesn't emit error either in this case.
Also if we change 'j += 1' to 'j++', the warning will disappear
with latest clang.

Note that clang will issue the warning if the volatile declaration
involves only simple assignment (var = ...).

To fix the issue, in function MaybeDecrementCount(), if the
operator is a compound assignment (i.e., +=, -=, etc.) and the
variable is volatile, the count for RefsMinusAssignments will be
decremented, similar to 'j++' case.

Differential Revision: https://reviews.llvm.org/D121715

Added: 


Modified: 
clang/lib/Sema/SemaExprCXX.cpp
clang/test/Sema/warn-unused-but-set-variables.c

Removed: 




diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index ee4bff5c14b89..c923dddb9f285 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -7925,6 +7925,7 @@ ExprResult Sema::ActOnNoexceptExpr(SourceLocation KeyLoc, 
SourceLocation,
 static void MaybeDecrementCount(
 Expr *E, llvm::DenseMap ) {
   DeclRefExpr *LHS = nullptr;
+  bool IsCompoundAssign = false;
   if (BinaryOperator *BO = dyn_cast(E)) {
 if (BO->getLHS()->getType()->isDependentType() ||
 BO->getRHS()->getType()->isDependentType()) {
@@ -7932,6 +7933,8 @@ static void MaybeDecrementCount(
 return;
 } else if (!BO->isAssignmentOp())
   return;
+else
+  IsCompoundAssign = BO->isCompoundAssignmentOp();
 LHS = dyn_cast(BO->getLHS());
   } else if (CXXOperatorCallExpr *COCE = dyn_cast(E)) {
 if (COCE->getOperator() != OO_Equal)
@@ -7943,6 +7946,10 @@ static void MaybeDecrementCount(
   VarDecl *VD = dyn_cast(LHS->getDecl());
   if (!VD)
 return;
+  // Don't decrement RefsMinusAssignments if volatile variable with compound
+  // assignment (+=, ...) to avoid potential unused-but-set-variable warning.
+  if (IsCompoundAssign && VD->getType().isVolatileQualified())
+return;
   auto iter = RefsMinusAssignments.find(VD);
   if (iter == RefsMinusAssignments.end())
 return;

diff  --git a/clang/test/Sema/warn-unused-but-set-variables.c 
b/clang/test/Sema/warn-unused-but-set-variables.c
index a8d2ceaa428c9..6e5b7d671711b 100644
--- a/clang/test/Sema/warn-unused-but-set-variables.c
+++ b/clang/test/Sema/warn-unused-but-set-variables.c
@@ -23,10 +23,24 @@ int f0(void) {
   int a;
   w = (a = 0);
 
+  int j = 0; // expected-warning{{variable 'j' set but not used}}
+  for (int i = 0; i < 1000; i++)
+j += 1;
+
   // Following gcc, warn for a volatile variable.
   volatile int b; // expected-warning{{variable 'b' set but not used}}
   b = 0;
 
+  // volatile variable k is used, no warning.
+  volatile int k = 0;
+  for (int i = 0; i < 1000; i++)
+k += 1;
+
+  // typedef of volatile type, no warning.
+  typedef volatile int volint;
+  volint l = 0;
+  l += 1;
+
   int x;
   x = 0;
   return x;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D120296: [Attr] Fix a btf_type_tag AST generation bug

2022-03-16 Thread Yonghong Song via cfe-commits



On 3/16/22 10:32 AM, Sterling Augustine via Phabricator wrote:

saugustine added a comment.

This change ends up leaving some unhandled enum with switches inside lldb, and 
it isn't obvious to me how to fix them. Can you take a quick look?

   
llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp:4098:11: 
error: enumeration value 'BTFTagAttributed' not handled in switch 
[-Werror,-Wswitch]
 switch (qual_type->getTypeClass()) {
 ^
   
llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp:4757:11: 
error: enumeration value 'BTFTagAttributed' not handled in switch 
[-Werror,-Wswitch]
 switch (qual_type->getTypeClass()) {
 ^
   
llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp:5140:11: 
error: enumeration value 'BTFTagAttributed' not handled in switch 
[-Werror,-Wswitch]
 switch (qual_type->getTypeClass()) {
 ^
   3 errors generated.



Thanks. Will take a look immediately.



Repository:
   rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
   https://reviews.llvm.org/D120296/new/

https://reviews.llvm.org/D120296


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 3251ba2 - [Attr] Fix a btf_type_tag AST generation

2022-03-16 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2022-03-16T08:46:52-07:00
New Revision: 3251ba2d0fcf5223fce3e270b91c54f548664b4e

URL: 
https://github.com/llvm/llvm-project/commit/3251ba2d0fcf5223fce3e270b91c54f548664b4e
DIFF: 
https://github.com/llvm/llvm-project/commit/3251ba2d0fcf5223fce3e270b91c54f548664b4e.diff

LOG: [Attr] Fix a btf_type_tag AST generation

Current ASTContext.getAttributedType() takes attribute kind,
ModifiedType and EquivType as the hash to decide whether an AST node
has been generated or note. But this is not enough for btf_type_tag
as the attribute might have the same ModifiedType and EquivType, but
still have different string associated with attribute.

For example, for a data structure like below,
  struct map_value {
int __attribute__((btf_type_tag("tag1"))) 
__attribute__((btf_type_tag("tag3"))) *a;
int __attribute__((btf_type_tag("tag2"))) 
__attribute__((btf_type_tag("tag4"))) *b;
  };
The current ASTContext.getAttributedType() will produce
an AST similar to below:
  struct map_value {
int __attribute__((btf_type_tag("tag1"))) 
__attribute__((btf_type_tag("tag3"))) *a;
int __attribute__((btf_type_tag("tag1"))) 
__attribute__((btf_type_tag("tag3"))) *b;
  };
and this is incorrect.

It is very difficult to use the current AttributedType as it is hard to
get the tag information. To fix the problem, this patch introduced
BTFTagAttributedType which is similar to AttributedType
in many ways but with an additional BTFTypeTagAttr. The tag itself can
be retrieved with BTFTypeTagAttr.
With the new BTFTagAttributed type, the debuginfo code can be greatly
simplified compared to previous TypeLoc based approach.

Differential Revision: https://reviews.llvm.org/D120296

Added: 
clang/test/CodeGen/attr-btf_type_tag-similar-type.c
clang/test/PCH/btf_type_tag_attr.c

Modified: 
clang/include/clang-c/Index.h
clang/include/clang/AST/ASTContext.h
clang/include/clang/AST/ASTNodeTraverser.h
clang/include/clang/AST/PropertiesBase.td
clang/include/clang/AST/RecursiveASTVisitor.h
clang/include/clang/AST/Type.h
clang/include/clang/AST/TypeLoc.h
clang/include/clang/AST/TypeProperties.td
clang/include/clang/Basic/TypeNodes.td
clang/include/clang/Serialization/ASTRecordReader.h
clang/include/clang/Serialization/ASTRecordWriter.h
clang/include/clang/Serialization/TypeBitCodes.def
clang/lib/AST/ASTContext.cpp
clang/lib/AST/ASTStructuralEquivalence.cpp
clang/lib/AST/ItaniumMangle.cpp
clang/lib/AST/TypeLoc.cpp
clang/lib/AST/TypePrinter.cpp
clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/CodeGen/CGDebugInfo.h
clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaType.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/test/Sema/attr-btf_type_tag.c
clang/tools/libclang/CIndex.cpp
clang/tools/libclang/CXType.cpp

Removed: 




diff  --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index ea44673a3f1ea..c6967e5f85609 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -3401,7 +3401,8 @@ enum CXTypeKind {
   CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175,
 
   CXType_ExtVector = 176,
-  CXType_Atomic = 177
+  CXType_Atomic = 177,
+  CXType_BTFTagAttributed = 178
 };
 
 /**

diff  --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index f2d7060e6f3d3..bae848f3d77e3 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -264,6 +264,7 @@ class ASTContext : public RefCountedBase {
   mutable llvm::FoldingSet PipeTypes;
   mutable llvm::FoldingSet BitIntTypes;
   mutable llvm::FoldingSet DependentBitIntTypes;
+  llvm::FoldingSet BTFTagAttributedTypes;
 
   mutable llvm::FoldingSet QualifiedTemplateNames;
   mutable llvm::FoldingSet DependentTemplateNames;
@@ -1592,6 +1593,9 @@ class ASTContext : public RefCountedBase {
  QualType modifiedType,
  QualType equivalentType);
 
+  QualType getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr,
+   QualType Wrapped);
+
   QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
 QualType Replacement) const;
   QualType getSubstTemplateTypeParmPackType(

diff  --git a/clang/include/clang/AST/ASTNodeTraverser.h 
b/clang/include/clang/AST/ASTNodeTraverser.h
index 18e7f491f2225..f2c5c01ac88de 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -386,6 +386,9 @@ class ASTNodeTraverser
 // FIXME: AttrKind
 Visit(T->getModifiedType());
   }
+  void VisitBTFTagAttributedType(const BTFTagAttributedType *T) {
+Visit(T->getWrappedType());
+  }
 

[clang] bbab17c - [Clang][Attr] fix a btf_type_attr CGDebugInfo codegen bug

2021-11-06 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2021-11-06T18:19:00-07:00
New Revision: bbab17c6c987d7a6612855c02a4e8988dac0dc17

URL: 
https://github.com/llvm/llvm-project/commit/bbab17c6c987d7a6612855c02a4e8988dac0dc17
DIFF: 
https://github.com/llvm/llvm-project/commit/bbab17c6c987d7a6612855c02a4e8988dac0dc17.diff

LOG: [Clang][Attr] fix a btf_type_attr CGDebugInfo codegen bug

Nathan Chancellor reported a crash due to commit
3466e00716e1 (Reland "[Attr] support btf_type_tag attribute").

The following test can reproduce the crash:
  $ cat efi.i
  typedef unsigned long efi_query_variable_info_t(int);
  typedef struct {
struct {
  efi_query_variable_info_t __attribute__((regparm(0))) * 
query_variable_info;
};
  } efi_runtime_services_t;
  efi_runtime_services_t efi_0;
  $ clang -m32 -O2 -g -c -o /dev/null efi.i

The reason is that FunctionTypeLoc.getParam(Idx) may return a
nullptr which should be checked before dereferencing the
result pointer. This patch fixed this issue.

Added: 


Modified: 
clang/lib/CodeGen/CGDebugInfo.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 2b9532534e3aa..1ce56f98e1f09 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1446,9 +1446,10 @@ llvm::DIType *CGDebugInfo::CreateType(const FunctionType 
*Ty,
 for (const QualType  : FPT->param_types()) {
   TypeLoc ParamTL;
   if (Idx < FTL_NumParams) {
-ParmVarDecl *Param = FTL.getParam(Idx);
-if (const TypeSourceInfo *TSI = Param->getTypeSourceInfo())
-  ParamTL = TSI->getTypeLoc();
+if (ParmVarDecl *Param = FTL.getParam(Idx)) {
+  if (const TypeSourceInfo *TSI = Param->getTypeSourceInfo())
+ParamTL = TSI->getTypeLoc();
+}
   }
   EltTys.push_back(getOrCreateType(ParamType, Unit, ParamTL));
   Idx++;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D111199: [Clang][LLVM][Attr] support btf_type_tag attribute

2021-11-06 Thread Yonghong Song via cfe-commits



On 11/6/21 4:36 PM, Nathan Chancellor via Phabricator wrote:

nathanchance added a comment.

I bisected a crash in the Linux kernel down to the reland commit (and it is not 
fixed as of 
https://github.com/llvm/llvm-project/commit/2249ecee8d9a6237f51485bd39f01ba031575987):

   $ git bisect log
   # bad: [bdaa181007a46d317a1665acb8234eddeee82815] 
[TwoAddressInstructionPass] Update existing physreg live intervals
   # good: [d4b1cf8f9c48a49ab808df15c4ab378276a07b82] [OpenMP] Build device 
runtimes for sm_86
   git bisect start 'bdaa181007a46d317a1665acb8234eddeee82815' 
'd4b1cf8f9c48a49ab808df15c4ab378276a07b82'
   # good: [f2703c3c3353031de8de8c465a59d31488b11fb3] [DAG] FoldConstantArithmetic 
- rename NumOps -> NumElts. NFC.
   git bisect good f2703c3c3353031de8de8c465a59d31488b11fb3
   # good: [c68183b81e5257186c9403cf91f8b958af7459bc] [gn build] Use `=` for of 
-fdebug-compilation-dir
   git bisect good c68183b81e5257186c9403cf91f8b958af7459bc
   # bad: [2d8ec3c61d3c2d47b303187bb882ca23544f6fc5] [libcxx] [test] Narrow down XFAILs regarding 
a MSVC mode specific bug to "windows-dll && msvc"
   git bisect bad 2d8ec3c61d3c2d47b303187bb882ca23544f6fc5
   # good: [97c899f3c5d9bbff2824b3252b21378bf96f3f3f] [mlir] Add callback to 
provide a pass pipeline to MlirOptMain
   git bisect good 97c899f3c5d9bbff2824b3252b21378bf96f3f3f
   # bad: [4070f305f9a0c488d7177754d77c0b367e8695bf] [mlir][DialectConversion] 
Legalize all live argument conversions
   git bisect bad 4070f305f9a0c488d7177754d77c0b367e8695bf
   # bad: [3466e00716e12e32fdb100e3fcfca5c2b3e8d784] Reland "[Attr] support 
btf_type_tag attribute"
   git bisect bad 3466e00716e12e32fdb100e3fcfca5c2b3e8d784
   # good: [f64580f8d2ce5e1161857f9c89c2eee7a74c5ab8] [AArch64][GISel] Optimize 
8 and 16 bit variants of uaddo.
   git bisect good f64580f8d2ce5e1161857f9c89c2eee7a74c5ab8
   # first bad commit: [3466e00716e12e32fdb100e3fcfca5c2b3e8d784] Reland "[Attr] 
support btf_type_tag attribute"


Thanks. I will look at this problem immediately.



`cvise` spits out:

   $ cat efi.i
   typedef unsigned long efi_query_variable_info_t(int);
   typedef struct {
 struct {
   efi_query_variable_info_t __attribute__((regparm(0))) * 
query_variable_info;
 };
   } efi_runtime_services_t;
   efi_runtime_services_t efi_0;
   
   $ clang -m32 -O2 -c -o /dev/null efi.i
   

[...]
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 3466e00 - Reland "[Attr] support btf_type_tag attribute"

2021-11-05 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2021-11-05T11:25:17-07:00
New Revision: 3466e00716e12e32fdb100e3fcfca5c2b3e8d784

URL: 
https://github.com/llvm/llvm-project/commit/3466e00716e12e32fdb100e3fcfca5c2b3e8d784
DIFF: 
https://github.com/llvm/llvm-project/commit/3466e00716e12e32fdb100e3fcfca5c2b3e8d784.diff

LOG: Reland "[Attr] support btf_type_tag attribute"

This is to revert commit f95bd18b5faa (Revert "[Attr] support
btf_type_tag attribute") plus a bug fix.

Previous change failed to handle cases like below:
$ cat reduced.c
void a(*);
void a() {}
$ clang -c reduced.c -O2 -g

In such cases, during clang IR generation, for function a(),
CGCodeGen has numParams = 1 for FunctionType. But for
FunctionTypeLoc we have FuncTypeLoc.NumParams = 0. By using
FunctionType.numParams as the bound to access FuncTypeLoc
params, a random crash is triggered. The bug fix is to
check against FuncTypeLoc.NumParams before accessing
FuncTypeLoc.getParam(Idx).

Differential Revision: https://reviews.llvm.org/D99

Added: 
clang/test/CodeGen/attr-btf_type_tag-func.c
clang/test/CodeGen/attr-btf_type_tag-typedef-field.c
clang/test/CodeGen/attr-btf_type_tag-var.c
llvm/test/Bitcode/attr-btf_type_tag.ll
llvm/test/DebugInfo/attr-btf_type_tag.ll

Modified: 
clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/CodeGen/CGDebugInfo.h
llvm/include/llvm/IR/DIBuilder.h
llvm/lib/IR/DIBuilder.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 64dd70f837f7b..2b9532534e3aa 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -929,8 +929,28 @@ static llvm::dwarf::Tag getNextQualifier(Qualifiers ) {
   return (llvm::dwarf::Tag)0;
 }
 
-llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
-   llvm::DIFile *Unit) {
+// Strip MacroQualifiedTypeLoc and AttributedTypeLoc
+// as their corresponding types will be ignored
+// during code generation. Stripping them allows
+// to maintain proper TypeLoc for a given type
+// during code generation.
+static TypeLoc StripMacroAttributed(TypeLoc TL) {
+  if (!TL)
+return TL;
+
+  while (true) {
+if (auto MTL = TL.getAs())
+  TL = MTL.getInnerLoc();
+else if (auto ATL = TL.getAs())
+  TL = ATL.getModifiedLoc();
+else
+  break;
+  }
+  return TL;
+}
+
+llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile *Unit,
+   TypeLoc TL) {
   QualifierCollector Qc;
   const Type *T = Qc.strip(Ty);
 
@@ -944,7 +964,15 @@ llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
 return getOrCreateType(QualType(T, 0), Unit);
   }
 
-  auto *FromTy = getOrCreateType(Qc.apply(CGM.getContext(), T), Unit);
+  QualType NextTy = Qc.apply(CGM.getContext(), T);
+  TypeLoc NextTL;
+  if (NextTy.hasQualifiers())
+NextTL = TL;
+  else if (TL) {
+if (auto QTL = TL.getAs())
+  NextTL = StripMacroAttributed(QTL.getNextTypeLoc());
+  }
+  auto *FromTy = getOrCreateType(NextTy, Unit, NextTL);
 
   // No need to fill in the Name, Line, Size, Alignment, Offset in case of
   // CVR derived types.
@@ -988,10 +1016,10 @@ llvm::DIType *CGDebugInfo::CreateType(const 
ObjCObjectPointerType *Ty,
Ty->getPointeeType(), Unit);
 }
 
-llvm::DIType *CGDebugInfo::CreateType(const PointerType *Ty,
-  llvm::DIFile *Unit) {
+llvm::DIType *CGDebugInfo::CreateType(const PointerType *Ty, llvm::DIFile 
*Unit,
+  TypeLoc TL) {
   return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
-   Ty->getPointeeType(), Unit);
+   Ty->getPointeeType(), Unit, TL);
 }
 
 /// \return whether a C++ mangling exists for the type defined by TD.
@@ -1132,7 +1160,8 @@ CGDebugInfo::getOrCreateRecordFwdDecl(const RecordType 
*Ty,
 llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
  const Type *Ty,
  QualType PointeeTy,
- llvm::DIFile *Unit) {
+ llvm::DIFile *Unit,
+ TypeLoc TL) {
   // Bit size, align and offset of the type.
   // Size is always the size of a pointer. We can't use getTypeSize here
   // because that does not return the correct value for references.
@@ -1142,13 +1171,52 @@ llvm::DIType 
*CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
   Optional DWARFAddressSpace =
   CGM.getTarget().getDWARFAddressSpace(AddressSpace);
 
+  llvm::DINodeArray Annotations = nullptr;
+  TypeLoc NextTL;
+  if (TL) {
+SmallVector Annots;
+NextTL = TL.getNextTypeLoc();
+

Re: [PATCH] D111199: [Clang][LLVM][Attr] support btf_type_tag attribute

2021-11-05 Thread Yonghong Song via cfe-commits



On 11/5/21 1:40 AM, Martin Storsjö via Phabricator wrote:

mstorsjo added a comment.

I went ahead and reverted this, as it caused crashes when compiling a number of 
projects. The most reduced testcase is this:

   $ cat reduced.c
   void a(*);
   void a() {}
   $ clang -c reduced.c -O2 -g

A full case (which reduces into this) is this, 
https://martin.st/temp/iconv-preproc.c , built with `clang -target 
i686-w64-mingw32 -w -c -O2 -g iconv-preproc.c`.



Martin, thanks for reporting. Let me debug this.



Repository:
   rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
   https://reviews.llvm.org/D99/new/

https://reviews.llvm.org/D99


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 737e421 - [Attr] support btf_type_tag attribute

2021-11-04 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2021-11-04T14:23:31-07:00
New Revision: 737e4216c537c33aab8ec51880f06b8a54325b94

URL: 
https://github.com/llvm/llvm-project/commit/737e4216c537c33aab8ec51880f06b8a54325b94
DIFF: 
https://github.com/llvm/llvm-project/commit/737e4216c537c33aab8ec51880f06b8a54325b94.diff

LOG: [Attr] support btf_type_tag attribute

This patch added clang codegen and llvm support
for btf_type_tag support. Currently, btf_type_tag
attribute info is preserved in DebugInfo IR only for
pointer types associated with typedef, global variable
and function declaration. Eventually, such information
is emitted to dwarf.

The following is an example:
  $ cat test.c
  #define __tag __attribute__((btf_type_tag("tag")))
  int __tag *g;
  $ clang -O2 -g -c test.c
  $ llvm-dwarfdump --debug-info test.o
  ...
  0x001e:   DW_TAG_variable
  DW_AT_name  ("g")
  DW_AT_type  (0x0033 "int *")
  DW_AT_external  (true)
  DW_AT_decl_file ("/home/yhs/test.c")
  DW_AT_decl_line (2)
  DW_AT_location  (DW_OP_addr 0x0)

  0x0033:   DW_TAG_pointer_type
  DW_AT_type  (0x0042 "int")

  0x0038: DW_TAG_LLVM_annotation
DW_AT_name("btf_type_tag")
DW_AT_const_value ("tag")

  0x0041: NULL

  0x0042:   DW_TAG_base_type
  DW_AT_name  ("int")
  DW_AT_encoding  (DW_ATE_signed)
  DW_AT_byte_size (0x04)

  0x0049:   NULL

Basically, a DW_TAG_LLVM_annotation tag will be inserted
under DW_TAG_pointer_type tag if that pointer has a btf_type_tag
associated with it.

Differential Revision: https://reviews.llvm.org/D99

Added: 
clang/test/CodeGen/attr-btf_type_tag-func.c
clang/test/CodeGen/attr-btf_type_tag-typedef-field.c
clang/test/CodeGen/attr-btf_type_tag-var.c
llvm/test/Bitcode/attr-btf_type_tag.ll
llvm/test/DebugInfo/attr-btf_type_tag.ll

Modified: 
clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/CodeGen/CGDebugInfo.h
llvm/include/llvm/IR/DIBuilder.h
llvm/lib/IR/DIBuilder.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 64dd70f837f7..9813c01beef3 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -929,8 +929,28 @@ static llvm::dwarf::Tag getNextQualifier(Qualifiers ) {
   return (llvm::dwarf::Tag)0;
 }
 
-llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
-   llvm::DIFile *Unit) {
+// Strip MacroQualifiedTypeLoc and AttributedTypeLoc
+// as their corresponding types will be ignored
+// during code generation. Stripping them allows
+// to maintain proper TypeLoc for a given type
+// during code generation.
+static TypeLoc StripMacroAttributed(TypeLoc TL) {
+  if (!TL)
+return TL;
+
+  while (true) {
+if (auto MTL = TL.getAs())
+  TL = MTL.getInnerLoc();
+else if (auto ATL = TL.getAs())
+  TL = ATL.getModifiedLoc();
+else
+  break;
+  }
+  return TL;
+}
+
+llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile *Unit,
+   TypeLoc TL) {
   QualifierCollector Qc;
   const Type *T = Qc.strip(Ty);
 
@@ -944,7 +964,15 @@ llvm::DIType *CGDebugInfo::CreateQualifiedType(QualType Ty,
 return getOrCreateType(QualType(T, 0), Unit);
   }
 
-  auto *FromTy = getOrCreateType(Qc.apply(CGM.getContext(), T), Unit);
+  QualType NextTy = Qc.apply(CGM.getContext(), T);
+  TypeLoc NextTL;
+  if (NextTy.hasQualifiers())
+NextTL = TL;
+  else if (TL) {
+if (auto QTL = TL.getAs())
+  NextTL = StripMacroAttributed(QTL.getNextTypeLoc());
+  }
+  auto *FromTy = getOrCreateType(NextTy, Unit, NextTL);
 
   // No need to fill in the Name, Line, Size, Alignment, Offset in case of
   // CVR derived types.
@@ -988,10 +1016,10 @@ llvm::DIType *CGDebugInfo::CreateType(const 
ObjCObjectPointerType *Ty,
Ty->getPointeeType(), Unit);
 }
 
-llvm::DIType *CGDebugInfo::CreateType(const PointerType *Ty,
-  llvm::DIFile *Unit) {
+llvm::DIType *CGDebugInfo::CreateType(const PointerType *Ty, llvm::DIFile 
*Unit,
+  TypeLoc TL) {
   return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
-   Ty->getPointeeType(), Unit);
+   Ty->getPointeeType(), Unit, TL);
 }
 
 /// \return whether a C++ mangling exists for the type defined by TD.
@@ -1132,7 +1160,8 @@ CGDebugInfo::getOrCreateRecordFwdDecl(const RecordType 
*Ty,
 llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
  const Type *Ty,
  

[clang] eb0fa8b - [Clang][Attr] Support btf_type_tag attribute

2021-11-04 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2021-11-04T13:59:18-07:00
New Revision: eb0fa8bfa356d49198f98b878b004bce59232bb0

URL: 
https://github.com/llvm/llvm-project/commit/eb0fa8bfa356d49198f98b878b004bce59232bb0
DIFF: 
https://github.com/llvm/llvm-project/commit/eb0fa8bfa356d49198f98b878b004bce59232bb0.diff

LOG: [Clang][Attr] Support btf_type_tag attribute

This patch introduced btf_type_tag attribute. The attribute
is a type attribute and intends to address the below
linux use cases.
typedef int __user *__intp;
int foo(int __user *arg, ...)
static int do_execve(struct filename *filename,
const char __user *const __user *__argv,
const char __user *const __user *__envp)

Here __user in the kernel defined as
__attribute__((noderef, address_space(__user)))
for sparse ([1]) type checking mode.

For normal clang compilation, we intend to replace it with
__attribute__((btf_type_tag("user")))
and record such informaiton in dwarf and BTF so such
information later can be used in kernel for bpf verification
or for other tracing functionalities.

  [1] https://www.kernel.org/doc/html/v4.11/dev-tools/sparse.html

Differential Revision: https://reviews.llvm.org/D99

Added: 
clang/test/Sema/attr-btf_type_tag.c

Modified: 
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/lib/AST/TypePrinter.cpp
clang/lib/Sema/SemaType.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 31ca7d21b902..a5443c967bf6 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1845,6 +1845,13 @@ def BTFDeclTag : InheritableAttr {
   let LangOpts = [COnly];
 }
 
+def BTFTypeTag : TypeAttr {
+  let Spellings = [Clang<"btf_type_tag">];
+  let Args = [StringArgument<"BTFTypeTag">];
+  let Documentation = [BTFTypeTagDocs];
+  let LangOpts = [COnly];
+}
+
 def WebAssemblyExportName : InheritableAttr,
 TargetSpecificAttr {
   let Spellings = [Clang<"export_name">];

diff  --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 09477d6c4423..e7afb3699eb1 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2023,6 +2023,23 @@ section too.
   }];
 }
 
+def BTFTypeTagDocs : Documentation {
+  let Category = DocCatType;
+  let Content = [{
+Clang supports the ``__attribute__((btf_type_tag("ARGUMENT")))`` attribute for
+all targets. It only has effect when ``-g`` is specified on the command line 
and
+is currently silently ignored when not applied to a pointer type (note: this
+scenario may be diagnosed in the future).
+
+The ``ARGUMENT`` string will be preserved in IR and emitted to DWARF for the
+types used in variable declarations, function declarations, or typedef
+declarations.
+
+For BPF targets, the ``ARGUMENT`` string will also be emitted to .BTF ELF
+section.
+  }];
+}
+
 def MipsInterruptDocs : Documentation {
   let Category = DocCatFunction;
   let Heading = "interrupt (MIPS)";

diff  --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 40127f18ce46..eca9af3e5f36 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1746,6 +1746,9 @@ void TypePrinter::printAttributedAfter(const 
AttributedType *T,
   case attr::ArmMveStrictPolymorphism:
 OS << "__clang_arm_mve_strict_polymorphism";
 break;
+  case attr::BTFTypeTag:
+OS << "btf_type_tag";
+break;
   }
   OS << "))";
 }

diff  --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 5918876c02bf..3512165ffdbf 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -5900,6 +5900,9 @@ namespace {
 void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
   Visit(TL.getUnqualifiedLoc());
 }
+// Allow to fill pointee's type locations, e.g.,
+//   int __attr * __attr * __attr *p;
+void VisitPointerTypeLoc(PointerTypeLoc TL) { Visit(TL.getNextTypeLoc()); }
 void VisitTypedefTypeLoc(TypedefTypeLoc TL) {
   TL.setNameLoc(DS.getTypeSpecTypeLoc());
 }
@@ -6500,6 +6503,34 @@ QualType Sema::BuildAddressSpaceAttr(QualType , Expr 
*AddrSpace,
   return BuildAddressSpaceAttr(T, ASIdx, AddrSpace, AttrLoc);
 }
 
+static void HandleBTFTypeTagAttribute(QualType , const ParsedAttr ,
+  TypeProcessingState ) {
+  Sema  = State.getSema();
+
+  // Check the number of attribute arguments.
+  if (Attr.getNumArgs() != 1) {
+S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
+<< Attr << 1;
+Attr.setInvalid();
+return;
+  }
+
+  // Ensure the argument is a string.
+  auto *StrLiteral = dyn_cast(Attr.getArgAsExpr(0));
+  if (!StrLiteral) {
+S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
+<< Attr << AANT_ArgumentString;
+Attr.setInvalid();
+ 

[clang] f6811ce - [DebugInfo] Support typedef with btf_decl_tag attributes

2021-10-21 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2021-10-21T08:42:58-07:00
New Revision: f6811cec84218912d1c7c9b0b8d308834e6e24e3

URL: 
https://github.com/llvm/llvm-project/commit/f6811cec84218912d1c7c9b0b8d308834e6e24e3
DIFF: 
https://github.com/llvm/llvm-project/commit/f6811cec84218912d1c7c9b0b8d308834e6e24e3.diff

LOG: [DebugInfo] Support typedef with btf_decl_tag attributes

Clang patch ([1]) added support for btf_decl_tag attributes with typedef
types. This patch added llvm support including dwarf generation.
For example, for typedef
   typedef unsigned * __u __attribute__((btf_decl_tag("tag1")));
   __u u;
the following shows llvm-dwarfdump result:
   0x0033:   DW_TAG_typedef
   DW_AT_type  (0x0048 "unsigned int *")
   DW_AT_name  ("__u")
   DW_AT_decl_file ("/home/yhs/work/tests/llvm/btf_tag/t.c")
   DW_AT_decl_line (1)

   0x003e: DW_TAG_LLVM_annotation
 DW_AT_name("btf_decl_tag")
 DW_AT_const_value ("tag1")

   0x0047: NULL

  [1] https://reviews.llvm.org/D110127

Differential Revision: https://reviews.llvm.org/D110129

Added: 
clang/test/CodeGen/attr-btf_tag-typedef.c
llvm/test/Bitcode/attr-btf_tag-typedef.ll
llvm/test/DebugInfo/X86/attr-btf_tag-typedef.ll

Modified: 
clang/lib/CodeGen/CGDebugInfo.cpp
llvm/include/llvm/IR/DIBuilder.h
llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
llvm/lib/IR/DIBuilder.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 132b5c28e8f55..6e477d40b83e6 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1276,9 +1276,11 @@ llvm::DIType *CGDebugInfo::CreateType(const TypedefType 
*Ty,
 
   uint32_t Align = getDeclAlignIfRequired(Ty->getDecl(), CGM.getContext());
   // Typedefs are derived from some other type.
+  llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(Ty->getDecl());
   return DBuilder.createTypedef(Underlying, Ty->getDecl()->getName(),
 getOrCreateFile(Loc), getLineNumber(Loc),
-getDeclContextDescriptor(Ty->getDecl()), 
Align);
+getDeclContextDescriptor(Ty->getDecl()), Align,
+Annotations);
 }
 
 static unsigned getDwarfCC(CallingConv CC) {

diff  --git a/clang/test/CodeGen/attr-btf_tag-typedef.c 
b/clang/test/CodeGen/attr-btf_tag-typedef.c
new file mode 100644
index 0..57aafde15893d
--- /dev/null
+++ b/clang/test/CodeGen/attr-btf_tag-typedef.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -debug-info-kind=limited -S 
-emit-llvm -o - %s | FileCheck %s
+
+#define __tag1 __attribute__((btf_decl_tag("tag1")))
+typedef struct { int a; } __s __tag1;
+typedef unsigned * __u __tag1;
+__s a;
+__u u;
+
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "__u", file: ![[#]], line: 
[[#]], baseType: ![[#]], annotations: ![[ANNOT:[0-9]+]])
+// CHECK: ![[ANNOT]] = !{![[TAG1:[0-9]+]]}
+// CHECK: ![[TAG1]] = !{!"btf_decl_tag", !"tag1"}
+
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "__s", file: ![[#]], line: 
[[#]], baseType: ![[#]], annotations: ![[ANNOT]])

diff  --git a/llvm/include/llvm/IR/DIBuilder.h 
b/llvm/include/llvm/IR/DIBuilder.h
index 28c70877aa2e8..90165095bb0c0 100644
--- a/llvm/include/llvm/IR/DIBuilder.h
+++ b/llvm/include/llvm/IR/DIBuilder.h
@@ -250,9 +250,11 @@ namespace llvm {
 /// \param LineNo  Line number.
 /// \param Context The surrounding context for the typedef.
 /// \param AlignInBits Alignment. (optional)
+/// \param Annotations Annotations. (optional)
 DIDerivedType *createTypedef(DIType *Ty, StringRef Name, DIFile *File,
  unsigned LineNo, DIScope *Context,
- uint32_t AlignInBits = 0);
+ uint32_t AlignInBits = 0,
+ DINodeArray Annotations = nullptr);
 
 /// Create debugging information entry for a 'friend'.
 DIDerivedType *createFriend(DIType *Ty, DIType *FriendTy);

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp 
b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index d4a7808b9d1e3..f1af9e2373f81 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -754,6 +754,8 @@ void DwarfUnit::constructTypeDIE(DIE , const 
DIDerivedType *DTy) {
   if (!Name.empty())
 addString(Buffer, dwarf::DW_AT_name, Name);
 
+  addAnnotation(Buffer, DTy->getAnnotations());
+
   // If alignment is specified for a typedef , create and insert 
DW_AT_alignment
   // attribute in DW_TAG_typedef DIE.
   if (Tag == dwarf::DW_TAG_typedef && DD->getDwarfVersion() >= 5) {

diff  --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index 

[clang] b396010 - [Clang] Support typedef with btf_decl_tag attributes

2021-10-21 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2021-10-21T08:41:49-07:00
New Revision: b396010240cda92f5fcfa30cba1b9ad905561eae

URL: 
https://github.com/llvm/llvm-project/commit/b396010240cda92f5fcfa30cba1b9ad905561eae
DIFF: 
https://github.com/llvm/llvm-project/commit/b396010240cda92f5fcfa30cba1b9ad905561eae.diff

LOG: [Clang] Support typedef with btf_decl_tag attributes

Previously, btf_del_tag attribute supports record, field, global variable,
function and function parameter ([1], [2]). This patch added support for 
typedef.
The main reason is for typedef of an anonymous struct/union, we can only apply
btf_decl_tag attribute to the anonymous struct/union like below:
  typedef struct { ... } __btf_decl_tag target_type
In this case, the __btf_decl_tag attribute applies to anonymous struct,
which increases downstream implementation complexity. But if
typedef with btf_decl_tag attribute is supported, we can have
  typedef struct { ... } target_type __btf_decl_tag
which applies __btf_decl_tag to typedef "target_type" which make it
easier to directly associate btf_decl_tag with a named type.
This patch permitted btf_decl_tag with typedef types with this reason.

 [1] https://reviews.llvm.org/D106614
 [2] https://reviews.llvm.org/D111588

Differential Revision: https://reviews.llvm.org/D110127

Added: 


Modified: 
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/test/Misc/pragma-attribute-supported-attributes-list.test
clang/test/Sema/attr-btf_tag.c

Removed: 




diff  --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index e94466bd6121a..f58217f8f44ae 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1839,7 +1839,8 @@ def BPFPreserveAccessIndex : InheritableAttr,
 def BTFDeclTag : InheritableAttr {
   let Spellings = [Clang<"btf_decl_tag">];
   let Args = [StringArgument<"BTFDeclTag">];
-  let Subjects = SubjectList<[Var, Function, Record, Field], ErrorDiag>;
+  let Subjects = SubjectList<[Var, Function, Record, Field, TypedefName],
+ ErrorDiag>;
   let Documentation = [BTFDeclTagDocs];
   let LangOpts = [COnly];
 }

diff  --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 3a70f88eff0a2..71f947687a08f 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2016,9 +2016,10 @@ def BTFDeclTagDocs : Documentation {
   let Content = [{
 Clang supports the ``__attribute__((btf_decl_tag("ARGUMENT")))`` attribute for
 all targets. This attribute may be attached to a struct/union, struct/union
-field, function, function parameter or variable declaration. If -g is 
specified,
-the ``ARGUMENT`` info will be preserved in IR and be emitted to dwarf.
-For BPF targets, the ``ARGUMENT`` info will be emitted to .BTF ELF section too.
+field, function, function parameter, variable or typedef declaration. If -g is
+specified, the ``ARGUMENT`` info will be preserved in IR and be emitted to
+dwarf. For BPF targets, the ``ARGUMENT`` info will be emitted to .BTF ELF
+section too.
   }];
 }
 

diff  --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test 
b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index d4cd73f5e9bce..199934b2791da 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -22,7 +22,7 @@
 // CHECK-NEXT: Assumption (SubjectMatchRule_function, 
SubjectMatchRule_objc_method)
 // CHECK-NEXT: Availability ((SubjectMatchRule_record, SubjectMatchRule_enum, 
SubjectMatchRule_enum_constant, SubjectMatchRule_field, 
SubjectMatchRule_function, SubjectMatchRule_namespace, 
SubjectMatchRule_objc_category, SubjectMatchRule_objc_implementation, 
SubjectMatchRule_objc_interface, SubjectMatchRule_objc_method, 
SubjectMatchRule_objc_property, SubjectMatchRule_objc_protocol, 
SubjectMatchRule_record, SubjectMatchRule_type_alias, 
SubjectMatchRule_variable))
 // CHECK-NEXT: BPFPreserveAccessIndex (SubjectMatchRule_record)
-// CHECK-NEXT: BTFDeclTag (SubjectMatchRule_variable, 
SubjectMatchRule_function, SubjectMatchRule_record, SubjectMatchRule_field)
+// CHECK-NEXT: BTFDeclTag (SubjectMatchRule_variable, 
SubjectMatchRule_function, SubjectMatchRule_record, SubjectMatchRule_field, 
SubjectMatchRule_type_alias)
 // CHECK-NEXT: BuiltinAlias (SubjectMatchRule_function)
 // CHECK-NEXT: CFAuditedTransfer (SubjectMatchRule_function)
 // CHECK-NEXT: CFConsumed (SubjectMatchRule_variable_is_parameter)

diff  --git a/clang/test/Sema/attr-btf_tag.c b/clang/test/Sema/attr-btf_tag.c
index 4f2a5dd57ad93..d33ccdf962825 100644
--- a/clang/test/Sema/attr-btf_tag.c
+++ b/clang/test/Sema/attr-btf_tag.c
@@ -25,18 +25,26 @@ int i1 __invalid; // expected-error {{'btf_decl_tag' 
attribute requires a string
 
 enum e1 {
   E1
-} 

[clang] a162b67 - [Clang][Attr] rename btf_tag to btf_decl_tag

2021-10-11 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2021-10-11T22:17:17-07:00
New Revision: a162b67c98066218d0d00aa13b99afb95d9bb5e6

URL: 
https://github.com/llvm/llvm-project/commit/a162b67c98066218d0d00aa13b99afb95d9bb5e6
DIFF: 
https://github.com/llvm/llvm-project/commit/a162b67c98066218d0d00aa13b99afb95d9bb5e6.diff

LOG: [Clang][Attr] rename btf_tag to btf_decl_tag

Current btf_tag is applied to declaration only.
Per discussion in https://reviews.llvm.org/D99,
we plan to introduce btf_type_tag attribute for types.
So rename btf_tag to btf_decl_tag to make it easily
differentiable from btf_type_tag.

Differential Revision: https://reviews.llvm.org/D111588

Added: 


Modified: 
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/include/clang/Sema/Sema.h
clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/CodeGen/CGDebugInfo.h
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/CodeGen/attr-btf_tag-dicomposite-2.c
clang/test/CodeGen/attr-btf_tag-dicomposite.c
clang/test/CodeGen/attr-btf_tag-diglobalvariable.c
clang/test/CodeGen/attr-btf_tag-disubprogram-callsite.c
clang/test/CodeGen/attr-btf_tag-disubprogram.c
clang/test/CodeGen/attr-btf_tag-field.c
clang/test/CodeGen/attr-btf_tag-parameter.c
clang/test/Misc/pragma-attribute-supported-attributes-list.test
clang/test/Sema/attr-btf_tag.c

Removed: 




diff  --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index c39657e6c8351..6d31b2906bc58 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1836,11 +1836,11 @@ def BPFPreserveAccessIndex : InheritableAttr,
   let LangOpts = [COnly];
 }
 
-def BTFTag : InheritableAttr {
-  let Spellings = [Clang<"btf_tag">];
-  let Args = [StringArgument<"BTFTag">];
+def BTFDeclTag : InheritableAttr {
+  let Spellings = [Clang<"btf_decl_tag">];
+  let Args = [StringArgument<"BTFDeclTag">];
   let Subjects = SubjectList<[Var, Function, Record, Field], ErrorDiag>;
-  let Documentation = [BTFTagDocs];
+  let Documentation = [BTFDeclTagDocs];
   let LangOpts = [COnly];
 }
 

diff  --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index b2b41c3bb4197..3a70f88eff0a2 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2011,12 +2011,12 @@ preserving struct or union member access debuginfo 
indices of this
 struct or union, similar to clang ``__builtin_preserve_access_index()``.
   }];
 }
-def BTFTagDocs : Documentation {
+def BTFDeclTagDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
-Clang supports the ``__attribute__((btf_tag("ARGUMENT")))`` attribute for all
-targets. This attribute may be attached to a struct/union, struct/union field,
-function, function parameter or variable declaration. If -g is specified,
+Clang supports the ``__attribute__((btf_decl_tag("ARGUMENT")))`` attribute for
+all targets. This attribute may be attached to a struct/union, struct/union
+field, function, function parameter or variable declaration. If -g is 
specified,
 the ``ARGUMENT`` info will be preserved in IR and be emitted to dwarf.
 For BPF targets, the ``ARGUMENT`` info will be emitted to .BTF ELF section too.
   }];

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 4d4d01376e0c0..e09803fddd10e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3390,7 +3390,7 @@ class Sema final {
   EnforceTCBAttr *mergeEnforceTCBAttr(Decl *D, const EnforceTCBAttr );
   EnforceTCBLeafAttr *mergeEnforceTCBLeafAttr(Decl *D,
   const EnforceTCBLeafAttr );
-  BTFTagAttr *mergeBTFTagAttr(Decl *D, const BTFTagAttr );
+  BTFDeclTagAttr *mergeBTFDeclTagAttr(Decl *D, const BTFDeclTagAttr );
 
   void mergeDeclAttributes(NamedDecl *New, Decl *Old,
AvailabilityMergeKind AMK = AMK_Redeclaration);

diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 9c98278aa6221..dcc838562e825 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1424,7 +1424,7 @@ llvm::DIType *CGDebugInfo::createBitFieldType(const 
FieldDecl *BitFieldDecl,
 Offset = BitFieldInfo.StorageSize - BitFieldInfo.Size - Offset;
   uint64_t OffsetInBits = StorageOffsetInBits + Offset;
   llvm::DINode::DIFlags Flags = getAccessFlag(BitFieldDecl->getAccess(), RD);
-  llvm::DINodeArray Annotations = CollectBTFTagAnnotations(BitFieldDecl);
+  llvm::DINodeArray Annotations = CollectBTFDeclTagAnnotations(BitFieldDecl);
   return DBuilder.createBitFieldMemberType(
   RecordTy, Name, File, Line, SizeInBits, OffsetInBits, 
StorageOffsetInBits,
   Flags, DebugType, Annotations);
@@ -1541,7 +1541,7 @@ void CGDebugInfo::CollectRecordNormalField(

[clang] c5fb1a0 - Revert "[Clang] Ignore BTFTag attr if used as a type attribute"

2021-10-11 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2021-10-11T15:34:26-07:00
New Revision: c5fb1a09533ec2ed43a80f39c1592e5ee887ef9e

URL: 
https://github.com/llvm/llvm-project/commit/c5fb1a09533ec2ed43a80f39c1592e5ee887ef9e
DIFF: 
https://github.com/llvm/llvm-project/commit/c5fb1a09533ec2ed43a80f39c1592e5ee887ef9e.diff

LOG: Revert "[Clang] Ignore BTFTag attr if used as a type attribute"

This reverts commit b875343873a584965daf507d73ff1fe71eab1953.

Per discussion in https://reviews.llvm.org/D99, instead to make
existing btf_tag attribute as a type-or-decl attribute, we will
make existing btf_tag attribute as a decl only attribute, and
introduce btf_type_tag as a type only attribute. This will make
it easy for cases like typedef where an attribute may be applied
as either a type attribute or a decl attribute.

Added: 


Modified: 
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/lib/AST/TypePrinter.cpp
clang/lib/Sema/SemaType.cpp
clang/test/Sema/attr-btf_tag.c

Removed: 




diff  --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index bd6510677fac0..c39657e6c8351 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1836,7 +1836,7 @@ def BPFPreserveAccessIndex : InheritableAttr,
   let LangOpts = [COnly];
 }
 
-def BTFTag : DeclOrTypeAttr {
+def BTFTag : InheritableAttr {
   let Spellings = [Clang<"btf_tag">];
   let Args = [StringArgument<"BTFTag">];
   let Subjects = SubjectList<[Var, Function, Record, Field], ErrorDiag>;

diff  --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index d3b0de06e7172..b2b41c3bb4197 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2019,10 +2019,6 @@ targets. This attribute may be attached to a 
struct/union, struct/union field,
 function, function parameter or variable declaration. If -g is specified,
 the ``ARGUMENT`` info will be preserved in IR and be emitted to dwarf.
 For BPF targets, the ``ARGUMENT`` info will be emitted to .BTF ELF section too.
-
-The attribute can also be used as a type qualifier. Right now it is accepted
-and silently ignored in order to permit the linux kernel to build with the
-attribute.
   }];
 }
 

diff  --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 2805916b1f7bb..3c7a6b8b9e953 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1704,7 +1704,6 @@ void TypePrinter::printAttributedAfter(const 
AttributedType *T,
   case attr::UPtr:
   case attr::AddressSpace:
   case attr::CmseNSCall:
-  case attr::BTFTag:
 llvm_unreachable("This attribute should have been handled already");
 
   case attr::NSReturnsRetained:

diff  --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 11a6d3faf2dd6..d2d54281c63e0 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -8127,12 +8127,6 @@ static void processTypeAttrs(TypeProcessingState , 
QualType ,
 case ParsedAttr::IgnoredAttribute:
   break;
 
-case ParsedAttr::AT_BTFTag:
-  // FIXME: Linux kernel may also use this attribute for type casting 
check,
-  // which clang doesn's support for now. Let us ignore them so linux 
kernel
-  // build won't break.
-  attr.setUsedAsTypeAttr();
-  break;
 case ParsedAttr::AT_MayAlias:
   // FIXME: This attribute needs to actually be handled, but if we ignore
   // it it breaks large amounts of Linux software.

diff  --git a/clang/test/Sema/attr-btf_tag.c b/clang/test/Sema/attr-btf_tag.c
index 2ba2515868344..88452fa875b1a 100644
--- a/clang/test/Sema/attr-btf_tag.c
+++ b/clang/test/Sema/attr-btf_tag.c
@@ -40,11 +40,3 @@ int __tag2 __tag3 foo(struct t1 *arg, struct t2 *arg2);
 int __tag1 foo(struct t1 *arg __tag1, struct t2 *arg2) {
   return arg->a + arg2->a;
 }
-
-void * convert(long arg) {
-  /* FIXME: the attribute __tag1 is accepted but didn't really do type 
conversion
-   * or enforce type checking. This is to permit linux kernel build with 
btf_tag
-   * attribute.
-   */
-  return (void __tag1 *)arg;
-}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] b875343 - [Clang] Ignore BTFTag attr if used as a type attribute

2021-09-22 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2021-09-22T13:48:29-07:00
New Revision: b875343873a584965daf507d73ff1fe71eab1953

URL: 
https://github.com/llvm/llvm-project/commit/b875343873a584965daf507d73ff1fe71eab1953
DIFF: 
https://github.com/llvm/llvm-project/commit/b875343873a584965daf507d73ff1fe71eab1953.diff

LOG: [Clang] Ignore BTFTag attr if used as a type attribute

Currently, linux kernel has a __user attribute ([1]) defined as
   __attribute__((noderef, address_space(__user)))
which is used by sparse tool ([2]) to do some
type checking of pointers to user space memory.
During normal compilation, __user will be defined
to nothing so it won't have an impact on compilation.

The btf_tag attribute, which is motivated by
carrying linux kernel annotations into dwarf/BTF,
is introduced in [3]. We intended to define __user as
   __attribute__((btf_tag("user")))
so such information will be encoded in dwarf/BTF
and can be used later by bpf verification or other
tracing tools.

But linux kernel __user attribute is also used during
type conversion which btf_tag doesn't support ([4]) since
such type conversion is only used for compiler analysis
and not encoded in dwarf/btf. Theoretically, it is
possible for clang to understand these tags and
do a sparse-like type checking work. But I would like
to leave that to future work and for now suggest simply
ignore these btf_tag attributes if they are used
as type attributes.

  [1] 
https://github.com/torvalds/linux/blob/master/include/linux/compiler_types.h#L10
  [2] https://sparse.docs.kernel.org/en/latest/
  [3] https://reviews.llvm.org/D106614
  [4] https://github.com/torvalds/linux/blob/master/fs/binfmt_flat.c#L135

Differential Revision: https://reviews.llvm.org/D110116

Added: 


Modified: 
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/lib/AST/TypePrinter.cpp
clang/lib/Sema/SemaType.cpp
clang/test/Sema/attr-btf_tag.c

Removed: 




diff  --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index a54039501a7f7..00e847bc5d2fb 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1835,7 +1835,7 @@ def BPFPreserveAccessIndex : InheritableAttr,
   let LangOpts = [COnly];
 }
 
-def BTFTag : InheritableAttr {
+def BTFTag : DeclOrTypeAttr {
   let Spellings = [Clang<"btf_tag">];
   let Args = [StringArgument<"BTFTag">];
   let Subjects = SubjectList<[Var, Function, Record, Field], ErrorDiag>;

diff  --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index b2b41c3bb4197..d3b0de06e7172 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2019,6 +2019,10 @@ targets. This attribute may be attached to a 
struct/union, struct/union field,
 function, function parameter or variable declaration. If -g is specified,
 the ``ARGUMENT`` info will be preserved in IR and be emitted to dwarf.
 For BPF targets, the ``ARGUMENT`` info will be emitted to .BTF ELF section too.
+
+The attribute can also be used as a type qualifier. Right now it is accepted
+and silently ignored in order to permit the linux kernel to build with the
+attribute.
   }];
 }
 

diff  --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 3c7a6b8b9e953..2805916b1f7bb 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1704,6 +1704,7 @@ void TypePrinter::printAttributedAfter(const 
AttributedType *T,
   case attr::UPtr:
   case attr::AddressSpace:
   case attr::CmseNSCall:
+  case attr::BTFTag:
 llvm_unreachable("This attribute should have been handled already");
 
   case attr::NSReturnsRetained:

diff  --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index d2d54281c63e0..11a6d3faf2dd6 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -8127,6 +8127,12 @@ static void processTypeAttrs(TypeProcessingState , 
QualType ,
 case ParsedAttr::IgnoredAttribute:
   break;
 
+case ParsedAttr::AT_BTFTag:
+  // FIXME: Linux kernel may also use this attribute for type casting 
check,
+  // which clang doesn's support for now. Let us ignore them so linux 
kernel
+  // build won't break.
+  attr.setUsedAsTypeAttr();
+  break;
 case ParsedAttr::AT_MayAlias:
   // FIXME: This attribute needs to actually be handled, but if we ignore
   // it it breaks large amounts of Linux software.

diff  --git a/clang/test/Sema/attr-btf_tag.c b/clang/test/Sema/attr-btf_tag.c
index 88452fa875b1a..2ba2515868344 100644
--- a/clang/test/Sema/attr-btf_tag.c
+++ b/clang/test/Sema/attr-btf_tag.c
@@ -40,3 +40,11 @@ int __tag2 __tag3 foo(struct t1 *arg, struct t2 *arg2);
 int __tag1 foo(struct t1 *arg __tag1, struct t2 *arg2) {
   return arg->a + arg2->a;
 }
+
+void * convert(long arg) {
+  /* FIXME: the attribute __tag1 is accepted but didn't 

[clang] 82d9cb3 - [DebugInfo] convert btf_tag attrs to DI annotations for func parameters

2021-08-26 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2021-08-26T14:27:58-07:00
New Revision: 82d9cb34a2782df04975abb5a86365546ffae867

URL: 
https://github.com/llvm/llvm-project/commit/82d9cb34a2782df04975abb5a86365546ffae867
DIFF: 
https://github.com/llvm/llvm-project/commit/82d9cb34a2782df04975abb5a86365546ffae867.diff

LOG: [DebugInfo] convert btf_tag attrs to DI annotations for func parameters

Generate btf_tag annotations for DILocalVariable. The annotations
are represented as an DINodeArray in DebugInfo.

Differential Revision: https://reviews.llvm.org/D106620

Added: 
clang/test/CodeGen/attr-btf_tag-parameter.c

Modified: 
clang/lib/CodeGen/CGDebugInfo.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 2de933f658009..5993ce8531f8f 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -4367,8 +4367,10 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const 
VarDecl *VD,
   // Create the descriptor for the variable.
   llvm::DILocalVariable *D = nullptr;
   if (ArgNo) {
+llvm::DINodeArray Annotations = CollectBTFTagAnnotations(VD);
 D = DBuilder.createParameterVariable(Scope, Name, *ArgNo, Unit, Line, Ty,
- CGM.getLangOpts().Optimize, Flags);
+ CGM.getLangOpts().Optimize, Flags,
+ Annotations);
   } else {
 // For normal local variable, we will try to find out whether 'VD' is the
 // copy parameter of coroutine.

diff  --git a/clang/test/CodeGen/attr-btf_tag-parameter.c 
b/clang/test/CodeGen/attr-btf_tag-parameter.c
new file mode 100644
index 0..77ca246f68270
--- /dev/null
+++ b/clang/test/CodeGen/attr-btf_tag-parameter.c
@@ -0,0 +1,18 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang -target x86_64 -g -S -emit-llvm -o - %s | FileCheck %s
+
+#define __tag1 __attribute__((btf_tag("tag1")))
+#define __tag2 __attribute__((btf_tag("tag2")))
+
+struct t1 {
+  int a;
+};
+
+int foo(struct t1 __tag1 __tag2 *arg) {
+  return arg->a;
+}
+
+// CHECK: !DILocalVariable(name: "arg", arg: 1, scope: ![[#]], file: ![[#]], 
line: [[#]], type: ![[#]], annotations: ![[ANNOT:[0-9]+]])
+// CHECK: ![[ANNOT]] = !{![[TAG1:[0-9]+]], ![[TAG2:[0-9]+]]}
+// CHECK: ![[TAG1]] = !{!"btf_tag", !"tag1"}
+// CHECK: ![[TAG2]] = !{!"btf_tag", !"tag2"}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] d2d7a90 - [DebugInfo] convert btf_tag attrs to DI annotations for DIGlobalVariable

2021-08-26 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2021-08-26T10:36:33-07:00
New Revision: d2d7a90ceded94251905b7adcd5eb2ac5191896f

URL: 
https://github.com/llvm/llvm-project/commit/d2d7a90ceded94251905b7adcd5eb2ac5191896f
DIFF: 
https://github.com/llvm/llvm-project/commit/d2d7a90ceded94251905b7adcd5eb2ac5191896f.diff

LOG: [DebugInfo] convert btf_tag attrs to DI annotations for DIGlobalVariable

Generate btf_tag annotations for DIGlobalVariable. The annotations
are represented as an DINodeArray in DebugInfo.

Differential Revision: https://reviews.llvm.org/D106619

Added: 
clang/test/CodeGen/attr-btf_tag-diglobalvariable.c

Modified: 
clang/lib/CodeGen/CGDebugInfo.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 57f915028dde..2de933f65800 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -4828,12 +4828,13 @@ void 
CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
 }
 AppendAddressSpaceXDeref(AddressSpace, Expr);
 
+llvm::DINodeArray Annotations = CollectBTFTagAnnotations(D);
 GVE = DBuilder.createGlobalVariableExpression(
 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, 
Unit),
 Var->hasLocalLinkage(), true,
 Expr.empty() ? nullptr : DBuilder.createExpression(Expr),
 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
-Align);
+Align, Annotations);
 Var->addDebugInfo(GVE);
   }
   DeclCache[D->getCanonicalDecl()].reset(GVE);

diff  --git a/clang/test/CodeGen/attr-btf_tag-diglobalvariable.c 
b/clang/test/CodeGen/attr-btf_tag-diglobalvariable.c
new file mode 100644
index ..e8b20a202990
--- /dev/null
+++ b/clang/test/CodeGen/attr-btf_tag-diglobalvariable.c
@@ -0,0 +1,29 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang -target x86_64 -g -S -emit-llvm -o - %s | FileCheck %s
+
+#define __tag1 __attribute__((btf_tag("tag1")))
+#define __tag2 __attribute__((btf_tag("tag2")))
+
+struct t1 {
+  int a;
+};
+struct t1 g1 __tag1 __tag2;
+
+extern struct t1 g2 __tag1 __tag2;
+struct t1 g2;
+
+// CHECK: distinct !DIGlobalVariable(name: "g1", scope: ![[#]], file: ![[#]], 
line: [[#]], type: ![[#]], isLocal: false, isDefinition: true, annotations: 
![[ANNOT:[0-9]+]])
+// CHECK: distinct !DIGlobalVariable(name: "g2", scope: ![[#]], file: ![[#]], 
line: [[#]], type: ![[#]], isLocal: false, isDefinition: true, annotations: 
![[ANNOT]])
+// CHECK: ![[ANNOT]] = !{![[TAG1:[0-9]+]], ![[TAG2:[0-9]+]]}
+// CHECK: ![[TAG1]] = !{!"btf_tag", !"tag1"}
+// CHECK: ![[TAG2]] = !{!"btf_tag", !"tag2"}
+
+extern struct t1 g3 __tag1;
+struct t1 g3 __tag2;
+
+// CHECK: distinct !DIGlobalVariable(name: "g3", scope: ![[#]], file: ![[#]], 
line: [[#]], type: ![[#]], isLocal: false, isDefinition: true, annotations: 
![[ANNOT]])
+
+extern struct t1 g4;
+struct t1 g4 __tag1 __tag2;
+
+// CHECK: distinct !DIGlobalVariable(name: "g4", scope: ![[#]], file: ![[#]], 
line: [[#]], type: ![[#]], isLocal: false, isDefinition: true, annotations: 
![[ANNOT]])



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 2de051b - [DebugInfo] convert btf_tag attrs to DI annotations for DISubprograms

2021-08-26 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2021-08-26T08:54:11-07:00
New Revision: 2de051ba124d92de953ac2420668407f458bcec6

URL: 
https://github.com/llvm/llvm-project/commit/2de051ba124d92de953ac2420668407f458bcec6
DIFF: 
https://github.com/llvm/llvm-project/commit/2de051ba124d92de953ac2420668407f458bcec6.diff

LOG: [DebugInfo] convert btf_tag attrs to DI annotations for DISubprograms

Generate btf_tag annotations for DISubprograms. The annotations
are represented as an DINodeArray in DebugInfo.

Differential Revision: https://reviews.llvm.org/D106618

Added: 
clang/test/CodeGen/attr-btf_tag-disubprogram-callsite.c
clang/test/CodeGen/attr-btf_tag-disubprogram.c

Modified: 
clang/lib/CodeGen/CGDebugInfo.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 989945a1b4ff..57f915028dde 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -3951,10 +3951,13 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, 
SourceLocation Loc,
   unsigned ScopeLine = getLineNumber(ScopeLoc);
   llvm::DISubroutineType *DIFnType = getOrCreateFunctionType(D, FnType, Unit);
   llvm::DISubprogram *Decl = nullptr;
-  if (D)
+  llvm::DINodeArray Annotations = nullptr;
+  if (D) {
 Decl = isa(D)
? getObjCMethodDeclaration(D, DIFnType, LineNo, Flags, SPFlags)
: getFunctionDeclaration(D);
+Annotations = CollectBTFTagAnnotations(D);
+  }
 
   // FIXME: The function declaration we're constructing here is mostly reusing
   // declarations from CXXMethodDecl and not constructing new ones for 
arbitrary
@@ -3963,7 +3966,8 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, 
SourceLocation Loc,
   // are emitted as CU level entities by the backend.
   llvm::DISubprogram *SP = DBuilder.createFunction(
   FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
-  FlagsForDef, SPFlagsForDef, TParamsArray.get(), Decl);
+  FlagsForDef, SPFlagsForDef, TParamsArray.get(), Decl, nullptr,
+  Annotations);
   Fn->setSubprogram(SP);
   // We might get here with a VarDecl in the case we're generating
   // code for the initialization of globals. Do not record these decls
@@ -4022,10 +4026,11 @@ void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, 
SourceLocation Loc,
   if (CGM.getLangOpts().Optimize)
 SPFlags |= llvm::DISubprogram::SPFlagOptimized;
 
+  llvm::DINodeArray Annotations = CollectBTFTagAnnotations(D);
   llvm::DISubprogram *SP = DBuilder.createFunction(
   FDContext, Name, LinkageName, Unit, LineNo,
   getOrCreateFunctionType(D, FnType, Unit), ScopeLine, Flags, SPFlags,
-  TParamsArray.get(), getFunctionDeclaration(D));
+  TParamsArray.get(), getFunctionDeclaration(D), nullptr, Annotations);
 
   if (IsDeclForCallSite)
 Fn->setSubprogram(SP);

diff  --git a/clang/test/CodeGen/attr-btf_tag-disubprogram-callsite.c 
b/clang/test/CodeGen/attr-btf_tag-disubprogram-callsite.c
new file mode 100644
index ..fcba5dd6d8a1
--- /dev/null
+++ b/clang/test/CodeGen/attr-btf_tag-disubprogram-callsite.c
@@ -0,0 +1,19 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang -target x86_64 -g -S -O2 -emit-llvm -o - %s | FileCheck %s
+
+#define __tag1 __attribute__((btf_tag("tag1")))
+#define __tag2 __attribute__((btf_tag("tag2")))
+
+struct t1 {
+  int a;
+};
+
+extern int __tag1 __tag2 foo(struct t1 *);
+int foo2(struct t1 *arg) {
+  return foo(arg);
+}
+
+// CHECK: ![[#]] = !DISubprogram(name: "foo", scope: ![[#]], file: ![[#]], 
line: [[#]], type: ![[#]], flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, 
retainedNodes: ![[#]], annotations: ![[ANNOT:[0-9]+]])
+// CHECK: ![[ANNOT]] = !{![[TAG1:[0-9]+]], ![[TAG2:[0-9]+]]}
+// CHECK: ![[TAG1]] = !{!"btf_tag", !"tag1"}
+// CHECK: ![[TAG2]] = !{!"btf_tag", !"tag2"}

diff  --git a/clang/test/CodeGen/attr-btf_tag-disubprogram.c 
b/clang/test/CodeGen/attr-btf_tag-disubprogram.c
new file mode 100644
index ..4c22e690f8df
--- /dev/null
+++ b/clang/test/CodeGen/attr-btf_tag-disubprogram.c
@@ -0,0 +1,40 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang -target x86_64 -g -S -emit-llvm -o - %s | FileCheck %s
+
+#define __tag1 __attribute__((btf_tag("tag1")))
+#define __tag2 __attribute__((btf_tag("tag2")))
+
+struct t1 {
+  int a;
+};
+
+int __tag1 __tag2 foo(struct t1 *arg) {
+  return arg->a;
+}
+
+// CHECK: distinct !DISubprogram(name: "foo", scope: ![[#]], file: ![[#]], 
line: [[#]], type: ![[#]], scopeLine: [[#]], flags: DIFlagPrototyped, spFlags: 
DISPFlagDefinition, unit: ![[#]], retainedNodes: ![[#]], annotations: 
![[ANNOT:[0-9]+]])
+// CHECK: ![[ANNOT]] = !{![[TAG1:[0-9]+]], ![[TAG2:[0-9]+]]}
+// CHECK: ![[TAG1]] = !{!"btf_tag", !"tag1"}
+// CHECK: ![[TAG2]] = !{!"btf_tag", !"tag2"}
+
+int __tag1 __tag2 foo2(struct t1 *arg);
+int foo2(struct t1 *arg) {
+  return arg->a;
+}
+
+// CHECK: distinct !DISubprogram(name: "foo2", 

[clang] 5ca7131 - [DebugInfo] convert btf_tag attrs to DI annotations for record fields

2021-08-20 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2021-08-20T12:52:51-07:00
New Revision: 5ca7131eb369949ee3adf2d3a562bf7e56ca7422

URL: 
https://github.com/llvm/llvm-project/commit/5ca7131eb369949ee3adf2d3a562bf7e56ca7422
DIFF: 
https://github.com/llvm/llvm-project/commit/5ca7131eb369949ee3adf2d3a562bf7e56ca7422.diff

LOG: [DebugInfo] convert btf_tag attrs to DI annotations for record fields

Generate btf_tag annotations for record fields. The annotations
are represented as an DINodeArray in DebugInfo.

Differential Revision: https://reviews.llvm.org/D106616

Added: 
clang/test/CodeGen/attr-btf_tag-field.c

Modified: 
clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/CodeGen/CGDebugInfo.h

Removed: 




diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 967fa7f1493a..989945a1b4ff 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1377,16 +1377,16 @@ llvm::DIType *CGDebugInfo::createBitFieldType(const 
FieldDecl *BitFieldDecl,
 Offset = BitFieldInfo.StorageSize - BitFieldInfo.Size - Offset;
   uint64_t OffsetInBits = StorageOffsetInBits + Offset;
   llvm::DINode::DIFlags Flags = getAccessFlag(BitFieldDecl->getAccess(), RD);
+  llvm::DINodeArray Annotations = CollectBTFTagAnnotations(BitFieldDecl);
   return DBuilder.createBitFieldMemberType(
   RecordTy, Name, File, Line, SizeInBits, OffsetInBits, 
StorageOffsetInBits,
-  Flags, DebugType);
+  Flags, DebugType, Annotations);
 }
 
-llvm::DIType *
-CGDebugInfo::createFieldType(StringRef name, QualType type, SourceLocation loc,
- AccessSpecifier AS, uint64_t offsetInBits,
- uint32_t AlignInBits, llvm::DIFile *tunit,
- llvm::DIScope *scope, const RecordDecl *RD) {
+llvm::DIType *CGDebugInfo::createFieldType(
+StringRef name, QualType type, SourceLocation loc, AccessSpecifier AS,
+uint64_t offsetInBits, uint32_t AlignInBits, llvm::DIFile *tunit,
+llvm::DIScope *scope, const RecordDecl *RD, llvm::DINodeArray Annotations) 
{
   llvm::DIType *debugType = getOrCreateType(type, tunit);
 
   // Get the location for the field.
@@ -1404,7 +1404,7 @@ CGDebugInfo::createFieldType(StringRef name, QualType 
type, SourceLocation loc,
 
   llvm::DINode::DIFlags flags = getAccessFlag(AS, RD);
   return DBuilder.createMemberType(scope, name, file, line, SizeInBits, Align,
-   offsetInBits, flags, debugType);
+   offsetInBits, flags, debugType, 
Annotations);
 }
 
 void CGDebugInfo::CollectRecordLambdaFields(
@@ -1494,9 +1494,10 @@ void CGDebugInfo::CollectRecordNormalField(
 FieldType = createBitFieldType(field, RecordTy, RD);
   } else {
 auto Align = getDeclAlignIfRequired(field, CGM.getContext());
+llvm::DINodeArray Annotations = CollectBTFTagAnnotations(field);
 FieldType =
 createFieldType(name, type, field->getLocation(), field->getAccess(),
-OffsetInBits, Align, tunit, RecordTy, RD);
+OffsetInBits, Align, tunit, RecordTy, RD, Annotations);
   }
 
   elements.push_back(FieldType);
@@ -2064,6 +2065,9 @@ llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
 }
 
 llvm::DINodeArray CGDebugInfo::CollectBTFTagAnnotations(const Decl *D) {
+  if (!D->hasAttr())
+return nullptr;
+
   SmallVector Annotations;
   for (const auto *I : D->specific_attrs()) {
 llvm::Metadata *Ops[2] = {
@@ -3446,10 +3450,7 @@ llvm::DICompositeType 
*CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
 Flags |= llvm::DINode::FlagExportSymbols;
   }
 
-  llvm::DINodeArray Annotations = nullptr;
-  if (D->hasAttr())
-Annotations = CollectBTFTagAnnotations(D);
-
+  llvm::DINodeArray Annotations = CollectBTFTagAnnotations(D);
   llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
   getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align,
   Flags, Identifier, Annotations);

diff  --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index c0674b4511c7..0d22accb93b6 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -299,7 +299,8 @@ class CGDebugInfo {
 SourceLocation loc, AccessSpecifier AS,
 uint64_t offsetInBits, uint32_t AlignInBits,
 llvm::DIFile *tunit, llvm::DIScope *scope,
-const RecordDecl *RD = nullptr);
+const RecordDecl *RD = nullptr,
+llvm::DINodeArray Annotations = nullptr);
 
   llvm::DIType *createFieldType(StringRef name, QualType type,
 SourceLocation loc, AccessSpecifier AS,

diff  --git a/clang/test/CodeGen/attr-btf_tag-field.c 

[clang] cab12fc - [DebugInfo] convert btf_tag attrs to annotations for DIComposite types

2021-08-19 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2021-08-19T18:01:29-07:00
New Revision: cab12fc28c75ea82b747d636a9d20f0840777299

URL: 
https://github.com/llvm/llvm-project/commit/cab12fc28c75ea82b747d636a9d20f0840777299
DIFF: 
https://github.com/llvm/llvm-project/commit/cab12fc28c75ea82b747d636a9d20f0840777299.diff

LOG: [DebugInfo] convert btf_tag attrs to annotations for DIComposite types

Clang patch D106614 added attribute btf_tag support. This patch
generates btf_tag annotations for DIComposite types.
Each btf_tag annotation is represented as a 2D array of
meta strings. Each record may have more than one
btf_tag annotations.

Differential Revision: https://reviews.llvm.org/D106615

Added: 
clang/test/CodeGen/attr-btf_tag-dicomposite-2.c
clang/test/CodeGen/attr-btf_tag-dicomposite.c

Modified: 
clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/CodeGen/CGDebugInfo.h

Removed: 




diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 81c910f40bf8..967fa7f1493a 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -2063,6 +2063,17 @@ llvm::DINodeArray CGDebugInfo::CollectCXXTemplateParams(
   return CollectTemplateParams(TPList, TAList.asArray(), Unit);
 }
 
+llvm::DINodeArray CGDebugInfo::CollectBTFTagAnnotations(const Decl *D) {
+  SmallVector Annotations;
+  for (const auto *I : D->specific_attrs()) {
+llvm::Metadata *Ops[2] = {
+llvm::MDString::get(CGM.getLLVMContext(), StringRef("btf_tag")),
+llvm::MDString::get(CGM.getLLVMContext(), I->getBTFTag())};
+Annotations.push_back(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
+  }
+  return DBuilder.getOrCreateArray(Annotations);
+}
+
 llvm::DIType *CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile *Unit) {
   if (VTablePtrType)
 return VTablePtrType;
@@ -3435,9 +3446,13 @@ llvm::DICompositeType 
*CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
 Flags |= llvm::DINode::FlagExportSymbols;
   }
 
+  llvm::DINodeArray Annotations = nullptr;
+  if (D->hasAttr())
+Annotations = CollectBTFTagAnnotations(D);
+
   llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
   getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align,
-  Flags, Identifier);
+  Flags, Identifier, Annotations);
 
   // Elements of composite types usually have back to the type, creating
   // uniquing cycles.  Distinct nodes are more efficient.

diff  --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index b01165f85a6c..c0674b4511c7 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -292,6 +292,9 @@ class CGDebugInfo {
   CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TS,
llvm::DIFile *F);
 
+  /// A helper function to collect debug info for btf_tag annotations.
+  llvm::DINodeArray CollectBTFTagAnnotations(const Decl *D);
+
   llvm::DIType *createFieldType(StringRef name, QualType type,
 SourceLocation loc, AccessSpecifier AS,
 uint64_t offsetInBits, uint32_t AlignInBits,

diff  --git a/clang/test/CodeGen/attr-btf_tag-dicomposite-2.c 
b/clang/test/CodeGen/attr-btf_tag-dicomposite-2.c
new file mode 100644
index ..ed937ec28c37
--- /dev/null
+++ b/clang/test/CodeGen/attr-btf_tag-dicomposite-2.c
@@ -0,0 +1,14 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang -target x86_64 -g -S -emit-llvm -o - %s | FileCheck %s
+
+#define __tag1 __attribute__((btf_tag("tag1")))
+#define __tag2 __attribute__((btf_tag("tag2")))
+
+struct __tag1 __tag2 t1;
+
+int foo(struct t1 *arg) {
+  return (int)(long)arg;
+}
+
+// CHECK: define dso_local i32 @foo(
+// CHECK-NOT: annotations

diff  --git a/clang/test/CodeGen/attr-btf_tag-dicomposite.c 
b/clang/test/CodeGen/attr-btf_tag-dicomposite.c
new file mode 100644
index ..514dc4e0ccc1
--- /dev/null
+++ b/clang/test/CodeGen/attr-btf_tag-dicomposite.c
@@ -0,0 +1,52 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang -target x86_64 -g -S -emit-llvm -o - %s | FileCheck %s
+
+#define __tag1 __attribute__((btf_tag("tag1")))
+#define __tag2 __attribute__((btf_tag("tag2")))
+
+struct __tag1 __tag2 t1;
+struct t1 {
+  int a;
+};
+
+int foo(struct t1 *arg) {
+  return arg->a;
+}
+
+// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", 
file: ![[#]], line: [[#]], size: 32, elements: ![[#]], annotations: 
![[ANNOT:[0-9]+]])
+// CHECK: ![[ANNOT]] = !{![[TAG1:[0-9]+]], ![[TAG2:[0-9]+]]}
+// CHECK: ![[TAG1]] = !{!"btf_tag", !"tag1"}
+// CHECK: ![[TAG2]] = !{!"btf_tag", !"tag2"}
+
+struct __tag1 t2;
+struct __tag2 t2 {
+  int a;
+};
+
+int foo2(struct t2 *arg) {
+  return arg->a;
+}
+
+// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t2", 
file: ![[#]], line: [[#]], size: 32, elements: ![[#]], annotations: 

[clang] 1b194ef - [Clang] add btf_tag attribute

2021-08-12 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2021-08-12T16:34:22-07:00
New Revision: 1b194ef1ab3b856afb8458fa9c58408360d292cb

URL: 
https://github.com/llvm/llvm-project/commit/1b194ef1ab3b856afb8458fa9c58408360d292cb
DIFF: 
https://github.com/llvm/llvm-project/commit/1b194ef1ab3b856afb8458fa9c58408360d292cb.diff

LOG: [Clang] add btf_tag attribute

A new attribute btf_tag is added. The syntax looks like
  __attribute__((btf_tag()))

Users may tag a particular structure/member/function/func_parameter/variable
declaration with an arbitrary string and the intention is
that this string is passed to dwarf so it is available for
post-compilation analysis. The string will be also passed
to .BTF section if the target is BPF. For each permitted
declaration, multiple btf_tag's are allowed.
For detailed use cases, please see
  https://lists.llvm.org/pipermail/llvm-dev/2021-June/151009.html

In case that there exist redeclarations, the btf_tag attributes
will be accumulated along with different declarations, and the
last declaration will contain all attributes.

Differential Revision: https://reviews.llvm.org/D106614

Added: 
clang/test/Sema/attr-btf_tag.c

Modified: 
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/Misc/pragma-attribute-supported-attributes-list.test

Removed: 




diff  --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 12d09181a2ea8..13d8c15001c92 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1835,6 +1835,14 @@ def BPFPreserveAccessIndex : InheritableAttr,
   let LangOpts = [COnly];
 }
 
+def BTFTag : InheritableAttr {
+  let Spellings = [Clang<"btf_tag">];
+  let Args = [StringArgument<"BTFTag">];
+  let Subjects = SubjectList<[Var, Function, Record, Field], ErrorDiag>;
+  let Documentation = [BTFTagDocs];
+  let LangOpts = [COnly];
+}
+
 def WebAssemblyExportName : InheritableAttr,
 TargetSpecificAttr {
   let Spellings = [Clang<"export_name">];

diff  --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index c265a877e3b1a..a1206347ae454 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2011,6 +2011,16 @@ preserving struct or union member access debuginfo 
indices of this
 struct or union, similar to clang ``__builtin_preserve_access_index()``.
   }];
 }
+def BTFTagDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+Clang supports the ``__attribute__((btf_tag("ARGUMENT")))`` attribute for all
+targets. This attribute may be attached to a struct/union, struct/union field,
+function, function parameter or variable declaration. If -g is specified,
+the ``ARGUMENT`` info will be preserved in IR and be emitted to dwarf.
+For BPF targets, the ``ARGUMENT`` info will be emitted to .BTF ELF section too.
+  }];
+}
 
 def MipsInterruptDocs : Documentation {
   let Category = DocCatFunction;

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index bcd05a3e027c8..e38f50733bebe 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3363,6 +3363,7 @@ class Sema final {
   EnforceTCBAttr *mergeEnforceTCBAttr(Decl *D, const EnforceTCBAttr );
   EnforceTCBLeafAttr *mergeEnforceTCBLeafAttr(Decl *D,
   const EnforceTCBLeafAttr );
+  BTFTagAttr *mergeBTFTagAttr(Decl *D, const BTFTagAttr );
 
   void mergeDeclAttributes(NamedDecl *New, Decl *Old,
AvailabilityMergeKind AMK = AMK_Redeclaration);

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index eba5141c24c93..2f7cbdb79c0a5 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2674,6 +2674,8 @@ static bool mergeDeclAttribute(Sema , NamedDecl *D,
 NewAttr = S.mergeEnforceTCBAttr(D, *TCBA);
   else if (const auto *TCBLA = dyn_cast(Attr))
 NewAttr = S.mergeEnforceTCBLeafAttr(D, *TCBLA);
+  else if (const auto *BTFA = dyn_cast(Attr))
+NewAttr = S.mergeBTFTagAttr(D, *BTFA);
   else if (Attr->shouldInheritEvenIfAlreadyPresent() || !DeclHasAttr(D, Attr))
 NewAttr = cast(Attr->clone(S.Context));
 

diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 3b3e4a414c78c..30132a298b771 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -6842,6 +6842,30 @@ static void handleBPFPreserveAccessIndexAttr(Sema , 
Decl *D,
   Rec->addAttr(::new (S.Context) BPFPreserveAccessIndexAttr(S.Context, AL));
 }
 
+static bool hasBTFTagAttr(Decl *D, StringRef Tag) {
+  for (const auto *I : D->specific_attrs()) {
+if (I->getBTFTag() == Tag)
+  return true;
+  }
+  return false;
+}
+
+static void 

[clang] 833e9b2 - [BPF] add support for 32 bit registers in inline asm

2021-05-16 Thread Yonghong Song via cfe-commits

Author: Alessandro Decina
Date: 2021-05-16T11:01:47-07:00
New Revision: 833e9b2ea7a7290f8833d524c8f8865558c1016a

URL: 
https://github.com/llvm/llvm-project/commit/833e9b2ea7a7290f8833d524c8f8865558c1016a
DIFF: 
https://github.com/llvm/llvm-project/commit/833e9b2ea7a7290f8833d524c8f8865558c1016a.diff

LOG: [BPF] add support for 32 bit registers in inline asm

Add "w" constraint type which allows selecting 32 bit registers.
32 bit registers were added in 
https://reviews.llvm.org/rGca31c3bb3ff149850b664838fbbc7d40ce571879.

Differential Revision: https://reviews.llvm.org/D102118

Added: 
clang/test/CodeGen/bpf-inline-asm.c
llvm/test/CodeGen/BPF/inlineasm-wreg.ll

Modified: 
clang/lib/Basic/Targets/BPF.cpp
clang/lib/Basic/Targets/BPF.h
llvm/lib/Target/BPF/BPFISelLowering.cpp
llvm/lib/Target/BPF/BPFISelLowering.h

Removed: 




diff  --git a/clang/lib/Basic/Targets/BPF.cpp b/clang/lib/Basic/Targets/BPF.cpp
index 2fe2450b9a654..0b0298df30a57 100644
--- a/clang/lib/Basic/Targets/BPF.cpp
+++ b/clang/lib/Basic/Targets/BPF.cpp
@@ -46,3 +46,14 @@ ArrayRef BPFTargetInfo::getTargetBuiltins() 
const {
   return llvm::makeArrayRef(BuiltinInfo, clang::BPF::LastTSBuiltin -
  Builtin::FirstTSBuiltin);
 }
+
+bool BPFTargetInfo::handleTargetFeatures(std::vector ,
+ DiagnosticsEngine ) {
+  for (const auto  : Features) {
+if (Feature == "+alu32") {
+  HasAlu32 = true;
+}
+  }
+
+  return true;
+}

diff  --git a/clang/lib/Basic/Targets/BPF.h b/clang/lib/Basic/Targets/BPF.h
index 06b451db189af..393a91ff53a51 100644
--- a/clang/lib/Basic/Targets/BPF.h
+++ b/clang/lib/Basic/Targets/BPF.h
@@ -23,6 +23,7 @@ namespace targets {
 
 class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public TargetInfo {
   static const Builtin::Info BuiltinInfo[];
+  bool HasAlu32 = false;
 
 public:
   BPFTargetInfo(const llvm::Triple , const TargetOptions &)
@@ -55,6 +56,8 @@ class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public 
TargetInfo {
  bool Enabled) const override {
 Features[Name] = Enabled;
   }
+  bool handleTargetFeatures(std::vector ,
+DiagnosticsEngine ) override;
 
   ArrayRef getTargetBuiltins() const override;
 
@@ -68,7 +71,16 @@ class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public 
TargetInfo {
   ArrayRef getGCCRegNames() const override { return None; }
 
   bool validateAsmConstraint(const char *,
- TargetInfo::ConstraintInfo ) const override {
+ TargetInfo::ConstraintInfo ) const override {
+switch (*Name) {
+default:
+  break;
+case 'w':
+  if (HasAlu32) {
+Info.setAllowsRegister();
+  }
+  break;
+}
 return true;
   }
 
@@ -93,6 +105,10 @@ class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public 
TargetInfo {
   void fillValidCPUList(SmallVectorImpl ) const override;
 
   bool setCPU(const std::string ) override {
+if (Name == "v3") {
+  HasAlu32 = true;
+}
+
 StringRef CPUName(Name);
 return isValidCPUName(CPUName);
   }

diff  --git a/clang/test/CodeGen/bpf-inline-asm.c 
b/clang/test/CodeGen/bpf-inline-asm.c
new file mode 100644
index 0..d85bcbe02bc3f
--- /dev/null
+++ b/clang/test/CodeGen/bpf-inline-asm.c
@@ -0,0 +1,31 @@
+// REQUIRES: bpf-registered-target
+// RUN: %clang -target bpf -emit-llvm -S -Xclang -target-feature -Xclang 
+alu32 %s -o - | FileCheck %s
+// RUN: %clang -target bpf -emit-llvm -S -mcpu=v3 %s -o - | FileCheck %s
+
+void test_generic_constraints(int var32, long var64) {
+  asm("%0 = %1"
+  : "=r"(var32)
+  : "0"(var32));
+  // CHECK: [[R32_ARG:%[a-zA-Z0-9]+]] = load i32, i32*
+  // CHECK: call i32 asm "$0 = $1", "=r,0"(i32 [[R32_ARG]])
+
+  asm("%0 = %1"
+  : "=r"(var64)
+  : "0"(var64));
+  // CHECK: [[R64_ARG:%[a-zA-Z0-9]+]] = load i64, i64*
+  // CHECK: call i64 asm "$0 = $1", "=r,0"(i64 [[R64_ARG]])
+
+  asm("%0 = %1"
+  : "=r"(var64)
+  : "r"(var64));
+  // CHECK: [[R64_ARG:%[a-zA-Z0-9]+]] = load i64, i64*
+  // CHECK: call i64 asm "$0 = $1", "=r,r"(i64 [[R64_ARG]])
+}
+
+void test_constraint_w(int a) {
+  asm("%0 = %1"
+  : "=w"(a)
+  : "w"(a));
+  // CHECK: [[R32_ARG:%[a-zA-Z0-9]+]] = load i32, i32*
+  // CHECK: call i32 asm "$0 = $1", "=w,w"(i32 [[R32_ARG]])
+}

diff  --git a/llvm/lib/Target/BPF/BPFISelLowering.cpp 
b/llvm/lib/Target/BPF/BPFISelLowering.cpp
index 8b16e0d3a23d0..c543dfcfca953 100644
--- a/llvm/lib/Target/BPF/BPFISelLowering.cpp
+++ b/llvm/lib/Target/BPF/BPFISelLowering.cpp
@@ -220,6 +220,20 @@ bool BPFTargetLowering::isZExtFree(EVT VT1, EVT VT2) const 
{
   return NumBits1 == 32 && NumBits2 == 64;
 }
 
+BPFTargetLowering::ConstraintType
+BPFTargetLowering::getConstraintType(StringRef Constraint) const {
+  if (Constraint.size() == 1) {
+switch (Constraint[0]) {
+

[clang] a2a3ca8 - BPF: emit debuginfo for Function of DeclRefExpr if requested

2021-04-26 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2021-04-26T16:53:25-07:00
New Revision: a2a3ca8d97962d90443ee758e47877e15d7e3832

URL: 
https://github.com/llvm/llvm-project/commit/a2a3ca8d97962d90443ee758e47877e15d7e3832
DIFF: 
https://github.com/llvm/llvm-project/commit/a2a3ca8d97962d90443ee758e47877e15d7e3832.diff

LOG: BPF: emit debuginfo for Function of DeclRefExpr if requested

Commit e3d8ee35e4ad ("reland "[DebugInfo] Support to emit debugInfo
for extern variables"") added support to emit debugInfo for
extern variables if requested by the target. Currently, only
BPF target enables this feature by default.

As BPF ecosystem grows, callback function started to get
support, e.g., recently bpf_for_each_map_elem() is introduced
(https://lwn.net/Articles/846504/) with a callback function as an
argument. In the future we may have something like below as
a demonstration of use case :
extern int do_work(int);
long bpf_helper(void *callback_fn, void *callback_ctx, ...);
long prog_main() {
struct { ... } ctx = { ... };
return bpf_helper(_work, , ...);
}
Basically bpf helper may have a callback function and the
callback function is defined in another file or in the kernel.
In this case, we would like to know the debuginfo types for
do_work(), so the verifier can proper verify the safety of
bpf_helper() call.

For the following example,
extern int do_work(int);
long bpf_helper(void *callback_fn);
long prog() {
return bpf_helper(_work);
}

Currently, there is no debuginfo generated for extern function do_work().
In the IR, we have,
...
define dso_local i64 @prog() local_unnamed_addr #0 !dbg !7 {
entry:
  %call = tail call i64 @bpf_helper(i8* bitcast (i32 (i32)* @do_work to 
i8*)) #2, !dbg !11
  ret i64 %call, !dbg !12
}
...
declare dso_local i32 @do_work(i32) #1
...

This patch added support for the above callback function use case, and
the generated IR looks like below:
...
declare !dbg !17 dso_local i32 @do_work(i32) #1
...
!17 = !DISubprogram(name: "do_work", scope: !1, file: !1, line: 1, type: 
!18, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2)
!18 = !DISubroutineType(types: !19)
!19 = !{!20, !20}
!20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)

The TargetInfo.allowDebugInfoForExternalVar is renamed to
TargetInfo.allowDebugInfoForExternalRef as now it guards
both extern variable and extern function debuginfo generation.

Differential Revision: https://reviews.llvm.org/D100567

Added: 
clang/test/CodeGen/debug-info-extern-callback.c

Modified: 
clang/include/clang/Basic/TargetInfo.h
clang/lib/Basic/Targets/BPF.h
clang/lib/CodeGen/CGExpr.cpp
clang/lib/Sema/SemaDecl.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index 449c026639b90..1655f932dad23 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1538,8 +1538,8 @@ class TargetInfo : public virtual TransferrableTargetInfo,
 
   virtual void setAuxTarget(const TargetInfo *Aux) {}
 
-  /// Whether target allows debuginfo types for decl only variables.
-  virtual bool allowDebugInfoForExternalVar() const { return false; }
+  /// Whether target allows debuginfo types for decl only variables/functions.
+  virtual bool allowDebugInfoForExternalRef() const { return false; }
 
 protected:
   /// Copy type and layout related info.

diff  --git a/clang/lib/Basic/Targets/BPF.h b/clang/lib/Basic/Targets/BPF.h
index 43e55dfbfb2b2..06b451db189af 100644
--- a/clang/lib/Basic/Targets/BPF.h
+++ b/clang/lib/Basic/Targets/BPF.h
@@ -76,7 +76,7 @@ class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public 
TargetInfo {
 return None;
   }
 
-  bool allowDebugInfoForExternalVar() const override { return true; }
+  bool allowDebugInfoForExternalRef() const override { return true; }
 
   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override 
{
 switch (CC) {

diff  --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index b98865971f8bf..2a272bf29e04e 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -2832,8 +2832,21 @@ LValue CodeGenFunction::EmitDeclRefLValue(const 
DeclRefExpr *E) {
 return LV;
   }
 
-  if (const auto *FD = dyn_cast(ND))
-return EmitFunctionDeclLValue(*this, E, FD);
+  if (const auto *FD = dyn_cast(ND)) {
+LValue LV = EmitFunctionDeclLValue(*this, E, FD);
+
+// Emit debuginfo for the function declaration if the target wants to.
+if (getContext().getTargetInfo().allowDebugInfoForExternalRef()) {
+  if (CGDebugInfo *DI = CGM.getModuleDebugInfo()) {
+auto *Fn =
+cast(LV.getPointer(*this)->stripPointerCasts());
+if (!Fn->getSubprogram())
+  DI->EmitFunctionDecl(FD, FD->getLocation(), 

[clang] 283db5f - BPF: fix enum value 0 issue for __builtin_preserve_enum_value()

2021-03-01 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2021-03-01T10:23:24-08:00
New Revision: 283db5f0837d55f91242812003adf6e189ba743e

URL: 
https://github.com/llvm/llvm-project/commit/283db5f0837d55f91242812003adf6e189ba743e
DIFF: 
https://github.com/llvm/llvm-project/commit/283db5f0837d55f91242812003adf6e189ba743e.diff

LOG: BPF: fix enum value 0 issue for __builtin_preserve_enum_value()

Lorenz Bauer reported that the following code will have
compilation error for bpf target:
enum e { TWO };
bpf_core_enum_value_exists(enum e, TWO);
The clang emitted the following error message:
__builtin_preserve_enum_value argument 1 invalid

In SemaChecking, an expression like "*(enum NAME)1" will have
cast kind CK_IntegralToPointer, but "*(enum NAME)0" will have
cast kind CK_NullToPointer. Current implementation only permits
CK_IntegralToPointer, missing enum value 0 case.

This patch permits CK_NullToPointer cast kind and
the above test case can pass now.

Differential Revision: https://reviews.llvm.org/D97659

Added: 


Modified: 
clang/lib/Sema/SemaChecking.cpp
clang/test/CodeGen/builtins-bpf-preserve-field-info-4.c

Removed: 




diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index f67cba189344..ccde2f3164a1 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2626,7 +2626,10 @@ static bool isValidBPFPreserveEnumValueArg(Expr *Arg) {
 return false;
 
   const auto *CE = dyn_cast(UO->getSubExpr());
-  if (!CE || CE->getCastKind() != CK_IntegralToPointer)
+  if (!CE)
+return false;
+  if (CE->getCastKind() != CK_IntegralToPointer &&
+  CE->getCastKind() != CK_NullToPointer)
 return false;
 
   // The integer must be from an EnumConstantDecl.

diff  --git a/clang/test/CodeGen/builtins-bpf-preserve-field-info-4.c 
b/clang/test/CodeGen/builtins-bpf-preserve-field-info-4.c
index e07c680bb370..b167b776e385 100644
--- a/clang/test/CodeGen/builtins-bpf-preserve-field-info-4.c
+++ b/clang/test/CodeGen/builtins-bpf-preserve-field-info-4.c
@@ -4,10 +4,11 @@
 #define _(x, y) (__builtin_preserve_enum_value((x), (y)))
 
 enum AA {
+  VAL0 = 0,
   VAL1 = 2,
   VAL2 = 0x8000UL,
 };
-typedef enum { VAL10 = -2, VAL11 = 0x8000, }  __BB;
+typedef enum { VAL00, VAL10 = -2, VAL11 = 0x8000, }  __BB;
 
 unsigned unit1() {
   return _(*(enum AA *)VAL1, 0) + _(*(__BB *)VAL10, 1);
@@ -17,10 +18,16 @@ unsigned unit2() {
   return _(*(enum AA *)VAL2, 0) + _(*(__BB *)VAL11, 1);
 }
 
+unsigned unit3() {
+  return _(*(enum AA *)VAL0, 0) + _(*(__BB *)VAL00, 1);
+}
+
 // CHECK: @0 = private unnamed_addr constant [7 x i8] c"VAL1:2\00", align 1
 // CHECK: @1 = private unnamed_addr constant [9 x i8] c"VAL10:-2\00", align 1
 // CHECK: @2 = private unnamed_addr constant [17 x i8] c"VAL2:-2147483648\00", 
align 1
 // CHECK: @3 = private unnamed_addr constant [17 x i8] c"VAL11:4294934528\00", 
align 1
+// CHECK: @4 = private unnamed_addr constant [7 x i8] c"VAL0:0\00", align 1
+// CHECK: @5 = private unnamed_addr constant [8 x i8] c"VAL00:0\00", align 1
 
 // CHECK: call i64 @llvm.bpf.preserve.enum.value(i32 0, i8* getelementptr 
inbounds ([7 x i8], [7 x i8]* @0, i32 0, i32 0), i64 0), !dbg !{{[0-9]+}}, 
!llvm.preserve.access.index ![[ENUM_AA:[0-9]+]]
 // CHECK: call i64 @llvm.bpf.preserve.enum.value(i32 1, i8* getelementptr 
inbounds ([9 x i8], [9 x i8]* @1, i32 0, i32 0), i64 1), !dbg !{{[0-9]+}}, 
!llvm.preserve.access.index ![[TYPEDEF_ENUM:[0-9]+]]
@@ -28,5 +35,8 @@ unsigned unit2() {
 // CHECK: call i64 @llvm.bpf.preserve.enum.value(i32 2, i8* getelementptr 
inbounds ([17 x i8], [17 x i8]* @2, i32 0, i32 0), i64 0), !dbg !{{[0-9]+}}, 
!llvm.preserve.access.index ![[ENUM_AA]]
 // CHECK: call i64 @llvm.bpf.preserve.enum.value(i32 3, i8* getelementptr 
inbounds ([17 x i8], [17 x i8]* @3, i32 0, i32 0), i64 1), !dbg !{{[0-9]+}}, 
!llvm.preserve.access.index ![[TYPEDEF_ENUM]]
 
+// CHECK: call i64 @llvm.bpf.preserve.enum.value(i32 4, i8* getelementptr 
inbounds ([7 x i8], [7 x i8]* @4, i32 0, i32 0), i64 0), !dbg !{{[0-9]+}}, 
!llvm.preserve.access.index ![[ENUM_AA]]
+// CHECK: call i64 @llvm.bpf.preserve.enum.value(i32 5, i8* getelementptr 
inbounds ([8 x i8], [8 x i8]* @5, i32 0, i32 0), i64 1), !dbg !{{[0-9]+}}, 
!llvm.preserve.access.index ![[TYPEDEF_ENUM]]
+
 // CHECK: ![[ENUM_AA]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: 
"AA"
 // CHECK: ![[TYPEDEF_ENUM]] = !DIDerivedType(tag: DW_TAG_typedef, name: "__BB"



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D72184: [BPF] support atomic instructions

2020-11-17 Thread Yonghong Song via cfe-commits



On 11/17/20 3:23 AM, Brendan Jackman via Phabricator wrote:

jackmanb added inline comments.



Comment at: llvm/lib/Target/BPF/BPFInstrInfo.td:684
+  let Inst{47-32} = addr{15-0}; // offset
+  let Inst{11-8} = val;
+  let Inst{7-4} = Opc.Value;

yonghong-song wrote:

jackmanb wrote:

jackmanb wrote:

jackmanb wrote:

Sorry I'm a beginner with the LLVM code, could you explain what `val` does? I 
didn't notice this when I looked through here before.

To try and get a clue I tried just removing this line and then compiling the 
following code:

```C
// SPDX-License-Identifier: GPL-2.0
#include 

#include 
#include 
#include 

__u64 test_data_64 = 0;
__u64 test1_result = 0;

SEC("fentry/bpf_fentry_test1")
int BPF_PROG(test1, int a)
{
 /* atomic_fetch_add(_data_64, 1); */
 test1_result = __sync_fetch_and_add(_data_64, 1);
 return 0;
}
```

And I was able to load and run the program, with the kernel on my WIP branch: 
https://github.com/bjackman/linux-bpf/tree/wips/bpf-atomics-v0

The result looks like this:

```shell
$ llvm-objdump -d atomics_test.o

atomics_test.o: file format elf64-bpf


Disassembly of section fentry/bpf_fentry_test1:

 :
0:   b7 01 00 00 01 00 00 00 r1 = 1
1:   18 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r2 = 0 ll
3:   db 12 00 00 01 00 00 00 r1 = atomic_fetch_add((u64 *)(r2 + 0), 
PLEASE submit a bug report to https://bugs.llvm.org/  and include the crash 
backtrace.
Stack dump:
0.  Program arguments: llvm-objdump -d atomics_test.o
Segmentation fault
```

Aside from the fact that llvm-objdump crashed, the encoding `db 12 00 00 01 00 
00 00` seems correct to me. If I add the `let Inst{11-8} = val` back in I get 
`db 12 00 00 01 01 00 00` which I don't understand.

Ah wait, I guess this is adding a 3rd operand register? In my example it's 
unclear because it is R1 which is also the dst operand. I was envisaging we 
just have semantics like `src = atomic_fetch_add(dst+off, src)` but you are 
instead proposing `dst = atomic_fetch_add(dst+off, val)`?

Sorry I mean `dst = atomic_fetch_add(src+off, val)`
Sorry I'm a beginner with the LLVM code, could you explain what `val` does? I 
didn't notice this when I looked through here before.


For the below statement:
   test1_result = __sync_fetch_and_add(_data_64, 1);

'val' represents the register which holds the value '1'.

bit 4-7 is also used in compare-and-exchange insn as you need a memory 
location, in-register old/new values.



To try and get a clue I tried just removing this line and then compiling the 
following code:

```C
// SPDX-License-Identifier: GPL-2.0
#include 

#include 
#include 
#include 

__u64 test_data_64 = 0;
__u64 test1_result = 0;

SEC("fentry/bpf_fentry_test1")
int BPF_PROG(test1, int a)
{
 /* atomic_fetch_add(_data_64, 1); */
 test1_result = __sync_fetch_and_add(_data_64, 1);
 return 0;
}
```

And I was able to load and run the program, with the kernel on my WIP branch: 
https://github.com/bjackman/linux-bpf/tree/wips/bpf-atomics-v0

The result looks like this:

```shell
$ llvm-objdump -d atomics_test.o

atomics_test.o: file format elf64-bpf


Disassembly of section fentry/bpf_fentry_test1:

 :
0:   b7 01 00 00 01 00 00 00 r1 = 1
1:   18 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r2 = 0 ll
3:   db 12 00 00 01 00 00 00 r1 = atomic_fetch_add((u64 *)(r2 + 0), 
PLEASE submit a bug report to https://bugs.llvm.org/  and include the crash 
backtrace.
Stack dump:
0.  Program arguments: llvm-objdump -d atomics_test.o
Segmentation fault
```



the crash may come from that the 'val' is not encoded properly. I will double 
check.


Aside from the fact that llvm-objdump crashed, the encoding `db 12 00 00 01 00 
00 00` seems correct to me. If I add the `let Inst{11-8} = val` back in I get 
`db 12 00 00 01 01 00 00` which I don't understand.


in this particular case, yes, as final asm code looks like
r1 = atomic_fetch_add((u64 *)(r2 + 0), r1)
where the value "r1" and the result "r1" shared the same register. A little bit compiler 
work is need to enforce "val" register and result register always the same.

My current design allows:
   r3 = atomic_fetch_add((u64 *)(r2 + 0), r1)
and I think this is more flexible as people may later on still use "r1". But 
let me know whether you prefer
   r1 = atomic_fetch_add((u64 *)(r2 + 0), r1)
always.



Got it - this design will introduce some impedance mismatch with x86, since 
XADD has only two operands (`r3 = atomic_fetch_add((u64 *)(r2 + 0), r1)` cannot 
be implemented in a single instruction). It also hard-codes RAX as the third 
operand for [cmp]xchg so my current kernel implementation hard-codes R0 - 
that's also what Alexei supported in the separate email thread.

Will you be available to discuss this in the BPF office hours this week? There 
are a few possible ways forward, we just need 

[clang] 4369223 - BPF: make __builtin_btf_type_id() return 64bit int

2020-11-16 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2020-11-16T07:08:41-08:00
New Revision: 4369223ea73c4b8a3fa9a8a84533125c7d0eea98

URL: 
https://github.com/llvm/llvm-project/commit/4369223ea73c4b8a3fa9a8a84533125c7d0eea98
DIFF: 
https://github.com/llvm/llvm-project/commit/4369223ea73c4b8a3fa9a8a84533125c7d0eea98.diff

LOG: BPF: make __builtin_btf_type_id() return 64bit int

Linux kernel recently added support for kernel modules
  https://lore.kernel.org/bpf/20201110011932.3201430-5-and...@kernel.org/

In such cases, a type id in the kernel needs to be presented
as (btf id for modules, btf type id for this module).
Change __builtin_btf_type_id() to return 64bit value
so libbpf can do the above encoding.

Differential Revision: https://reviews.llvm.org/D91489

Added: 


Modified: 
clang/include/clang/Basic/BuiltinsBPF.def
clang/lib/Sema/SemaChecking.cpp
clang/test/CodeGen/builtin-bpf-btf-type-id.c
llvm/include/llvm/IR/IntrinsicsBPF.td
llvm/lib/Target/BPF/BPFPreserveDIType.cpp
llvm/lib/Target/BPF/BTFDebug.cpp
llvm/test/CodeGen/BPF/BTF/builtin-btf-type-id.ll
llvm/test/CodeGen/BPF/CORE/btf-id-duplicate.ll
llvm/test/CodeGen/BPF/optnone-2.ll

Removed: 




diff  --git a/clang/include/clang/Basic/BuiltinsBPF.def 
b/clang/include/clang/Basic/BuiltinsBPF.def
index 04b45a52cbe7..190062645ec4 100644
--- a/clang/include/clang/Basic/BuiltinsBPF.def
+++ b/clang/include/clang/Basic/BuiltinsBPF.def
@@ -21,7 +21,7 @@
 TARGET_BUILTIN(__builtin_preserve_field_info, "Ui.", "t", "")
 
 // Get BTF type id.
-TARGET_BUILTIN(__builtin_btf_type_id, "Ui.", "t", "")
+TARGET_BUILTIN(__builtin_btf_type_id, "LUi.", "t", "")
 
 // Get type information.
 TARGET_BUILTIN(__builtin_preserve_type_info, "Ui.", "t", "")

diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index eacf00c93015..8d4c90c7812f 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2696,6 +2696,8 @@ bool Sema::CheckBPFBuiltinFunctionCall(unsigned BuiltinID,
   kind = diag::err_preserve_enum_value_invalid;
 }
 ReturnUnsignedInt = false;
+  } else if (BuiltinID == BPF::BI__builtin_btf_type_id) {
+ReturnUnsignedInt = false;
   }
 
   if (InvalidArg) {

diff  --git a/clang/test/CodeGen/builtin-bpf-btf-type-id.c 
b/clang/test/CodeGen/builtin-bpf-btf-type-id.c
index bbfbbb877aa7..c8f29ee5fe4a 100644
--- a/clang/test/CodeGen/builtin-bpf-btf-type-id.c
+++ b/clang/test/CodeGen/builtin-bpf-btf-type-id.c
@@ -12,12 +12,12 @@ unsigned test3() {
 }
 
 // CHECK: define dso_local i32 @test1
-// CHECK: call i32 @llvm.bpf.btf.type.id(i32 0, i64 0), !dbg !{{[0-9]+}}, 
!llvm.preserve.access.index ![[INT:[0-9]+]]
+// CHECK: call i64 @llvm.bpf.btf.type.id(i32 0, i64 0), !dbg !{{[0-9]+}}, 
!llvm.preserve.access.index ![[INT:[0-9]+]]
 // CHECK: define dso_local i32 @test2
-// CHECK: call i32 @llvm.bpf.btf.type.id(i32 1, i64 0), !dbg !{{[0-9]+}}, 
!llvm.preserve.access.index ![[INT_POINTER:[0-9]+]]
+// CHECK: call i64 @llvm.bpf.btf.type.id(i32 1, i64 0), !dbg !{{[0-9]+}}, 
!llvm.preserve.access.index ![[INT_POINTER:[0-9]+]]
 // CHECK: define dso_local i32 @test3
-// CHECK: call i32 @llvm.bpf.btf.type.id(i32 2, i64 1), !dbg !{{[0-9]+}}, 
!llvm.preserve.access.index ![[STRUCT_T1:[0-9]+]]
-// CHECK: call i32 @llvm.bpf.btf.type.id(i32 3, i64 1), !dbg !{{[0-9]+}}, 
!llvm.preserve.access.index ![[TYPEDEF_T1:[0-9]+]]
+// CHECK: call i64 @llvm.bpf.btf.type.id(i32 2, i64 1), !dbg !{{[0-9]+}}, 
!llvm.preserve.access.index ![[STRUCT_T1:[0-9]+]]
+// CHECK: call i64 @llvm.bpf.btf.type.id(i32 3, i64 1), !dbg !{{[0-9]+}}, 
!llvm.preserve.access.index ![[TYPEDEF_T1:[0-9]+]]
 //
 // CHECK: ![[INT]] = !DIBasicType(name: "int", size: 32, encoding: 
DW_ATE_signed
 // CHECK: ![[INT_POINTER]] = !DIDerivedType(tag: DW_TAG_pointer_type, 
baseType: ![[INT]], size: 64

diff  --git a/llvm/include/llvm/IR/IntrinsicsBPF.td 
b/llvm/include/llvm/IR/IntrinsicsBPF.td
index 651b28748cd3..4b4dd94b1599 100644
--- a/llvm/include/llvm/IR/IntrinsicsBPF.td
+++ b/llvm/include/llvm/IR/IntrinsicsBPF.td
@@ -24,7 +24,7 @@ let TargetPrefix = "bpf" in {  // All intrinsics start with 
"llvm.bpf."
   Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty, llvm_i64_ty],
   [IntrNoMem, ImmArg>]>;
   def int_bpf_btf_type_id : GCCBuiltin<"__builtin_bpf_btf_type_id">,
-  Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty],
+  Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i64_ty],
   [IntrNoMem]>;
   def int_bpf_preserve_type_info : 
GCCBuiltin<"__builtin_bpf_preserve_type_info">,
   Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i64_ty],

diff  --git a/llvm/lib/Target/BPF/BPFPreserveDIType.cpp 
b/llvm/lib/Target/BPF/BPFPreserveDIType.cpp
index 75febbe4b138..18a4f60c171a 100644
--- a/llvm/lib/Target/BPF/BPFPreserveDIType.cpp
+++ b/llvm/lib/Target/BPF/BPFPreserveDIType.cpp
@@ -90,7 +90,7 @@ static bool 

[clang] 000ad1a - [clang] fix a compilation bug

2020-08-16 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2020-08-16T21:53:37-07:00
New Revision: 000ad1a976a537256b17788dcf8b50ca117007b8

URL: 
https://github.com/llvm/llvm-project/commit/000ad1a976a537256b17788dcf8b50ca117007b8
DIFF: 
https://github.com/llvm/llvm-project/commit/000ad1a976a537256b17788dcf8b50ca117007b8.diff

LOG: [clang] fix a compilation bug

With gcc 6.3.0, I hit the following compilation bug:
  /home/yhs/work/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp:
  In function ‘bool ParseCodeGenArgs(clang::CodeGenOptions&, 
llvm::opt::ArgList&,
  clang::InputKind, clang::DiagnosticsEngine&, const clang::TargetOptions&,
  const clang::FrontendOptions&)’:
  /home/yhs/work/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp:780:12:
error: unused variable ‘A’ [-Werror=unused-variable]
 if (Arg *A = Args.getLastArg(OPT_fuse_ctor_homing))
  ^
  cc1plus: all warnings being treated as errors

The bug is introduced by Commit ae6523cd62a4 ("[DebugInfo] Add
-fuse-ctor-homing cc1 flag so we can turn on constructor homing only
if limited debug info is already on.")

Added: 


Modified: 
clang/lib/Frontend/CompilerInvocation.cpp

Removed: 




diff  --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index 86504ed9f92b..3b69eef12b90 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -777,7 +777,7 @@ static bool ParseCodeGenArgs(CodeGenOptions , ArgList 
, InputKind IK,
   }
   // If -fuse-ctor-homing is set and limited debug info is already on, then use
   // constructor homing.
-  if (Arg *A = Args.getLastArg(OPT_fuse_ctor_homing))
+  if (Args.getLastArg(OPT_fuse_ctor_homing))
 if (Opts.getDebugInfo() == codegenoptions::LimitedDebugInfo)
   Opts.setDebugInfo(codegenoptions::DebugInfoConstructor);
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 00602ee - BPF: simplify IR generation for __builtin_btf_type_id()

2020-08-04 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2020-08-04T16:29:42-07:00
New Revision: 00602ee7ef0bf6c68d690a2bd729c12b95c95c99

URL: 
https://github.com/llvm/llvm-project/commit/00602ee7ef0bf6c68d690a2bd729c12b95c95c99
DIFF: 
https://github.com/llvm/llvm-project/commit/00602ee7ef0bf6c68d690a2bd729c12b95c95c99.diff

LOG: BPF: simplify IR generation for __builtin_btf_type_id()

This patch simplified IR generation for __builtin_btf_type_id().
For __builtin_btf_type_id(obj, flag), previously IR builtin
looks like
   if (obj is a lvalue)
 llvm.bpf.btf.type.id(obj.ptr, 1, flag)  !type
   else
 llvm.bpf.btf.type.id(obj, 0, flag)  !type
The purpose of the 2nd argument is to differentiate
   __builtin_btf_type_id(obj, flag) where obj is a lvalue
vs.
   __builtin_btf_type_id(obj.ptr, flag)

Note that obj or obj.ptr is never used by the backend
and the `obj` argument is only used to derive the type.
This code sequence is subject to potential llvm CSE when
  - obj is the same .e.g., nullptr
  - flag is the same
  - metadata type is different, e.g., typedef of struct "s"
and strust "s".
In the above, we don't want CSE since their metadata is different.

This patch change IR builtin to
   llvm.bpf.btf.type.id(seq_num, flag)  !type
and seq_num is always increasing. This will prevent potential
llvm CSE.

Also report an error if the type name is empty for
remote relocation since remote relocation needs non-empty
type name to do relocation against vmlinux.

Differential Revision: https://reviews.llvm.org/D85174

Added: 


Modified: 
clang/lib/CodeGen/CGBuiltin.cpp
clang/test/CodeGen/builtin-bpf-btf-type-id.c
llvm/include/llvm/IR/IntrinsicsBPF.td
llvm/lib/Target/BPF/BPFPreserveDIType.cpp
llvm/test/CodeGen/BPF/BTF/builtin-btf-type-id.ll

Removed: 




diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 18911184aa41..1797dfa05234 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -10961,68 +10961,7 @@ Value *CodeGenFunction::EmitBPFBuiltinExpr(unsigned 
BuiltinID,
 {FieldAddr->getType()});
 return Builder.CreateCall(FnGetFieldInfo, {FieldAddr, InfoKind});
   }
-  case BPF::BI__builtin_btf_type_id: {
-Value *FieldVal = nullptr;
-
-// The LValue cannot be converted Value in order to be used as the function
-// parameter. If it is a structure, it is the "alloca" result of the LValue
-// (a pointer) is used in the parameter. If it is a simple type,
-// the value will be loaded from its corresponding "alloca" and used as
-// the parameter. In our case, let us just get a pointer of the LValue
-// since we do not really use the parameter. The purpose of parameter
-// is to prevent the generated IR llvm.bpf.btf.type.id intrinsic call,
-// which carries metadata, from being changed.
-bool IsLValue = E->getArg(0)->isLValue();
-if (IsLValue)
-  FieldVal = EmitLValue(E->getArg(0)).getPointer(*this);
-else
-  FieldVal = EmitScalarExpr(E->getArg(0));
-
-if (!getDebugInfo()) {
-  CGM.Error(E->getExprLoc(), "using __builtin_btf_type_id() without -g");
-  return nullptr;
-}
-
-// Generate debuginfo type for the first argument.
-llvm::DIType *DbgInfo =
-getDebugInfo()->getOrCreateStandaloneType(E->getArg(0)->getType(),
-  E->getArg(0)->getExprLoc());
-
-ConstantInt *Flag = cast(EmitScalarExpr(E->getArg(1)));
-Value *FlagValue = ConstantInt::get(Int64Ty, Flag->getSExtValue());
-
-// Built the IR for the btf_type_id intrinsic.
-//
-// In the above, we converted LValue argument to a pointer to LValue.
-// For example, the following
-//   int v;
-//   C1: __builtin_btf_type_id(v, flag);
-// will be converted to
-//   L1: llvm.bpf.btf.type.id(, flag)
-// This makes it hard to 
diff erentiate from
-//   C2: __builtin_btf_type_id(, flag);
-// to
-//   L2: llvm.bpf.btf.type.id(, flag)
-//
-// If both C1 and C2 are present in the code, the llvm may later
-// on do CSE on L1 and L2, which will result in incorrect tagged types.
-//
-// The C1->L1 transformation only happens if the argument of
-// __builtin_btf_type_id() is a LValue. So Let us put whether
-// the argument is an LValue or not into generated IR. This should
-// prevent potential CSE from causing debuginfo type loss.
-//
-// The generated IR intrinsics will hence look like
-//   L1: llvm.bpf.btf.type.id(, 1, flag) !di_type_for_{v};
-//   L2: llvm.bpf.btf.type.id(, 0, flag) !di_type_for_{};
-Constant *CV = ConstantInt::get(IntTy, IsLValue);
-llvm::Function *FnBtfTypeId = llvm::Intrinsic::getDeclaration(
-(), llvm::Intrinsic::bpf_btf_type_id,
-{FieldVal->getType(), CV->getType()});
-CallInst *Fn = Builder.CreateCall(FnBtfTypeId, {FieldVal, CV, 

[clang] 6d67506 - [clang][BPF] support type exist/size and enum exist/value relocations

2020-08-04 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2020-08-04T08:39:53-07:00
New Revision: 6d6750696400e7ce988d66a1a00e1d0cb32815f8

URL: 
https://github.com/llvm/llvm-project/commit/6d6750696400e7ce988d66a1a00e1d0cb32815f8
DIFF: 
https://github.com/llvm/llvm-project/commit/6d6750696400e7ce988d66a1a00e1d0cb32815f8.diff

LOG: [clang][BPF] support type exist/size and enum exist/value relocations

This patch added the following additional compile-once
run-everywhere (CO-RE) relocations:
  - existence/size of typedef, struct/union or enum type
  - enum value and enum value existence

These additional relocations will make CO-RE bpf programs more
adaptive for potential kernel internal data structure changes.

For existence/size relocations, the following two code patterns
are supported:
  1. uint32_t __builtin_preserve_type_info(*( *)0, flag);
  2.  var;
 uint32_t __builtin_preserve_field_info(var, flag);
flag = 0 for existence relocation and flag = 1 for size relocation.

For enum value existence and enum value relocations, the following code
pattern is supported:
  uint64_t __builtin_preserve_enum_value(*( *),
 flag);
flag = 0 means existence relocation and flag = 1 for enum value.
relocation. In the above  can be an enum type or
a typedef to enum type. The  needs to be an enumerator
value from the same enum type. The return type is uint64_t to
permit potential 64bit enumerator values.

Differential Revision: https://reviews.llvm.org/D83242

Added: 
clang/test/CodeGen/builtins-bpf-preserve-field-info-3.c
clang/test/CodeGen/builtins-bpf-preserve-field-info-4.c

Modified: 
clang/include/clang/Basic/BuiltinsBPF.def
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/CodeGen/CGBuiltin.cpp
clang/lib/Sema/SemaChecking.cpp
clang/test/Sema/builtins-bpf.c
llvm/include/llvm/IR/IntrinsicsBPF.td

Removed: 




diff  --git a/clang/include/clang/Basic/BuiltinsBPF.def 
b/clang/include/clang/Basic/BuiltinsBPF.def
index 237e9dc8784b..04b45a52cbe7 100644
--- a/clang/include/clang/Basic/BuiltinsBPF.def
+++ b/clang/include/clang/Basic/BuiltinsBPF.def
@@ -23,5 +23,11 @@ TARGET_BUILTIN(__builtin_preserve_field_info, "Ui.", "t", "")
 // Get BTF type id.
 TARGET_BUILTIN(__builtin_btf_type_id, "Ui.", "t", "")
 
+// Get type information.
+TARGET_BUILTIN(__builtin_preserve_type_info, "Ui.", "t", "")
+
+// Preserve enum value.
+TARGET_BUILTIN(__builtin_preserve_enum_value, "Li.", "t", "")
+
 #undef BUILTIN
 #undef TARGET_BUILTIN

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 054b81c4a72b..7bcff3eb4d8c 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10865,6 +10865,14 @@ def err_preserve_field_info_not_const: Error<
   "__builtin_preserve_field_info argument %0 not a constant">;
 def err_btf_type_id_not_const: Error<
   "__builtin_btf_type_id argument %0 not a constant">;
+def err_preserve_type_info_invalid : Error<
+  "__builtin_preserve_type_info argument %0 invalid">;
+def err_preserve_type_info_not_const: Error<
+  "__builtin_preserve_type_info argument %0 not a constant">;
+def err_preserve_enum_value_invalid : Error<
+  "__builtin_preserve_enum_value argument %0 invalid">;
+def err_preserve_enum_value_not_const: Error<
+  "__builtin_preserve_enum_value argument %0 not a constant">;
 
 def err_bit_cast_non_trivially_copyable : Error<
   "__builtin_bit_cast %select{source|destination}0 type must be trivially 
copyable">;

diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 2ef164b8b65a..18911184aa41 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -10921,9 +10921,16 @@ Value 
*CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
 Value *CodeGenFunction::EmitBPFBuiltinExpr(unsigned BuiltinID,
const CallExpr *E) {
   assert((BuiltinID == BPF::BI__builtin_preserve_field_info ||
-  BuiltinID == BPF::BI__builtin_btf_type_id) &&
+  BuiltinID == BPF::BI__builtin_btf_type_id ||
+  BuiltinID == BPF::BI__builtin_preserve_type_info ||
+  BuiltinID == BPF::BI__builtin_preserve_enum_value) &&
  "unexpected BPF builtin");
 
+  // A sequence number, injected into IR builtin functions, to
+  // prevent CSE given the only 
diff erence of the funciton
+  // may just be the debuginfo metadata.
+  static uint32_t BuiltinSeqNum;
+
   switch (BuiltinID) {
   default:
 llvm_unreachable("Unexpected BPF builtin");
@@ -11016,6 +11023,63 @@ Value *CodeGenFunction::EmitBPFBuiltinExpr(unsigned 
BuiltinID,
 Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo);
 return Fn;
   }
+  case BPF::BI__builtin_preserve_type_info: {
+if (!getDebugInfo()) {
+  CGM.Error(E->getExprLoc(), "using 

[clang] 072cde0 - [Clang][BPF] implement __builtin_btf_type_id() builtin function

2020-05-15 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2020-05-15T09:44:54-07:00
New Revision: 072cde03aaa13a2c57acf62d79876bf79aa1919f

URL: 
https://github.com/llvm/llvm-project/commit/072cde03aaa13a2c57acf62d79876bf79aa1919f
DIFF: 
https://github.com/llvm/llvm-project/commit/072cde03aaa13a2c57acf62d79876bf79aa1919f.diff

LOG: [Clang][BPF] implement __builtin_btf_type_id() builtin function

Such a builtin function is mostly useful to preserve btf type id
for non-global data. For example,
   extern void foo(..., void *data, int size);
   int test(...) {
 struct t { int a; int b; int c; } d;
 d.a = ...; d.b = ...; d.c = ...;
 foo(..., , sizeof(d));
   }

The function "foo" in the above only see raw data and does not
know what type of the data is. In certain cases, e.g., logging,
the additional type information will help pretty print.

This patch implemented a BPF specific builtin
  u32 btf_type_id = __builtin_btf_type_id(param, flag)
which will return a btf type id for the "param".
flag == 0 will indicate a BTF local relocation,
which means btf type_id only adjusted when bpf program BTF changes.
flag == 1 will indicate a BTF remote relocation,
which means btf type_id is adjusted against linux kernel or
future other entities.

Differential Revision: https://reviews.llvm.org/D74668

Added: 
clang/test/CodeGen/builtin-bpf-btf-type-id.c
clang/test/Sema/builtin-bpf-btf-type-id.c

Modified: 
clang/include/clang/Basic/BuiltinsBPF.def
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/CodeGen/CGBuiltin.cpp
clang/lib/Sema/SemaChecking.cpp
llvm/include/llvm/IR/IntrinsicsBPF.td

Removed: 




diff  --git a/clang/include/clang/Basic/BuiltinsBPF.def 
b/clang/include/clang/Basic/BuiltinsBPF.def
index bd96b9ef531b..237e9dc8784b 100644
--- a/clang/include/clang/Basic/BuiltinsBPF.def
+++ b/clang/include/clang/Basic/BuiltinsBPF.def
@@ -20,5 +20,8 @@
 // Get record field information.
 TARGET_BUILTIN(__builtin_preserve_field_info, "Ui.", "t", "")
 
+// Get BTF type id.
+TARGET_BUILTIN(__builtin_btf_type_id, "Ui.", "t", "")
+
 #undef BUILTIN
 #undef TARGET_BUILTIN

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 371e20183e1e..0fe8b1e6abfc 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10749,6 +10749,8 @@ def err_preserve_field_info_not_field : Error<
   "__builtin_preserve_field_info argument %0 not a field access">;
 def err_preserve_field_info_not_const: Error<
   "__builtin_preserve_field_info argument %0 not a constant">;
+def err_btf_type_id_not_const: Error<
+  "__builtin_btf_type_id argument %0 not a constant">;
 
 def err_bit_cast_non_trivially_copyable : Error<
   "__builtin_bit_cast %select{source|destination}0 type must be trivially 
copyable">;

diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 5166f91e252c..524924e36638 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -10633,33 +10633,103 @@ Value 
*CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
 
 Value *CodeGenFunction::EmitBPFBuiltinExpr(unsigned BuiltinID,
const CallExpr *E) {
-  assert(BuiltinID == BPF::BI__builtin_preserve_field_info &&
- "unexpected ARM builtin");
+  assert((BuiltinID == BPF::BI__builtin_preserve_field_info ||
+  BuiltinID == BPF::BI__builtin_btf_type_id) &&
+ "unexpected BPF builtin");
 
-  const Expr *Arg = E->getArg(0);
-  bool IsBitField = Arg->IgnoreParens()->getObjectKind() == OK_BitField;
+  switch (BuiltinID) {
+  default:
+llvm_unreachable("Unexpected BPF builtin");
+  case BPF::BI__builtin_preserve_field_info: {
+const Expr *Arg = E->getArg(0);
+bool IsBitField = Arg->IgnoreParens()->getObjectKind() == OK_BitField;
 
-  if (!getDebugInfo()) {
-CGM.Error(E->getExprLoc(), "using builtin_preserve_field_info() without 
-g");
-return IsBitField ? EmitLValue(Arg).getBitFieldPointer()
-  : EmitLValue(Arg).getPointer(*this);
-  }
+if (!getDebugInfo()) {
+  CGM.Error(E->getExprLoc(),
+"using __builtin_preserve_field_info() without -g");
+  return IsBitField ? EmitLValue(Arg).getBitFieldPointer()
+: EmitLValue(Arg).getPointer(*this);
+}
+
+// Enable underlying preserve_*_access_index() generation.
+bool OldIsInPreservedAIRegion = IsInPreservedAIRegion;
+IsInPreservedAIRegion = true;
+Value *FieldAddr = IsBitField ? EmitLValue(Arg).getBitFieldPointer()
+  : EmitLValue(Arg).getPointer(*this);
+IsInPreservedAIRegion = OldIsInPreservedAIRegion;
+
+ConstantInt *C = cast(EmitScalarExpr(E->getArg(1)));
+Value *InfoKind = ConstantInt::get(Int64Ty, C->getSExtValue());
+
+// Built the IR for 

[clang] ced0d1f - [BPF] support 128bit int explicitly in layout spec

2020-03-28 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2020-03-28T11:46:29-07:00
New Revision: ced0d1f42b39bd93b350b2597ce6587d107c26a7

URL: 
https://github.com/llvm/llvm-project/commit/ced0d1f42b39bd93b350b2597ce6587d107c26a7
DIFF: 
https://github.com/llvm/llvm-project/commit/ced0d1f42b39bd93b350b2597ce6587d107c26a7.diff

LOG: [BPF] support 128bit int explicitly in layout spec

Currently, bpf does not specify 128bit alignment in its
layout spec. So for a structure like
  struct ipv6_key_t {
unsigned pid;
unsigned __int128 saddr;
unsigned short lport;
  };
clang will generate IR type
  %struct.ipv6_key_t = type { i32, [12 x i8], i128, i16, [14 x i8] }
Additional padding is to ensure later IR->MIR can generate correct
stack layout with target layout spec.

But it is common practice for a tracing program to be
first compiled with target flag (e.g., x86_64 or aarch64) through
clang to generate IR and then go through llc to generate bpf
byte code. Tracing program often refers to kernel internal
data structures which needs to be compiled with non-bpf target.

But such a compilation model may cause a problem on aarch64.
The bcc issue https://github.com/iovisor/bcc/issues/2827
reported such a problem.

For the above structure, since aarch64 has "i128:128" in its
layout string, the generated IR will have
  %struct.ipv6_key_t = type { i32, i128, i16 }

Since bpf does not have "i128:128" in its spec string,
the selectionDAG assumes alignment 8 for i128 and
computes the stack storage size for the above is 32 bytes,
which leads incorrect code later.

The x86_64 does not have this issue as it does not have
"i128:128" in its layout spec as it does permits i128 to
be alignmented at 8 bytes at stack. Its IR type looks like
  %struct.ipv6_key_t = type { i32, [12 x i8], i128, i16, [14 x i8] }

The fix here is add i128 support in layout spec, the same as
aarch64. The only downside is we may have less optimal stack
allocation in certain cases since we require 16byte alignment
for i128 instead of 8. But this is probably fine as i128 is
not used widely and in most cases users should already
have proper alignment.

Differential Revision: https://reviews.llvm.org/D76587

Added: 
llvm/test/CodeGen/BPF/i128.ll

Modified: 
clang/lib/Basic/Targets/BPF.h
clang/test/CodeGen/target-data.c
llvm/lib/Target/BPF/BPFTargetMachine.cpp

Removed: 




diff  --git a/clang/lib/Basic/Targets/BPF.h b/clang/lib/Basic/Targets/BPF.h
index b2f1831e960e..43e55dfbfb2b 100644
--- a/clang/lib/Basic/Targets/BPF.h
+++ b/clang/lib/Basic/Targets/BPF.h
@@ -35,9 +35,9 @@ class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public 
TargetInfo {
 Int64Type = SignedLong;
 RegParmMax = 5;
 if (Triple.getArch() == llvm::Triple::bpfeb) {
-  resetDataLayout("E-m:e-p:64:64-i64:64-n32:64-S128");
+  resetDataLayout("E-m:e-p:64:64-i64:64-i128:128-n32:64-S128");
 } else {
-  resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128");
+  resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S128");
 }
 MaxAtomicPromoteWidth = 64;
 MaxAtomicInlineWidth = 64;

diff  --git a/clang/test/CodeGen/target-data.c 
b/clang/test/CodeGen/target-data.c
index e49f8453e360..e619843f4bdb 100644
--- a/clang/test/CodeGen/target-data.c
+++ b/clang/test/CodeGen/target-data.c
@@ -245,8 +245,8 @@
 
 // RUN: %clang_cc1 -triple bpfel -o - -emit-llvm %s | \
 // RUN: FileCheck %s -check-prefix=BPFEL
-// BPFEL: target datalayout = "e-m:e-p:64:64-i64:64-n32:64-S128"
+// BPFEL: target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
 
 // RUN: %clang_cc1 -triple bpfeb -o - -emit-llvm %s | \
 // RUN: FileCheck %s -check-prefix=BPFEB
-// BPFEB: target datalayout = "E-m:e-p:64:64-i64:64-n32:64-S128"
+// BPFEB: target datalayout = "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128"

diff  --git a/llvm/lib/Target/BPF/BPFTargetMachine.cpp 
b/llvm/lib/Target/BPF/BPFTargetMachine.cpp
index d2a332c78aa6..4d42e7414075 100644
--- a/llvm/lib/Target/BPF/BPFTargetMachine.cpp
+++ b/llvm/lib/Target/BPF/BPFTargetMachine.cpp
@@ -42,9 +42,9 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void 
LLVMInitializeBPFTarget() {
 // DataLayout: little or big endian
 static std::string computeDataLayout(const Triple ) {
   if (TT.getArch() == Triple::bpfeb)
-return "E-m:e-p:64:64-i64:64-n32:64-S128";
+return "E-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
   else
-return "e-m:e-p:64:64-i64:64-n32:64-S128";
+return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
 }
 
 static Reloc::Model getEffectiveRelocModel(Optional RM) {

diff  --git a/llvm/test/CodeGen/BPF/i128.ll b/llvm/test/CodeGen/BPF/i128.ll
new file mode 100644
index ..c77838fa8bb4
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/i128.ll
@@ -0,0 +1,67 @@
+; RUN: llc -march=bpfel -o - %s | FileCheck %s
+; RUN: llc -march=bpfeb -o - %s | FileCheck %s
+; Source code:
+;   struct ipv6_key_t {
+; unsigned pid;
+; unsigned __int128 saddr;
+; 

[clang] 9271cab - [BPF] use base lvalue type for preserve_{struct, union}_access_index metadata

2020-02-04 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2020-02-04T09:28:30-08:00
New Revision: 9271cab270a52b5200ef45a16f1a9d9baaccaba0

URL: 
https://github.com/llvm/llvm-project/commit/9271cab270a52b5200ef45a16f1a9d9baaccaba0
DIFF: 
https://github.com/llvm/llvm-project/commit/9271cab270a52b5200ef45a16f1a9d9baaccaba0.diff

LOG: [BPF] use base lvalue type for preserve_{struct,union}_access_index 
metadata

Linux commit
  
https://github.com/torvalds/linux/commit/1cf5b23988ea0086a252a5c8b005b075f1e9b030#diff-289313b9fec99c6f0acfea19d9cfd949
uses "#pragma clang attribute push (__attribute__((preserve_access_index)),
  apply_to = record)"
to apply CO-RE relocations to all records including the following pattern:
  #pragma clang attribute push (__attribute__((preserve_access_index)), 
apply_to = record)
  typedef struct {
int a;
  } __t;
  #pragma clang attribute pop
  int test(__t *arg) { return arg->a; }

The current approach to use struct type in the relocation record will
result in an anonymous struct, which make later type matching difficult
in bpf loader. In fact, current BPF backend will fail the above program
with assertion:
  clang: ../lib/Target/BPF/BPFAbstractMemberAccess.cpp:796: ...
 Assertion `TypeName.size()' failed.

The patch use the base lvalue type for the "base" value to annotate
preservee_{struct,union}_access_index intrinsics. In the above example,
the type will be "__t" which preserved the type name.

Differential Revision: https://reviews.llvm.org/D73900

Added: 
clang/test/CodeGen/builtin-preserve-access-index-typedef.c

Modified: 
clang/lib/CodeGen/CGExpr.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 4b8a31c180c8..17fc16a1fe5b 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -4024,17 +4024,17 @@ static Address emitAddrOfFieldStorage(CodeGenFunction 
, Address base,
   return CGF.Builder.CreateStructGEP(base, idx, field->getName());
 }
 
-static Address emitPreserveStructAccess(CodeGenFunction , Address base,
-const FieldDecl *field) {
+static Address emitPreserveStructAccess(CodeGenFunction , LValue base,
+Address addr, const FieldDecl *field) {
   const RecordDecl *rec = field->getParent();
-  llvm::DIType *DbgInfo = CGF.getDebugInfo()->getOrCreateRecordType(
-  CGF.getContext().getRecordType(rec), rec->getLocation());
+  llvm::DIType *DbgInfo = CGF.getDebugInfo()->getOrCreateStandaloneType(
+  base.getType(), rec->getLocation());
 
   unsigned idx =
   CGF.CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field);
 
   return CGF.Builder.CreatePreserveStructAccessIndex(
-  base, idx, CGF.getDebugInfoFIndex(rec, field->getFieldIndex()), DbgInfo);
+  addr, idx, CGF.getDebugInfoFIndex(rec, field->getFieldIndex()), DbgInfo);
 }
 
 static bool hasAnyVptr(const QualType Type, const ASTContext ) {
@@ -4158,8 +4158,8 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
 if (IsInPreservedAIRegion ||
 (getDebugInfo() && rec->hasAttr())) {
   // Remember the original union field index
-  llvm::DIType *DbgInfo = getDebugInfo()->getOrCreateRecordType(
-  getContext().getRecordType(rec), rec->getLocation());
+  llvm::DIType *DbgInfo = 
getDebugInfo()->getOrCreateStandaloneType(base.getType(),
+  rec->getLocation());
   addr = Address(
   Builder.CreatePreserveUnionAccessIndex(
   addr.getPointer(), getDebugInfoFIndex(rec, 
field->getFieldIndex()), DbgInfo),
@@ -4176,7 +4176,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base,
   addr = emitAddrOfFieldStorage(*this, addr, field);
 else
   // Remember the original struct field index
-  addr = emitPreserveStructAccess(*this, addr, field);
+  addr = emitPreserveStructAccess(*this, base, addr, field);
   }
 
   // If this is a reference field, load the reference right now.

diff  --git a/clang/test/CodeGen/builtin-preserve-access-index-typedef.c 
b/clang/test/CodeGen/builtin-preserve-access-index-typedef.c
new file mode 100644
index ..c7752cd23abd
--- /dev/null
+++ b/clang/test/CodeGen/builtin-preserve-access-index-typedef.c
@@ -0,0 +1,24 @@
+// REQUIRES: bpf-registered-target
+// RUN: %clang -target bpf -emit-llvm -S -g %s -o - | FileCheck %s
+
+#pragma clang attribute push (__attribute__((preserve_access_index)), apply_to 
= record)
+typedef struct {
+   int a;
+} __t;
+typedef union {
+   int b;
+} __u;
+#pragma clang attribute pop
+
+int test1(__t *arg) { return arg->a; }
+int test2(const __u *arg) { return arg->b; }
+
+
+// CHECK: define dso_local i32 @test1
+// CHECK: call i32* 
@llvm.preserve.struct.access.index.p0i32.p0s_struct.__ts(%struct.__t* 
%{{[0-9a-z]+}}, i32 0, i32 0), !dbg !{{[0-9]+}}, !llvm.preserve.access.index 
![[TYPEDEF_STRUCT:[0-9]+]]
+// CHECK: define 

[clang] e3d8ee3 - reland "[DebugInfo] Support to emit debugInfo for extern variables"

2019-12-22 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2019-12-22T18:28:50-08:00
New Revision: e3d8ee35e4adca664a9149536e0f0b3b0ceaeaeb

URL: 
https://github.com/llvm/llvm-project/commit/e3d8ee35e4adca664a9149536e0f0b3b0ceaeaeb
DIFF: 
https://github.com/llvm/llvm-project/commit/e3d8ee35e4adca664a9149536e0f0b3b0ceaeaeb.diff

LOG: reland "[DebugInfo] Support to emit debugInfo for extern variables"

Commit d77ae1552fc21a9f3877f3ed7e13d631f517c825
("[DebugInfo] Support to emit debugInfo for extern variables")
added deebugInfo for extern variables for BPF target.
The commit is reverted by 891e25b02d760d0de18c7d46947913b3166047e7
as the committed tests using %clang instead of %clang_cc1 causing
test failed in certain scenarios as reported by Reid Kleckner.

This patch fixed the tests by using %clang_cc1.

Differential Revision: https://reviews.llvm.org/D71818

Added: 
clang/test/CodeGen/debug-info-extern-basic.c
clang/test/CodeGen/debug-info-extern-duplicate.c
clang/test/CodeGen/debug-info-extern-multi.c
clang/test/CodeGen/debug-info-extern-unused.c

Modified: 
clang/include/clang/AST/ASTConsumer.h
clang/include/clang/Basic/TargetInfo.h
clang/include/clang/Sema/Sema.h
clang/lib/Basic/Targets/BPF.h
clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/CodeGen/CGDebugInfo.h
clang/lib/CodeGen/CodeGenAction.cpp
clang/lib/CodeGen/CodeGenModule.cpp
clang/lib/CodeGen/CodeGenModule.h
clang/lib/CodeGen/ModuleBuilder.cpp
clang/lib/Sema/Sema.cpp
clang/lib/Sema/SemaDecl.cpp
llvm/include/llvm/IR/DIBuilder.h
llvm/lib/IR/DIBuilder.cpp
llvm/lib/IR/DebugInfo.cpp
llvm/unittests/Transforms/Utils/CloningTest.cpp

Removed: 




diff  --git a/clang/include/clang/AST/ASTConsumer.h 
b/clang/include/clang/AST/ASTConsumer.h
index dc216a89c205..ecdd8e873e1e 100644
--- a/clang/include/clang/AST/ASTConsumer.h
+++ b/clang/include/clang/AST/ASTConsumer.h
@@ -102,6 +102,11 @@ class ASTConsumer {
   /// modified by the introduction of an implicit zero initializer.
   virtual void CompleteTentativeDefinition(VarDecl *D) {}
 
+  /// CompleteExternalDeclaration - Callback invoked at the end of a 
translation
+  /// unit to notify the consumer that the given external declaration should be
+  /// completed.
+  virtual void CompleteExternalDeclaration(VarDecl *D) {}
+
   /// Callback invoked when an MSInheritanceAttr has been attached to a
   /// CXXRecordDecl.
   virtual void AssignInheritanceModel(CXXRecordDecl *RD) {}

diff  --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index 33cecdadc686..bc06f59d41d4 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1389,6 +1389,9 @@ class TargetInfo : public virtual TransferrableTargetInfo,
 
   virtual void setAuxTarget(const TargetInfo *Aux) {}
 
+  /// Whether target allows debuginfo types for decl only variables.
+  virtual bool allowDebugInfoForExternalVar() const { return false; }
+
 protected:
   /// Copy type and layout related info.
   void copyAuxTarget(const TargetInfo *Aux);

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 8cce6fdb1259..41c0e1459199 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -668,6 +668,9 @@ class Sema final {
   /// All the tentative definitions encountered in the TU.
   TentativeDefinitionsType TentativeDefinitions;
 
+  /// All the external declarations encoutered and used in the TU.
+  SmallVector ExternalDeclarations;
+
   typedef LazyVector
 UnusedFileScopedDeclsType;

diff  --git a/clang/lib/Basic/Targets/BPF.h b/clang/lib/Basic/Targets/BPF.h
index 117f81430bf4..b2f1831e960e 100644
--- a/clang/lib/Basic/Targets/BPF.h
+++ b/clang/lib/Basic/Targets/BPF.h
@@ -76,6 +76,8 @@ class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public 
TargetInfo {
 return None;
   }
 
+  bool allowDebugInfoForExternalVar() const override { return true; }
+
   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override 
{
 switch (CC) {
 default:

diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 8858e08f2a77..675df309e3f0 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -4485,7 +4485,7 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable 
*Var,
 
 GVE = DBuilder.createGlobalVariableExpression(
 DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, 
Unit),
-Var->hasLocalLinkage(),
+Var->hasLocalLinkage(), true,
 Expr.empty() ? nullptr : DBuilder.createExpression(Expr),
 getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
 Align);
@@ -4588,10 +4588,29 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl 
*VD, const APValue ) {
 
   GV.reset(DBuilder.createGlobalVariableExpression(
   DContext, Name, 

[clang] d77ae15 - [DebugInfo] Support to emit debugInfo for extern variables

2019-12-10 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2019-12-10T08:09:51-08:00
New Revision: d77ae1552fc21a9f3877f3ed7e13d631f517c825

URL: 
https://github.com/llvm/llvm-project/commit/d77ae1552fc21a9f3877f3ed7e13d631f517c825
DIFF: 
https://github.com/llvm/llvm-project/commit/d77ae1552fc21a9f3877f3ed7e13d631f517c825.diff

LOG: [DebugInfo] Support to emit debugInfo for extern variables

Extern variable usage in BPF is different from traditional
pure user space application. Recent discussion in linux bpf
mailing list has two use cases where debug info types are
required to use extern variables:
  - extern types are required to have a suitable interface
in libbpf (bpf loader) to provide kernel config parameters
to bpf programs.

https://lore.kernel.org/bpf/CAEf4BzYCNo5GeVGMhp3fhysQ=_axAf=23ptwazs-yayafmx...@mail.gmail.com/T/#t
  - extern types are required so kernel bpf verifier can
verify program which uses external functions more precisely.
This will make later link with actual external function no
need to reverify.

https://lore.kernel.org/bpf/87eez4odqp@toke.dk/T/#m8d5c3e87ffe7f2764e02d722cb0d8cbc136880ed

This patch added clang support to emit debuginfo for extern variables
with a TargetInfo hook to enable it. The debuginfo for the
extern variable is emitted only if that extern variable is
referenced in the current compilation unit.

Currently, only BPF target enables to generate debug info for
extern variables. The emission of such debuginfo is disabled for C++
 at this moment since BPF only supports a subset of C language.
Emission with C++ can be enabled later if an appropriate use case
is identified.

-fstandalone-debug permits us to see more debuginfo with the cost
of bloated binary size. This patch did not add emission of extern
variable debug info with -fstandalone-debug. This can be
re-evaluated if there is a real need.

Differential Revision: https://reviews.llvm.org/D70696

Added: 
clang/test/CodeGen/debug-info-extern-basic.c
clang/test/CodeGen/debug-info-extern-duplicate.c
clang/test/CodeGen/debug-info-extern-multi.c
clang/test/CodeGen/debug-info-extern-unused.c

Modified: 
clang/include/clang/AST/ASTConsumer.h
clang/include/clang/Basic/TargetInfo.h
clang/include/clang/Sema/Sema.h
clang/lib/Basic/Targets/BPF.h
clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/CodeGen/CGDebugInfo.h
clang/lib/CodeGen/CodeGenAction.cpp
clang/lib/CodeGen/CodeGenModule.cpp
clang/lib/CodeGen/CodeGenModule.h
clang/lib/CodeGen/ModuleBuilder.cpp
clang/lib/Sema/Sema.cpp
clang/lib/Sema/SemaDecl.cpp
llvm/include/llvm/IR/DIBuilder.h
llvm/lib/IR/DIBuilder.cpp
llvm/lib/IR/DebugInfo.cpp
llvm/unittests/Transforms/Utils/CloningTest.cpp

Removed: 




diff  --git a/clang/include/clang/AST/ASTConsumer.h 
b/clang/include/clang/AST/ASTConsumer.h
index dc216a89c205..ecdd8e873e1e 100644
--- a/clang/include/clang/AST/ASTConsumer.h
+++ b/clang/include/clang/AST/ASTConsumer.h
@@ -102,6 +102,11 @@ class ASTConsumer {
   /// modified by the introduction of an implicit zero initializer.
   virtual void CompleteTentativeDefinition(VarDecl *D) {}
 
+  /// CompleteExternalDeclaration - Callback invoked at the end of a 
translation
+  /// unit to notify the consumer that the given external declaration should be
+  /// completed.
+  virtual void CompleteExternalDeclaration(VarDecl *D) {}
+
   /// Callback invoked when an MSInheritanceAttr has been attached to a
   /// CXXRecordDecl.
   virtual void AssignInheritanceModel(CXXRecordDecl *RD) {}

diff  --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index 33cecdadc686..bc06f59d41d4 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1389,6 +1389,9 @@ class TargetInfo : public virtual TransferrableTargetInfo,
 
   virtual void setAuxTarget(const TargetInfo *Aux) {}
 
+  /// Whether target allows debuginfo types for decl only variables.
+  virtual bool allowDebugInfoForExternalVar() const { return false; }
+
 protected:
   /// Copy type and layout related info.
   void copyAuxTarget(const TargetInfo *Aux);

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 5633f95b2c23..1cdaab3dc28c 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -667,6 +667,9 @@ class Sema final {
   /// All the tentative definitions encountered in the TU.
   TentativeDefinitionsType TentativeDefinitions;
 
+  /// All the external declarations encoutered and used in the TU.
+  SmallVector ExternalDeclarations;
+
   typedef LazyVector
 UnusedFileScopedDeclsType;

diff  --git a/clang/lib/Basic/Targets/BPF.h b/clang/lib/Basic/Targets/BPF.h
index 117f81430bf4..b2f1831e960e 100644
--- a/clang/lib/Basic/Targets/BPF.h
+++ b/clang/lib/Basic/Targets/BPF.h
@@ -76,6 +76,8 @@ class LLVM_LIBRARY_VISIBILITY 

[clang] dd16b3f - [BPF] Restrict preserve_access_index attribute to C only

2019-11-14 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2019-11-14T14:14:59-08:00
New Revision: dd16b3fe2559789adcdd7d4d0bfe2796897877a3

URL: 
https://github.com/llvm/llvm-project/commit/dd16b3fe2559789adcdd7d4d0bfe2796897877a3
DIFF: 
https://github.com/llvm/llvm-project/commit/dd16b3fe2559789adcdd7d4d0bfe2796897877a3.diff

LOG: [BPF] Restrict preserve_access_index attribute to C only

This patch is a follow-up for commit 4e2ce228ae79
  [BPF] Add preserve_access_index attribute for record definition
to restrict attribute for C only. A new test case is added
to check for this restriction.

Additional code polishing is done based on
Aaron Ballman's suggestion in https://reviews.llvm.org/D69759/new/.

Differential Revision: https://reviews.llvm.org/D70257

Added: 
clang/test/Sema/bpf-attr-preserve-access-index.cpp

Modified: 
clang/include/clang/Basic/Attr.td
clang/lib/CodeGen/CGExpr.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 91140c0ddf17..ce7ad2ceaac2 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1584,6 +1584,7 @@ def BPFPreserveAccessIndex : InheritableAttr,
   let Spellings = [Clang<"preserve_access_index">];
   let Subjects = SubjectList<[Record], ErrorDiag>;
   let Documentation = [BPFPreserveAccessIndexDocs];
+  let LangOpts = [COnly];
 }
 
 def WebAssemblyImportModule : InheritableAttr,

diff  --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index e32db8c56df9..384e8f72a619 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3408,10 +3408,6 @@ static bool IsPreserveAIArrayBase(CodeGenFunction , 
const Expr *ArrayBase) {
   if (!ArrayBase || !CGF.getDebugInfo())
 return false;
 
-  const auto *ImplicitCast = dyn_cast(ArrayBase);
-  if (!ImplicitCast)
-return false;
-
   // Only support base as either a MemberExpr or DeclRefExpr.
   // DeclRefExpr to cover cases like:
   //struct s { int a; int b[10]; };
@@ -3419,39 +3415,24 @@ static bool IsPreserveAIArrayBase(CodeGenFunction , 
const Expr *ArrayBase) {
   //p[1].a
   // p[1] will generate a DeclRefExpr and p[1].a is a MemberExpr.
   // p->b[5] is a MemberExpr example.
-  const Expr *E = ImplicitCast->getSubExpr();
-  const auto *MemberCast = dyn_cast(E);
-  if (MemberCast)
-return MemberCast->getMemberDecl()->hasAttr();
-
-  const auto *DeclRefCast = dyn_cast(E);
-  if (DeclRefCast) {
-const VarDecl *VarDef = dyn_cast(DeclRefCast->getDecl());
+  const Expr *E = ArrayBase->IgnoreImpCasts();
+  if (const auto *ME = dyn_cast(E))
+return ME->getMemberDecl()->hasAttr();
+
+  if (const auto *DRE = dyn_cast(E)) {
+const auto *VarDef = dyn_cast(DRE->getDecl());
 if (!VarDef)
   return false;
 
-const auto *PtrT = dyn_cast(VarDef->getType().getTypePtr());
+const auto *PtrT = VarDef->getType()->getAs();
 if (!PtrT)
   return false;
-const auto *PointeeT = PtrT->getPointeeType().getTypePtr();
-
-// Peel off typedef's
-const auto *TypedefT = dyn_cast(PointeeT);
-while (TypedefT) {
-  PointeeT = TypedefT->desugar().getTypePtr();
-  TypedefT = dyn_cast(PointeeT);
-}
-
-// Not a typedef any more, it should be an elaborated type.
-const auto ElaborateT = dyn_cast(PointeeT);
-if (!ElaborateT)
-  return false;
 
-const auto *RecT = 
dyn_cast(ElaborateT->desugar().getTypePtr());
-if (!RecT)
-  return false;
-
-return RecT->getDecl()->hasAttr();
+const auto *PointeeT = PtrT->getPointeeType()
+ ->getUnqualifiedDesugaredType();
+if (const auto *RecT = dyn_cast(PointeeT))
+  return RecT->getDecl()->hasAttr();
+return false;
   }
 
   return false;

diff  --git a/clang/test/Sema/bpf-attr-preserve-access-index.cpp 
b/clang/test/Sema/bpf-attr-preserve-access-index.cpp
new file mode 100644
index ..4a88ec2eda3c
--- /dev/null
+++ b/clang/test/Sema/bpf-attr-preserve-access-index.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -x c++ -triple bpf-pc-linux-gnu -dwarf-version=4 
-fsyntax-only -verify %s
+
+#define __reloc__ __attribute__((preserve_access_index))
+
+struct t1 {
+  int a;
+  int b[4];
+  int c:1;
+} __reloc__; // expected-warning {{'preserve_access_index' attribute ignored}}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 1583158 - [BPF] fix clang test failure for bpf-attr-preserve-access-index-4.c

2019-11-13 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2019-11-13T09:40:57-08:00
New Revision: 1583158042a7e1f8b4f5194b1db362328e6902f3

URL: 
https://github.com/llvm/llvm-project/commit/1583158042a7e1f8b4f5194b1db362328e6902f3
DIFF: 
https://github.com/llvm/llvm-project/commit/1583158042a7e1f8b4f5194b1db362328e6902f3.diff

LOG: [BPF] fix clang test failure for bpf-attr-preserve-access-index-4.c

Depending on different cmake configures, clang may generate different
IR name for slot variables. Let us use the regex instead of hard
coding the name. I did the same for other bpf-attr-preserve-access-index
tests with such an approach, but somehow did not do for this one.

Added: 


Modified: 
clang/test/CodeGen/bpf-attr-preserve-access-index-4.c

Removed: 




diff  --git a/clang/test/CodeGen/bpf-attr-preserve-access-index-4.c 
b/clang/test/CodeGen/bpf-attr-preserve-access-index-4.c
index 5ec56d96de18..49930996e306 100644
--- a/clang/test/CodeGen/bpf-attr-preserve-access-index-4.c
+++ b/clang/test/CodeGen/bpf-attr-preserve-access-index-4.c
@@ -27,7 +27,7 @@ int test(__s3 *arg) {
 
 // CHECK: define dso_local i32 @test
 // CHECK-NOT: call %struct.s2* 
@llvm.preserve.struct.access.index.p0s_struct.s2s.p0s_struct.s3s
-// CHECK: call %union.anon* 
@llvm.preserve.struct.access.index.p0s_union.anons.p0s_struct.s2s(%struct.s2* 
%a, i32 0, i32 0)
-// CHECK: call %union.anon* 
@llvm.preserve.union.access.index.p0s_union.anons.p0s_union.anons(%union.anon* 
%1, i32 0)
-// CHECK: call %struct.s1* 
@llvm.preserve.array.access.index.p0s_struct.s1s.p0a3s_struct.s1s([3 x 
%struct.s1]* %b, i32 1, i32 2)
+// CHECK: call %union.anon* 
@llvm.preserve.struct.access.index.p0s_union.anons.p0s_struct.s2s(%struct.s2* 
%{{[0-9a-z]+}}, i32 0, i32 0)
+// CHECK: call %union.anon* 
@llvm.preserve.union.access.index.p0s_union.anons.p0s_union.anons(%union.anon* 
%{{[0-9a-z]+}}, i32 0)
+// CHECK: call %struct.s1* 
@llvm.preserve.array.access.index.p0s_struct.s1s.p0a3s_struct.s1s([3 x 
%struct.s1]* %{{[0-9a-z]+}}, i32 1, i32 2)
 // CHECK-NOT: call i32* @llvm.preserve.struct.access.index.p0i32.p0s_struct.s1s



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] f582479 - [BPF] add missing attribute in pragma-attribute-supported-attributes-list.test

2019-11-13 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2019-11-13T08:50:42-08:00
New Revision: f5824799f612d9d3f19470a60533c2872bcc096b

URL: 
https://github.com/llvm/llvm-project/commit/f5824799f612d9d3f19470a60533c2872bcc096b
DIFF: 
https://github.com/llvm/llvm-project/commit/f5824799f612d9d3f19470a60533c2872bcc096b.diff

LOG: [BPF] add missing attribute in 
pragma-attribute-supported-attributes-list.test

Add the newly supported BPF specific __attribute__((preserve_access_index)
in the pragma-attribute-supported-attributes-list.test.

Added: 


Modified: 
clang/test/Misc/pragma-attribute-supported-attributes-list.test

Removed: 




diff  --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test 
b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index 729e9b7a6f77..877f6ee6f3fd 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -20,6 +20,7 @@
 // CHECK-NEXT: ArmMveAlias (SubjectMatchRule_function)
 // CHECK-NEXT: AssumeAligned (SubjectMatchRule_objc_method, 
SubjectMatchRule_function)
 // CHECK-NEXT: Availability ((SubjectMatchRule_record, SubjectMatchRule_enum, 
SubjectMatchRule_enum_constant, SubjectMatchRule_field, 
SubjectMatchRule_function, SubjectMatchRule_namespace, 
SubjectMatchRule_objc_category, SubjectMatchRule_objc_implementation, 
SubjectMatchRule_objc_interface, SubjectMatchRule_objc_method, 
SubjectMatchRule_objc_property, SubjectMatchRule_objc_protocol, 
SubjectMatchRule_record, SubjectMatchRule_type_alias, 
SubjectMatchRule_variable))
+// CHECK-NEXT: BPFPreserveAccessIndex (SubjectMatchRule_record)
 // CHECK-NEXT: CFAuditedTransfer (SubjectMatchRule_function)
 // CHECK-NEXT: CFConsumed (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: CFICanonicalJumpTable (SubjectMatchRule_function)



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 4e2ce22 - [BPF] Add preserve_access_index attribute for record definition

2019-11-13 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2019-11-13T08:23:44-08:00
New Revision: 4e2ce228ae7954a6499fbb8e4995c13ac8b60f9a

URL: 
https://github.com/llvm/llvm-project/commit/4e2ce228ae7954a6499fbb8e4995c13ac8b60f9a
DIFF: 
https://github.com/llvm/llvm-project/commit/4e2ce228ae7954a6499fbb8e4995c13ac8b60f9a.diff

LOG: [BPF] Add preserve_access_index attribute for record definition

This is a resubmission for the previous reverted commit
943436040121 with the same subject. This commit fixed the
segfault issue and addressed additional review comments.

This patch introduced a new bpf specific attribute which can
be added to struct or union definition. For example,
  struct s { ... } __attribute__((preserve_access_index));
  union u { ... } __attribute__((preserve_access_index));
The goal is to simplify user codes for cases
where preserve access index happens for certain struct/union,
so user does not need to use clang __builtin_preserve_access_index
for every members.

The attribute has no effect if -g is not specified.

When the attribute is specified and -g is specified, any member
access defined by that structure or union, including array subscript
access and inner records, will be preserved through
  __builtin_preserve_{array,struct,union}_access_index()
IR intrinsics, which will enable relocation generation
in bpf backend.

The following is an example to illustrate the usage:
  -bash-4.4$ cat t.c
  #define __reloc__ __attribute__((preserve_access_index))
  struct s1 {
int c;
  } __reloc__;

  struct s2 {
union {
  struct s1 b[3];
};
  } __reloc__;

  struct s3 {
struct s2 a;
  } __reloc__;

  int test(struct s3 *arg) {
return arg->a.b[2].c;
  }
  -bash-4.4$ clang -target bpf -g -S -O2 t.c

A relocation with access string "0:0:0:0:2:0" will be generated
representing access offset of arg->a.b[2].c.

forward declaration with attribute is also handled properly such
that the attribute is copied and populated in real record definition.

Differential Revision: https://reviews.llvm.org/D69759

Added: 
clang/test/CodeGen/bpf-attr-preserve-access-index-1.c
clang/test/CodeGen/bpf-attr-preserve-access-index-2.c
clang/test/CodeGen/bpf-attr-preserve-access-index-3.c
clang/test/CodeGen/bpf-attr-preserve-access-index-4.c
clang/test/CodeGen/bpf-attr-preserve-access-index-5.c
clang/test/CodeGen/bpf-attr-preserve-access-index-6.c
clang/test/CodeGen/bpf-attr-preserve-access-index-7.c
clang/test/CodeGen/bpf-attr-preserve-access-index-8.c
clang/test/Sema/bpf-attr-preserve-access-index.c

Modified: 
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/lib/CodeGen/CGExpr.cpp
clang/lib/Sema/SemaDeclAttr.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index f12ebdc126a4..91140c0ddf17 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -332,6 +332,7 @@ class TargetArch arches> : TargetSpec {
 }
 def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>;
 def TargetAVR : TargetArch<["avr"]>;
+def TargetBPF : TargetArch<["bpfel", "bpfeb"]>;
 def TargetMips32 : TargetArch<["mips", "mipsel"]>;
 def TargetAnyMips : TargetArch<["mips", "mipsel", "mips64", "mips64el"]>;
 def TargetMSP430 : TargetArch<["msp430"]>;
@@ -1578,6 +1579,13 @@ def AMDGPUNumVGPR : InheritableAttr {
   let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
 }
 
+def BPFPreserveAccessIndex : InheritableAttr,
+ TargetSpecificAttr  {
+  let Spellings = [Clang<"preserve_access_index">];
+  let Subjects = SubjectList<[Record], ErrorDiag>;
+  let Documentation = [BPFPreserveAccessIndexDocs];
+}
+
 def WebAssemblyImportModule : InheritableAttr,
   TargetSpecificAttr {
   let Spellings = [Clang<"import_module">];

diff  --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 3a9093124637..50e76bf080b4 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -1634,6 +1634,17 @@ The semantics are as follows:
   }];
 }
 
+def BPFPreserveAccessIndexDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+Clang supports the ``__attribute__((preserve_access_index))``
+attribute for the BPF target. This attribute may be attached to a
+struct or union declaration, where if -g is specified, it enables
+preserving struct or union member access debuginfo indicies of this
+struct or union, similar to clang ``__builtin_preserve_acceess_index()``.
+  }];
+}
+
 def MipsInterruptDocs : Documentation {
   let Category = DocCatFunction;
   let Heading = "interrupt (MIPS)";

diff  --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 99406715cbf8..e32db8c56df9 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp

[clang] 9434360 - Revert "[BPF] Add preserve_access_index attribute for record definition"

2019-11-09 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2019-11-09T08:32:44-08:00
New Revision: 9434360401218ae02aaea1fbb53a42bc3af2bc76

URL: 
https://github.com/llvm/llvm-project/commit/9434360401218ae02aaea1fbb53a42bc3af2bc76
DIFF: 
https://github.com/llvm/llvm-project/commit/9434360401218ae02aaea1fbb53a42bc3af2bc76.diff

LOG: Revert "[BPF] Add preserve_access_index attribute for record definition"

This reverts commit 4a5aa1a7bf8b1714b817ede8e09cd28c0784228a.

There are some other test failures. Investigate them first.

Added: 


Modified: 
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/CodeGen/CGExpr.cpp
clang/lib/Sema/SemaDeclAttr.cpp

Removed: 
clang/test/CodeGen/bpf-attr-preserve-access-index-1.c
clang/test/CodeGen/bpf-attr-preserve-access-index-2.c
clang/test/CodeGen/bpf-attr-preserve-access-index-3.c
clang/test/CodeGen/bpf-attr-preserve-access-index-4.c
clang/test/CodeGen/bpf-attr-preserve-access-index-5.c
clang/test/CodeGen/bpf-attr-preserve-access-index-6.c
clang/test/CodeGen/bpf-attr-preserve-access-index-7.c
clang/test/CodeGen/bpf-attr-preserve-access-index-8.c
clang/test/Sema/bpf-attr-preserve-access-index.c



diff  --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index aef02b5a8e96..0d25e775e2af 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -332,7 +332,6 @@ class TargetArch arches> : TargetSpec {
 }
 def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>;
 def TargetAVR : TargetArch<["avr"]>;
-def TargetBPF : TargetArch<["bpfel", "bpfeb"]>;
 def TargetMips32 : TargetArch<["mips", "mipsel"]>;
 def TargetAnyMips : TargetArch<["mips", "mipsel", "mips64", "mips64el"]>;
 def TargetMSP430 : TargetArch<["msp430"]>;
@@ -1579,12 +1578,6 @@ def AMDGPUNumVGPR : InheritableAttr {
   let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
 }
 
-def BPFPreserveAccessIndex : InheritableAttr,
- TargetSpecificAttr  {
-  let Spellings = [Clang<"preserve_access_index">];
-  let Documentation = [BPFPreserveAccessIndexDocs];
-}
-
 def WebAssemblyImportModule : InheritableAttr,
   TargetSpecificAttr {
   let Spellings = [Clang<"import_module">];

diff  --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 50e76bf080b4..3a9093124637 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -1634,17 +1634,6 @@ The semantics are as follows:
   }];
 }
 
-def BPFPreserveAccessIndexDocs : Documentation {
-  let Category = DocCatFunction;
-  let Content = [{
-Clang supports the ``__attribute__((preserve_access_index))``
-attribute for the BPF target. This attribute may be attached to a
-struct or union declaration, where if -g is specified, it enables
-preserving struct or union member access debuginfo indicies of this
-struct or union, similar to clang ``__builtin_preserve_acceess_index()``.
-  }];
-}
-
 def MipsInterruptDocs : Documentation {
   let Category = DocCatFunction;
   let Heading = "interrupt (MIPS)";

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 33a0f9710856..88d73dc89b55 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10065,7 +10065,6 @@ def err_preserve_field_info_not_field : Error<
   "__builtin_preserve_field_info argument %0 not a field access">;
 def err_preserve_field_info_not_const: Error<
   "__builtin_preserve_field_info argument %0 not a constant">;
-def err_preserve_access_index_wrong_type: Error<"%0 attribute only applies to 
%1">;
 
 def err_bit_cast_non_trivially_copyable : Error<
   "__builtin_bit_cast %select{source|destination}0 type must be trivially 
copyable">;

diff  --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index e32db8c56df9..99406715cbf8 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3402,67 +3402,11 @@ static QualType getFixedSizeElementType(const 
ASTContext ,
   return eltType;
 }
 
-/// Given an array base, check whether its member access belongs to a record
-/// with preserve_access_index attribute or not.
-static bool IsPreserveAIArrayBase(CodeGenFunction , const Expr *ArrayBase) 
{
-  if (!ArrayBase || !CGF.getDebugInfo())
-return false;
-
-  const auto *ImplicitCast = dyn_cast(ArrayBase);
-  if (!ImplicitCast)
-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.
-  const Expr *E = 

[clang] 4a5aa1a - [BPF] Add preserve_access_index attribute for record definition

2019-11-09 Thread Yonghong Song via cfe-commits

Author: Yonghong Song
Date: 2019-11-09T08:17:12-08:00
New Revision: 4a5aa1a7bf8b1714b817ede8e09cd28c0784228a

URL: 
https://github.com/llvm/llvm-project/commit/4a5aa1a7bf8b1714b817ede8e09cd28c0784228a
DIFF: 
https://github.com/llvm/llvm-project/commit/4a5aa1a7bf8b1714b817ede8e09cd28c0784228a.diff

LOG: [BPF] Add preserve_access_index attribute for record definition

This patch introduced a new bpf specific attribute which can
be added to struct or union definition. For example,
  struct s { ... } __attribute__((preserve_access_index));
  union u { ... } __attribute__((preserve_access_index));
The goal is to simplify user codes for cases
where preserve access index happens for certain struct/union,
so user does not need to use clang __builtin_preserve_access_index
for every members.

The attribute has no effect if -g is not specified.

When the attribute is specified and -g is specified, any member
access defined by that structure or union, including array subscript
access and inner records, will be preserved through
  __builtin_preserve_{array,struct,union}_access_index()
IR intrinsics, which will enable relocation generation
in bpf backend.

The following is an example to illustrate the usage:
  -bash-4.4$ cat t.c
  #define __reloc__ __attribute__((preserve_access_index))
  struct s1 {
int c;
  } __reloc__;

  struct s2 {
union {
  struct s1 b[3];
};
  } __reloc__;

  struct s3 {
struct s2 a;
  } __reloc__;

  int test(struct s3 *arg) {
return arg->a.b[2].c;
  }
  -bash-4.4$ clang -target bpf -g -S -O2 t.c

A relocation with access string "0:0:0:0:2:0" will be generated
representing access offset of arg->a.b[2].c.

forward declaration with attribute is also handled properly such
that the attribute is copied and populated in real record definition.

Differential Revision: https://reviews.llvm.org/D69759

Added: 
clang/test/CodeGen/bpf-attr-preserve-access-index-1.c
clang/test/CodeGen/bpf-attr-preserve-access-index-2.c
clang/test/CodeGen/bpf-attr-preserve-access-index-3.c
clang/test/CodeGen/bpf-attr-preserve-access-index-4.c
clang/test/CodeGen/bpf-attr-preserve-access-index-5.c
clang/test/CodeGen/bpf-attr-preserve-access-index-6.c
clang/test/CodeGen/bpf-attr-preserve-access-index-7.c
clang/test/CodeGen/bpf-attr-preserve-access-index-8.c
clang/test/Sema/bpf-attr-preserve-access-index.c

Modified: 
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/CodeGen/CGExpr.cpp
clang/lib/Sema/SemaDeclAttr.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 0d25e775e2af..aef02b5a8e96 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -332,6 +332,7 @@ class TargetArch arches> : TargetSpec {
 }
 def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>;
 def TargetAVR : TargetArch<["avr"]>;
+def TargetBPF : TargetArch<["bpfel", "bpfeb"]>;
 def TargetMips32 : TargetArch<["mips", "mipsel"]>;
 def TargetAnyMips : TargetArch<["mips", "mipsel", "mips64", "mips64el"]>;
 def TargetMSP430 : TargetArch<["msp430"]>;
@@ -1578,6 +1579,12 @@ def AMDGPUNumVGPR : InheritableAttr {
   let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
 }
 
+def BPFPreserveAccessIndex : InheritableAttr,
+ TargetSpecificAttr  {
+  let Spellings = [Clang<"preserve_access_index">];
+  let Documentation = [BPFPreserveAccessIndexDocs];
+}
+
 def WebAssemblyImportModule : InheritableAttr,
   TargetSpecificAttr {
   let Spellings = [Clang<"import_module">];

diff  --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 3a9093124637..50e76bf080b4 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -1634,6 +1634,17 @@ The semantics are as follows:
   }];
 }
 
+def BPFPreserveAccessIndexDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+Clang supports the ``__attribute__((preserve_access_index))``
+attribute for the BPF target. This attribute may be attached to a
+struct or union declaration, where if -g is specified, it enables
+preserving struct or union member access debuginfo indicies of this
+struct or union, similar to clang ``__builtin_preserve_acceess_index()``.
+  }];
+}
+
 def MipsInterruptDocs : Documentation {
   let Category = DocCatFunction;
   let Heading = "interrupt (MIPS)";

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 88d73dc89b55..33a0f9710856 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10065,6 +10065,7 @@ def err_preserve_field_info_not_field : Error<
   

r374099 - [BPF] do compile-once run-everywhere relocation for bitfields

2019-10-08 Thread Yonghong Song via cfe-commits
Author: yhs
Date: Tue Oct  8 11:23:17 2019
New Revision: 374099

URL: http://llvm.org/viewvc/llvm-project?rev=374099=rev
Log:
[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(, 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   

r372516 - [CLANG][BPF] permit any argument type for __builtin_preserve_access_index()

2019-09-22 Thread Yonghong Song via cfe-commits
Author: yhs
Date: Sun Sep 22 10:33:48 2019
New Revision: 372516

URL: http://llvm.org/viewvc/llvm-project?rev=372516=rev
Log:
[CLANG][BPF] permit any argument type for __builtin_preserve_access_index()

Commit c15aa241f821 ("[CLANG][BPF] change __builtin_preserve_access_index()
signature") changed the builtin function signature to
  PointerT __builtin_preserve_access_index(PointerT ptr)
with a pointer type as the argument/return type, where argument and
return types must be the same.

There is really no reason for this constraint. The builtin just
presented a code region so that IR builtins
  __builtin_{array, struct, union}_preserve_access_index
can be applied.

This patch removed the pointer type restriction to permit any
argument type as long as it is permitted by the compiler.

Differential Revision: https://reviews.llvm.org/D67883

Added:
cfe/trunk/test/CodeGen/builtin-preserve-access-index-nonptr.c
Modified:
cfe/trunk/docs/LanguageExtensions.rst
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/test/Sema/builtin-preserve-access-index.c

Modified: cfe/trunk/docs/LanguageExtensions.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=372516=372515=372516=diff
==
--- cfe/trunk/docs/LanguageExtensions.rst (original)
+++ cfe/trunk/docs/LanguageExtensions.rst Sun Sep 22 10:33:48 2019
@@ -2354,13 +2354,13 @@ array subscript access and structure/uni
 under bpf compile-once run-everywhere framework. Debuginfo (typically
 with ``-g``) is needed, otherwise, the compiler will exit with an error.
 The return type for the intrinsic is the same as the type of the
-argument, and must be a pointer type.
+argument.
 
 **Syntax**:
 
 .. code-block:: c
 
-  PointerT __builtin_preserve_access_index(PointerT ptr)
+  type __builtin_preserve_access_index(type arg)
 
 **Example of Use**:
 
@@ -2375,7 +2375,8 @@ argument, and must be a pointer type.
 } c[4];
   };
   struct t *v = ...;
-  const void *pb =__builtin_preserve_access_index(>c[3].b);
+  int *pb =__builtin_preserve_access_index(>c[3].b);
+  __builtin_preserve_access_index(v->j);
 
 Multiprecision Arithmetic Builtins
 --

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=372516=372515=372516=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Sep 22 10:33:48 
2019
@@ -9916,7 +9916,4 @@ def err_bit_cast_non_trivially_copyable
   "__builtin_bit_cast %select{source|destination}0 type must be trivially 
copyable">;
 def err_bit_cast_type_size_mismatch : Error<
   "__builtin_bit_cast source size does not equal destination size (%0 vs %1)">;
-
-def err_builtin_preserve_access_index_invalid_arg : Error<
-  "__builtin_preserve_access_index argument must a pointer type instead of 
%0">;
 } // end of sema component.

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=372516=372515=372516=diff
==
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Sun Sep 22 10:33:48 2019
@@ -191,22 +191,12 @@ static bool SemaBuiltinAddressof(Sema 
   return false;
 }
 
-/// Check the number of arguments and arg type, and set the result type to
+/// Check the number of arguments and set the result type to
 /// the argument type.
 static bool SemaBuiltinPreserveAI(Sema , CallExpr *TheCall) {
   if (checkArgCount(S, TheCall, 1))
 return true;
 
-  // The argument type must be a pointer
-  ExprResult Arg = TheCall->getArg(0);
-  QualType Ty = Arg.get()->getType();
-  if (!Ty->isPointerType()) {
-S.Diag(Arg.get()->getBeginLoc(),
-   diag::err_builtin_preserve_access_index_invalid_arg)
-<< Ty << Arg.get()->getSourceRange();
-return true;
-  }
-
   TheCall->setType(TheCall->getArg(0)->getType());
   return false;
 }

Added: cfe/trunk/test/CodeGen/builtin-preserve-access-index-nonptr.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtin-preserve-access-index-nonptr.c?rev=372516=auto
==
--- cfe/trunk/test/CodeGen/builtin-preserve-access-index-nonptr.c (added)
+++ cfe/trunk/test/CodeGen/builtin-preserve-access-index-nonptr.c Sun Sep 22 
10:33:48 2019
@@ -0,0 +1,18 @@
+// RUN: %clang -target x86_64 -emit-llvm -S -g %s -o - | FileCheck %s
+
+#define _(x) (__builtin_preserve_access_index(x))
+
+struct s1 {
+  char a;
+  int b[4];
+};
+
+int unit1(struct s1 *arg) {
+  return _(arg->b[2]);
+}
+// CHECK: define 

r372294 - [CLANG][BPF] change __builtin_preserve_access_index() signature

2019-09-18 Thread Yonghong Song via cfe-commits
Author: yhs
Date: Wed Sep 18 19:59:43 2019
New Revision: 372294

URL: http://llvm.org/viewvc/llvm-project?rev=372294=rev
Log:
[CLANG][BPF] change __builtin_preserve_access_index() signature

The clang intrinsic __builtin_preserve_access_index() currently
has signature:
  const void * __builtin_preserve_access_index(const void * ptr)

This may cause compiler warning when:
  - parameter type is "volatile void *" or "const volatile void *", or
  - the assign-to type of the intrinsic does not have "const" qualifier.
Further, this signature does not allow dereference of the
builtin result pointer as it is a "const void *" type, which
adds extra step for the user to do type casting.

Let us change the signature to:
  PointerT __builtin_preserve_access_index(PointerT ptr)
such that the result and argument types are the same.
With this, directly dereferencing the builtin return value
becomes possible.

Differential Revision: https://reviews.llvm.org/D67734

Modified:
cfe/trunk/docs/LanguageExtensions.rst
cfe/trunk/include/clang/Basic/Builtins.def
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/test/Sema/builtin-preserve-access-index.c

Modified: cfe/trunk/docs/LanguageExtensions.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=372294=372293=372294=diff
==
--- cfe/trunk/docs/LanguageExtensions.rst (original)
+++ cfe/trunk/docs/LanguageExtensions.rst Wed Sep 18 19:59:43 2019
@@ -2353,12 +2353,14 @@ and other similar allocation libraries,
 array subscript access and structure/union member access are relocatable
 under bpf compile-once run-everywhere framework. Debuginfo (typically
 with ``-g``) is needed, otherwise, the compiler will exit with an error.
+The return type for the intrinsic is the same as the type of the
+argument, and must be a pointer type.
 
 **Syntax**:
 
 .. code-block:: c
 
-  const void * __builtin_preserve_access_index(const void * ptr)
+  PointerT __builtin_preserve_access_index(PointerT ptr)
 
 **Example of Use**:
 

Modified: cfe/trunk/include/clang/Basic/Builtins.def
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=372294=372293=372294=diff
==
--- cfe/trunk/include/clang/Basic/Builtins.def (original)
+++ cfe/trunk/include/clang/Basic/Builtins.def Wed Sep 18 19:59:43 2019
@@ -1470,7 +1470,7 @@ BUILTIN(__builtin_operator_new, "v*z", "
 BUILTIN(__builtin_operator_delete, "vv*", "tn")
 BUILTIN(__builtin_char_memchr, "c*cC*iz", "n")
 BUILTIN(__builtin_dump_struct, "ivC*v*", "tn")
-BUILTIN(__builtin_preserve_access_index, "vC*vC*", "nU")
+BUILTIN(__builtin_preserve_access_index, "v.", "t")
 
 // Safestack builtins
 BUILTIN(__builtin___get_unsafe_stack_start, "v*", "Fn")

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=372294=372293=372294=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Sep 18 19:59:43 
2019
@@ -9925,4 +9925,7 @@ def err_bit_cast_non_trivially_copyable
   "__builtin_bit_cast %select{source|destination}0 type must be trivially 
copyable">;
 def err_bit_cast_type_size_mismatch : Error<
   "__builtin_bit_cast source size does not equal destination size (%0 vs %1)">;
+
+def err_builtin_preserve_access_index_invalid_arg : Error<
+  "__builtin_preserve_access_index argument must a pointer type instead of 
%0">;
 } // end of sema component.

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=372294=372293=372294=diff
==
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Wed Sep 18 19:59:43 2019
@@ -191,12 +191,22 @@ static bool SemaBuiltinAddressof(Sema 
   return false;
 }
 
-/// Check the number of arguments, and set the result type to
+/// Check the number of arguments and arg type, and set the result type to
 /// the argument type.
 static bool SemaBuiltinPreserveAI(Sema , CallExpr *TheCall) {
   if (checkArgCount(S, TheCall, 1))
 return true;
 
+  // The argument type must be a pointer
+  ExprResult Arg = TheCall->getArg(0);
+  QualType Ty = Arg.get()->getType();
+  if (!Ty->isPointerType()) {
+S.Diag(Arg.get()->getBeginLoc(),
+   diag::err_builtin_preserve_access_index_invalid_arg)
+<< Ty << Arg.get()->getSourceRange();
+return true;
+  }
+
   TheCall->setType(TheCall->getArg(0)->getType());
   return false;
 }

Modified: cfe/trunk/test/Sema/builtin-preserve-access-index.c
URL: 

r367724 - [BPF] annotate DIType metadata for builtin preseve_array_access_index()

2019-08-02 Thread Yonghong Song via cfe-commits
Author: yhs
Date: Fri Aug  2 14:28:28 2019
New Revision: 367724

URL: http://llvm.org/viewvc/llvm-project?rev=367724=rev
Log:
[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([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 

Differential Revision: https://reviews.llvm.org/D65664

Added:
cfe/trunk/test/CodeGen/builtin-preserve-access-index-array.c
Modified:
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/test/CodeGen/builtin-preserve-access-index.c

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=367724=367723=367724=diff
==
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Fri Aug  2 14:28:28 2019
@@ -3400,6 +3400,7 @@ static Address emitArraySubscriptGEP(Cod
  ArrayRef indices,
  QualType eltType, bool inbounds,
  bool signedIndices, SourceLocation loc,
+ QualType *arrayType = nullptr,
  const llvm::Twine  = "arrayidx") {
   // All the indices except that last must be zero.
 #ifndef NDEBUG
@@ -3428,9 +3429,12 @@ static Address emitArraySubscriptGEP(Cod
   } else {
 // Remember the original array subscript for bpf target
 unsigned idx = LastIndex->getZExtValue();
+llvm::DIType *DbgInfo = nullptr;
+if (arrayType)
+  DbgInfo = CGF.getDebugInfo()->getOrCreateStandaloneType(*arrayType, loc);
 eltPtr = CGF.Builder.CreatePreserveArrayAccessIndex(addr.getPointer(),
 indices.size() - 1,
-idx);
+idx, DbgInfo);
   }
 
   return Address(eltPtr, eltAlign);
@@ -3567,19 +3571,21 @@ LValue CodeGenFunction::EmitArraySubscri
 auto *Idx = EmitIdxAfterBase(/*Promote*/true);
 
 // Propagate the alignment from the array itself to the result.
+QualType arrayType = Array->getType();
 Addr = emitArraySubscriptGEP(
 *this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
 E->getType(), !getLangOpts().isSignedOverflowDefined(), SignedIndices,
-E->getExprLoc());
+E->getExprLoc(), );
 EltBaseInfo = ArrayLV.getBaseInfo();
 EltTBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, E->getType());
   } else {
 // The base must be a pointer; emit it with an estimate of its alignment.
 Addr = EmitPointerWithAlignment(E->getBase(), , );
 auto *Idx = EmitIdxAfterBase(/*Promote*/true);
+QualType ptrType = E->getBase()->getType();
 Addr = emitArraySubscriptGEP(*this, Addr, Idx, E->getType(),
  !getLangOpts().isSignedOverflowDefined(),
- SignedIndices, E->getExprLoc());
+ SignedIndices, E->getExprLoc(), );
   }
 
   LValue LV = MakeAddrLValue(Addr, E->getType(), EltBaseInfo, EltTBAAInfo);

Added: cfe/trunk/test/CodeGen/builtin-preserve-access-index-array.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtin-preserve-access-index-array.c?rev=367724=auto
==
--- cfe/trunk/test/CodeGen/builtin-preserve-access-index-array.c (added)
+++ cfe/trunk/test/CodeGen/builtin-preserve-access-index-array.c Fri Aug  2 
14:28:28 2019
@@ -0,0 +1,18 @@
+// RUN: 

Re: r366076 - fix unnamed fiefield issue and add tests for __builtin_preserve_access_index intrinsic

2019-07-16 Thread Yonghong Song via cfe-commits


On 7/16/19 11:03 AM, Nick Desaulniers wrote:
> On Tue, Jul 16, 2019 at 11:02 AM Nick Desaulniers
>  wrote:
>>
>> On Mon, Jul 15, 2019 at 5:13 PM Eric Christopher  wrote:
>>>
>>> I'm going to cheat and make Nick do it :)
>>
>> I suspect that Eric still compiles LLVM by specifying all object files
>> in order on the command line and doesn't want to talk about it on
>> cfe-commits. :) Though, even I'm behind the times as I think the cool
>> kids are using "gn" these days?  I'm so out of touch.
>>
>>> On Mon, Jul 15, 2019 at 5:12 PM Yonghong Song  wrote:
 I just tried the following cmake (removing -DLLVM_ENABLE_ASSERTIONS=ON 
 which is used in my previous build)

 cmake -G "Unix Makefiles" -DLLVM_TARGETS_TO_BUILD="BPF;X86" \
  -DCMAKE_C_COMPILER=/llvm8/bin/clang \
  -DCMAKE_CXX_COMPILER=/llvm8/bin/clang++ \
  -DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON
  -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install ..

 and cannot reproduce the issue. If you could send me the cmake
 command line which caused failure in your environment. That will
 be great!
>>
>> I did:
>> $ cmake .. -DCMAKE_BUILD_TYPE=Release -G Ninja
>> -DCMAKE_C_COMPILER=
>> -DCMAKE_CXX_COMPILER=
>> -DLLVM_ENABLE_LLD=ON -DLLVM_ENABLE_PROJECTS="clang;lld"
>> -DLLVM_TARGETS_TO_BUILD="AArch64;ARM;X86"
>>
>> I sometimes add:
>> -DLLVM_ENABLE_ASSERTIONS=ON
>> which hopefully gets cleared when rerunning cmake, but I wouldn't bet
>> my life on that. (Looks like it's OFF in my CMakeCache.txt, so I guess
>> I could've taken that bet).
> 
> Forgot to mention that jdoerfert also mentioned on IRC yesterday that
> -DLLVM_ENABLE_ASSERTIONS=ON can influence Clang's codegen of LLVM IR.

Thanks, Nick. Will give your cmake a try and keep in mind that
testing both LLVM_ENABLE_ASSERTIONS ON/OFF for clang changes.

> 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r366231 - fix unnamed fiefield issue and add tests for __builtin_preserve_access_index intrinsic

2019-07-16 Thread Yonghong Song via cfe-commits
Author: yhs
Date: Tue Jul 16 10:24:33 2019
New Revision: 366231

URL: http://llvm.org/viewvc/llvm-project?rev=366231=rev
Log:
fix unnamed fiefield issue and add tests for __builtin_preserve_access_index 
intrinsic

The original commit is r366076. It is temporarily reverted (r366155)
due to test failure. This resubmit makes test more robust by accepting
regex instead of hardcoded names/references in several places.

This is a followup patch for https://reviews.llvm.org/D61809.
Handle unnamed bitfield properly and add more test cases.

Fixed the unnamed bitfield issue. The unnamed bitfield is ignored
by debug info, so we need to ignore such a struct/union member
when we try to get the member index in the debug info.

D61809 contains two test cases but not enough as it does
not checking generated IRs in the fine grain level, and also
it does not have semantics checking tests.
This patch added unit tests for both code gen and semantics checking for
the new intrinsic.

Signed-off-by: Yonghong Song 

Added:
cfe/trunk/test/CodeGen/builtin-preserve-access-index.c
cfe/trunk/test/Sema/builtin-preserve-access-index.c
Modified:
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=366231=366230=366231=diff
==
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Jul 16 10:24:33 2019
@@ -3892,6 +3892,23 @@ LValue CodeGenFunction::EmitLValueForLam
   return EmitLValueForField(LambdaLV, Field);
 }
 
+/// 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;
+}
+
 /// 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 , Address Base,
@@ -3931,7 +3948,7 @@ static Address emitPreserveStructAccess(
   CGF.CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field);
 
   return CGF.Builder.CreatePreserveStructAccessIndex(
-  base, idx, field->getFieldIndex(), DbgInfo);
+  base, idx, CGF.getDebugInfoFIndex(rec, field->getFieldIndex()), DbgInfo);
 }
 
 static bool hasAnyVptr(const QualType Type, const ASTContext ) {
@@ -4048,7 +4065,7 @@ LValue CodeGenFunction::EmitLValueForFie
   getContext().getRecordType(rec), rec->getLocation());
   addr = Address(
   Builder.CreatePreserveUnionAccessIndex(
-  addr.getPointer(), field->getFieldIndex(), DbgInfo),
+  addr.getPointer(), getDebugInfoFIndex(rec, 
field->getFieldIndex()), DbgInfo),
   addr.getAlignment());
 }
   } else {

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=366231=366230=366231=diff
==
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Jul 16 10:24:33 2019
@@ -2652,6 +2652,9 @@ public:
   /// Converts Location to a DebugLoc, if debug information is enabled.
   llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location);
 
+  /// Get the record field index as represented in debug info.
+  unsigned getDebugInfoFIndex(const RecordDecl *Rec, unsigned FieldIndex);
+
 
   
//======//
   //Declaration Emission

Added: cfe/trunk/test/CodeGen/builtin-preserve-access-index.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtin-preserve-access-index.c?rev=366231=auto
==
--- cfe/trunk/test/CodeGen/builtin-preserve-access-index.c (added)
+++ cfe/trunk/test/CodeGen/builtin-preserve-access-index.c Tue Jul 16 10:24:33 
2019
@@ -0,0 +1,177 @@
+// RUN: %clang -target x86_64 -emit-llvm -S -g %s -o - | FileCheck %s
+
+#define _(x) (__builtin_preserve_access_index(x))
+
+const void *unit1(const void *arg) {
+  return _(arg);
+}
+// CHECK: define dso_local i8* @unit1
+// CHECK-NOT: llvm.preserve.array.access.index
+// CHECK-NOT: llvm.preserve.struct.access.index
+// CHECK-NOT: llvm.preserve.union.access.index
+
+const void *unit2(void) {
+  return _((const void *)0xULL);
+}
+// CHECK: define dso_local i8* @unit2
+// CHECK-NOT: llvm.preserve.array.access.index
+// CHECK-NOT: 

Re: r366076 - fix unnamed fiefield issue and add tests for __builtin_preserve_access_index intrinsic

2019-07-15 Thread Yonghong Song via cfe-commits
HI, Eric,

No problem!

I just tried the following cmake (removing -DLLVM_ENABLE_ASSERTIONS=ON which is 
used in my previous build)

cmake -G "Unix Makefiles" -DLLVM_TARGETS_TO_BUILD="BPF;X86" \
-DCMAKE_C_COMPILER=/llvm8/bin/clang \
-DCMAKE_CXX_COMPILER=/llvm8/bin/clang++ \
-DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN=ON 
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/install ..

and cannot reproduce the issue. If you could send me the cmake
command line which caused failure in your environment. That will
be great!

Thanks,

Yonghong

On 7/15/19, 4:50 PM, "Eric Christopher"  wrote:

Just wanted to let you know I've temporarily reverted this here:

echristo@jhereg ~/s/llvm-project> git llvm push
Pushing 1 commit:
  ba7decf8c91 Temporarily Revert "fix unnamed fiefield issue and add
tests for __builtin_preserve_access_index intrinsic"
Sendingcfe/trunk/lib/CodeGen/CGExpr.cpp
Sendingcfe/trunk/lib/CodeGen/CodeGenFunction.h
Deleting   cfe/trunk/test/CodeGen/builtin-preserve-access-index.c
Deleting   cfe/trunk/test/Sema/builtin-preserve-access-index.c
Transmitting file data ..done
Committing transaction...
Committed revision 366155.
Committed ba7decf8c91 to svn.

Since the testcase was causing problems in non-assert builds. Feel
free to recommit when you fix that :)

Thanks!

-eric

    On Mon, Jul 15, 2019 at 8:42 AM Yonghong Song via cfe-commits
 wrote:
>
> Author: yhs
> Date: Mon Jul 15 08:42:41 2019
> New Revision: 366076
>
> URL: 
https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D366076-26view-3Drev=DwIBaQ=5VD0RTtNlTh3ycd41b3MUw=DA8e1B5r073vIqRrFz7MRA=dtjPkUWyM2j7LOCdes9xK0tSCe4BrvYtJpmJu_el7xE=LyV9cu6egVjs0MILQtMXrDRw1r2afyEdzsh_tKDRsQE=
 
> Log:
> fix unnamed fiefield issue and add tests for 
__builtin_preserve_access_index intrinsic
>
> This is a followup patch for 
https://urldefense.proofpoint.com/v2/url?u=https-3A__reviews.llvm.org_D61809=DwIBaQ=5VD0RTtNlTh3ycd41b3MUw=DA8e1B5r073vIqRrFz7MRA=dtjPkUWyM2j7LOCdes9xK0tSCe4BrvYtJpmJu_el7xE=zdwdBj89w175wBRDiJ8ts1YTR7VrNyt4IHp-29y6b8E=
 .
> Handle unnamed bitfield properly and add more test cases.
>
> Fixed the unnamed bitfield issue. The unnamed bitfield is ignored
> by debug info, so we need to ignore such a struct/union member
> when we try to get the member index in the debug info.
>
> D61809 contains two test cases but not enough as it does
> not checking generated IRs in the fine grain level, and also
> it does not have semantics checking tests.
> This patch added unit tests for both code gen and semantics checking for
> the new intrinsic.
>
> Signed-off-by: Yonghong Song 
>
> Added:
> cfe/trunk/test/CodeGen/builtin-preserve-access-index.c
> cfe/trunk/test/Sema/builtin-preserve-access-index.c
> Modified:
> cfe/trunk/lib/CodeGen/CGExpr.cpp
> cfe/trunk/lib/CodeGen/CodeGenFunction.h
>
> Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
> URL: 
https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_CodeGen_CGExpr.cpp-3Frev-3D366076-26r1-3D366075-26r2-3D366076-26view-3Ddiff=DwIBaQ=5VD0RTtNlTh3ycd41b3MUw=DA8e1B5r073vIqRrFz7MRA=dtjPkUWyM2j7LOCdes9xK0tSCe4BrvYtJpmJu_el7xE=wNn-0ZBP1UL0gaIGHoTeMMTdnpNcjwneAK5I8Y8AaJY=
 
> 
==
> --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Mon Jul 15 08:42:41 2019
> @@ -3892,6 +3892,23 @@ LValue CodeGenFunction::EmitLValueForLam
>return EmitLValueForField(LambdaLV, Field);
>  }
>
> +/// 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;
> +}
> +
>  /// 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 , Address 
Base,
> @@ -3931,7 +3948,7 @@ static Address emitPreserveStructAccess(
>CGF.CGM.getTypes().getCGRecordLayout(

r366076 - fix unnamed fiefield issue and add tests for __builtin_preserve_access_index intrinsic

2019-07-15 Thread Yonghong Song via cfe-commits
Author: yhs
Date: Mon Jul 15 08:42:41 2019
New Revision: 366076

URL: http://llvm.org/viewvc/llvm-project?rev=366076=rev
Log:
fix unnamed fiefield issue and add tests for __builtin_preserve_access_index 
intrinsic

This is a followup patch for https://reviews.llvm.org/D61809.
Handle unnamed bitfield properly and add more test cases.

Fixed the unnamed bitfield issue. The unnamed bitfield is ignored
by debug info, so we need to ignore such a struct/union member
when we try to get the member index in the debug info.

D61809 contains two test cases but not enough as it does
not checking generated IRs in the fine grain level, and also
it does not have semantics checking tests.
This patch added unit tests for both code gen and semantics checking for
the new intrinsic.

Signed-off-by: Yonghong Song 

Added:
cfe/trunk/test/CodeGen/builtin-preserve-access-index.c
cfe/trunk/test/Sema/builtin-preserve-access-index.c
Modified:
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=366076=366075=366076=diff
==
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Mon Jul 15 08:42:41 2019
@@ -3892,6 +3892,23 @@ LValue CodeGenFunction::EmitLValueForLam
   return EmitLValueForField(LambdaLV, Field);
 }
 
+/// 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;
+}
+
 /// 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 , Address Base,
@@ -3931,7 +3948,7 @@ static Address emitPreserveStructAccess(
   CGF.CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field);
 
   return CGF.Builder.CreatePreserveStructAccessIndex(
-  base, idx, field->getFieldIndex(), DbgInfo);
+  base, idx, CGF.getDebugInfoFIndex(rec, field->getFieldIndex()), DbgInfo);
 }
 
 static bool hasAnyVptr(const QualType Type, const ASTContext ) {
@@ -4048,7 +4065,7 @@ LValue CodeGenFunction::EmitLValueForFie
   getContext().getRecordType(rec), rec->getLocation());
   addr = Address(
   Builder.CreatePreserveUnionAccessIndex(
-  addr.getPointer(), field->getFieldIndex(), DbgInfo),
+  addr.getPointer(), getDebugInfoFIndex(rec, 
field->getFieldIndex()), DbgInfo),
   addr.getAlignment());
 }
   } else {

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=366076=366075=366076=diff
==
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Mon Jul 15 08:42:41 2019
@@ -2652,6 +2652,9 @@ public:
   /// Converts Location to a DebugLoc, if debug information is enabled.
   llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location);
 
+  /// Get the record field index as represented in debug info.
+  unsigned getDebugInfoFIndex(const RecordDecl *Rec, unsigned FieldIndex);
+
 
   
//======//
   //Declaration Emission

Added: cfe/trunk/test/CodeGen/builtin-preserve-access-index.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtin-preserve-access-index.c?rev=366076=auto
==
--- cfe/trunk/test/CodeGen/builtin-preserve-access-index.c (added)
+++ cfe/trunk/test/CodeGen/builtin-preserve-access-index.c Mon Jul 15 08:42:41 
2019
@@ -0,0 +1,177 @@
+// RUN: %clang -target x86_64 -emit-llvm -S -g %s -o - | FileCheck %s
+
+#define _(x) (__builtin_preserve_access_index(x))
+
+const void *unit1(const void *arg) {
+  return _(arg);
+}
+// CHECK: define dso_local i8* @unit1(i8* %arg)
+// CHECK-NOT: llvm.preserve.array.access.index
+// CHECK-NOT: llvm.preserve.struct.access.index
+// CHECK-NOT: llvm.preserve.union.access.index
+
+const void *unit2(void) {
+  return _((const void *)0xULL);
+}
+// CHECK: define dso_local i8* @unit2()
+// CHECK-NOT: llvm.preserve.array.access.index
+// CHECK-NOT: llvm.preserve.struct.access.index
+// CHECK-NOT: llvm.preserve.union.access.index
+
+const void *unit3(const int *arg) {
+  return _(arg + 1);
+}
+// CHECK: define dso_local i8* @unit3(i32* %arg)
+// CHECK-NOT: 

r365438 - [BPF] Preserve debuginfo array/union/struct type/access index

2019-07-08 Thread Yonghong Song via cfe-commits
Author: yhs
Date: Mon Jul  8 21:21:50 2019
New Revision: 365438

URL: http://llvm.org/viewvc/llvm-project?rev=365438=rev
Log:
[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(_id, sizeof(char), _(>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 >u[5].dev.dev_id,
  . The "%6 = ..." represents struct member "u" with index 2 for IR layout and 
index 3 for DI 

r365436 - Revert "[BPF] Preserve debuginfo array/union/struct type/access index"

2019-07-08 Thread Yonghong Song via cfe-commits
Author: yhs
Date: Mon Jul  8 21:15:12 2019
New Revision: 365436

URL: http://llvm.org/viewvc/llvm-project?rev=365436=rev
Log:
Revert "[BPF] Preserve debuginfo array/union/struct type/access index"

This reverts commit r365435.

Forgot adding the Differential Revision link. Will add to the
commit message and resubmit.

Removed:
cfe/trunk/test/CodeGen/bpf-preserve-access-index-2.c
cfe/trunk/test/CodeGen/bpf-preserve-access-index.c
Modified:
cfe/trunk/docs/LanguageExtensions.rst
cfe/trunk/include/clang/Basic/Builtins.def
cfe/trunk/lib/CodeGen/CGBuilder.h
cfe/trunk/lib/CodeGen/CGBuiltin.cpp
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
cfe/trunk/lib/Sema/SemaChecking.cpp

Modified: cfe/trunk/docs/LanguageExtensions.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=365436=365435=365436=diff
==
--- cfe/trunk/docs/LanguageExtensions.rst (original)
+++ cfe/trunk/docs/LanguageExtensions.rst Mon Jul  8 21:15:12 2019
@@ -1950,35 +1950,6 @@ form of ``__builtin_operator_delete`` is
 These builtins are intended for use in the implementation of ``std::allocator``
 and other similar allocation libraries, and are only available in C++.
 
-``__builtin_preserve_access_index``

-
-``__builtin_preserve_access_index`` specifies a code section where
-array subscript access and structure/union member access are relocatable
-under bpf compile-once run-everywhere framework. Debuginfo (typically
-with ``-g``) is needed, otherwise, the compiler will exit with an error.
-
-**Syntax**:
-
-.. code-block:: c
-
-  const void * __builtin_preserve_access_index(const void * ptr)
-
-**Example of Use**:
-
-.. code-block:: c
-
-  struct t {
-int i;
-int j;
-union {
-  int a;
-  int b;
-} c[4];
-  };
-  struct t *v = ...;
-  const void *pb =__builtin_preserve_access_index(>c[3].b);
-
 Multiprecision Arithmetic Builtins
 --
 

Modified: cfe/trunk/include/clang/Basic/Builtins.def
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=365436=365435=365436=diff
==
--- cfe/trunk/include/clang/Basic/Builtins.def (original)
+++ cfe/trunk/include/clang/Basic/Builtins.def Mon Jul  8 21:15:12 2019
@@ -1449,7 +1449,6 @@ BUILTIN(__builtin_operator_new, "v*z", "
 BUILTIN(__builtin_operator_delete, "vv*", "tn")
 BUILTIN(__builtin_char_memchr, "c*cC*iz", "n")
 BUILTIN(__builtin_dump_struct, "ivC*v*", "tn")
-BUILTIN(__builtin_preserve_access_index, "vC*vC*", "nU")
 
 // Safestack builtins
 BUILTIN(__builtin___get_unsafe_stack_start, "v*", "Fn")

Modified: cfe/trunk/lib/CodeGen/CGBuilder.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuilder.h?rev=365436=365435=365436=diff
==
--- cfe/trunk/lib/CodeGen/CGBuilder.h (original)
+++ cfe/trunk/lib/CodeGen/CGBuilder.h Mon Jul  8 21:15:12 2019
@@ -298,21 +298,6 @@ public:
 return CreateMemSet(Dest.getPointer(), Value, Size,
 Dest.getAlignment().getQuantity(), IsVolatile);
   }
-
-  using CGBuilderBaseTy::CreatePreserveStructAccessIndex;
-  Address CreatePreserveStructAccessIndex(Address Addr,
-  unsigned Index,
-  unsigned FieldIndex,
-  llvm::MDNode *DbgInfo) {
-llvm::StructType *ElTy = cast(Addr.getElementType());
-const llvm::DataLayout  = BB->getParent()->getParent()->getDataLayout();
-const llvm::StructLayout *Layout = DL.getStructLayout(ElTy);
-auto Offset = CharUnits::fromQuantity(Layout->getElementOffset(Index));
-
-return Address(CreatePreserveStructAccessIndex(Addr.getPointer(),
-   Index, FieldIndex, DbgInfo),
-   Addr.getAlignment().alignmentAtOffset(Offset));
-  }
 };
 
 }  // end namespace CodeGen

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=365436=365435=365436=diff
==
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Mon Jul  8 21:15:12 2019
@@ -1840,27 +1840,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(
 return RValue::get(Res);
   }
 
-  case Builtin::BI__builtin_preserve_access_index: {
-// Only enabled preserved access index region when debuginfo
-// is available as debuginfo is needed to preserve user-level
-// access pattern.
-if (!getDebugInfo()) {
-  CGM.Error(E->getExprLoc(), "using builtin_preserve_access_index() 
without -g");
-  return 

r365435 - [BPF] Preserve debuginfo array/union/struct type/access index

2019-07-08 Thread Yonghong Song via cfe-commits
Author: yhs
Date: Mon Jul  8 21:04:21 2019
New Revision: 365435

URL: http://llvm.org/viewvc/llvm-project?rev=365435=rev
Log:
[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(_id, sizeof(char), _(>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 >u[5].dev.dev_id,
  . The "%6 = ..." represents struct member "u" with index 2 for IR layout and 
index 3 for DI 

r359310 - [BPF] do not generate predefined macro bpf

2019-04-26 Thread Yonghong Song via cfe-commits
Author: yhs
Date: Fri Apr 26 08:35:51 2019
New Revision: 359310

URL: http://llvm.org/viewvc/llvm-project?rev=359310=rev
Log:
[BPF] do not generate predefined macro bpf

"DefineStd(Builder, "bpf", Opts)" generates the following three
macros:
  bpf
  __bpf
  __bpf__
and the macro "bpf" is due to the fact that the target language
is C which allows GNU extensions.

The name "bpf" could be easily used as variable name or type
field name. For example, in current linux kernel, there are
four places where bpf is used as a field name. If the corresponding
types are included in bpf program, the compilation error will
occur.

This patch removed predefined macro "bpf" as well as "__bpf" which
is rarely used if used at all.

Signed-off-by: Yonghong Song 

Differential Revision: https://reviews.llvm.org/D61173

Added:
cfe/trunk/test/Preprocessor/bpf-predefined-macros.c
Modified:
cfe/trunk/lib/Basic/Targets/BPF.cpp

Modified: cfe/trunk/lib/Basic/Targets/BPF.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets/BPF.cpp?rev=359310=359309=359310=diff
==
--- cfe/trunk/lib/Basic/Targets/BPF.cpp (original)
+++ cfe/trunk/lib/Basic/Targets/BPF.cpp Fri Apr 26 08:35:51 2019
@@ -20,7 +20,7 @@ using namespace clang::targets;
 
 void BPFTargetInfo::getTargetDefines(const LangOptions ,
  MacroBuilder ) const {
-  DefineStd(Builder, "bpf", Opts);
+  Builder.defineMacro("__bpf__");
   Builder.defineMacro("__BPF__");
 }
 

Added: cfe/trunk/test/Preprocessor/bpf-predefined-macros.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/bpf-predefined-macros.c?rev=359310=auto
==
--- cfe/trunk/test/Preprocessor/bpf-predefined-macros.c (added)
+++ cfe/trunk/test/Preprocessor/bpf-predefined-macros.c Fri Apr 26 08:35:51 2019
@@ -0,0 +1,16 @@
+// RUN: %clang -E -target bpfel -x c -o - %s | FileCheck %s
+// RUN: %clang -E -target bpfeb -x c -o - %s | FileCheck %s
+
+#ifdef __bpf__
+int b;
+#endif
+#ifdef __BPF__
+int c;
+#endif
+#ifdef bpf
+int d;
+#endif
+
+// CHECK: int b;
+// CHECK: int c;
+// CHECK-NOT: int d;


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r334839 - bpf: recognize target specific option -mattr=dwarfris in clang

2018-06-15 Thread Yonghong Song via cfe-commits
Author: yhs
Date: Fri Jun 15 08:53:31 2018
New Revision: 334839

URL: http://llvm.org/viewvc/llvm-project?rev=334839=rev
Log:
bpf: recognize target specific option -mattr=dwarfris in clang

The following is the usage example with clang:
  bash-4.2$ clang -target bpf -O2 -g -c -Xclang -target-feature -Xclang 
+dwarfris t.c
  bash-4.2$ llvm-objdump -S -d t.o

  t.o:file format ELF64-BPF

  Disassembly of section .text:
  test:
  ; int test(void) {
   0:   b7 00 00 00 00 00 00 00 r0 = 0
  ; return 0;
 1:   95 00 00 00 00 00 00 00 exit
  bash-4.2$ cat t.c
  int test(void) {
return 0;
  }
  bash-4.2$

Signed-off-by: Yonghong Song 

Modified:
cfe/trunk/lib/Basic/Targets/BPF.h

Modified: cfe/trunk/lib/Basic/Targets/BPF.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets/BPF.h?rev=334839=334838=334839=diff
==
--- cfe/trunk/lib/Basic/Targets/BPF.h (original)
+++ cfe/trunk/lib/Basic/Targets/BPF.h Fri Jun 15 08:53:31 2018
@@ -47,7 +47,7 @@ public:
 MacroBuilder ) const override;
 
   bool hasFeature(StringRef Feature) const override {
-return Feature == "bpf" || Feature == "alu32";
+return Feature == "bpf" || Feature == "alu32" || Feature == "dwarfris";
   }
 
   void setFeatureEnabled(llvm::StringMap , StringRef Name,


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r329823 - bpf: accept all asm register names

2018-04-12 Thread Yonghong Song via cfe-commits
Author: yhs
Date: Wed Apr 11 09:08:00 2018
New Revision: 329823

URL: http://llvm.org/viewvc/llvm-project?rev=329823=rev
Log:
bpf: accept all asm register names

Sometimes when people compile bpf programs with
"clang ... -target bpf ...", the kernel header
files may contain host arch inline assembly codes
as in the patch https://patchwork.kernel.org/patch/10119683/
by Arnaldo Carvaldo de Melo.

The current workaround in the above patch
is to guard the inline assembly with "#ifndef __BPF__"
marco. So when __BPF__ is defined, these macros will
have no use.

Such a method is not extensible. As a matter of fact,
most of these inline assembly codes will be thrown away
at the end of clang compilation.

So for bpf target, this patch accepts all asm register
names in clang AST stage. The name will be checked
again during llc code generation if the inline assembly
code is indeed for bpf programs.

With this patch, the above "#ifndef __BPF__" is not needed
any more in https://patchwork.kernel.org/patch/10119683/.

Signed-off-by: Yonghong Song 

Modified:
cfe/trunk/include/clang/Basic/TargetInfo.h
cfe/trunk/lib/Basic/Targets/BPF.h

Modified: cfe/trunk/include/clang/Basic/TargetInfo.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TargetInfo.h?rev=329823=329822=329823=diff
==
--- cfe/trunk/include/clang/Basic/TargetInfo.h (original)
+++ cfe/trunk/include/clang/Basic/TargetInfo.h Wed Apr 11 09:08:00 2018
@@ -619,7 +619,7 @@ public:
   /// according to GCC.
   ///
   /// This is used by Sema for inline asm statements.
-  bool isValidGCCRegisterName(StringRef Name) const;
+  virtual bool isValidGCCRegisterName(StringRef Name) const;
 
   /// \brief Returns the "normalized" GCC register name.
   ///

Modified: cfe/trunk/lib/Basic/Targets/BPF.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets/BPF.h?rev=329823=329822=329823=diff
==
--- cfe/trunk/lib/Basic/Targets/BPF.h (original)
+++ cfe/trunk/lib/Basic/Targets/BPF.h Wed Apr 11 09:08:00 2018
@@ -63,6 +63,7 @@ public:
 return TargetInfo::VoidPtrBuiltinVaList;
   }
 
+  bool isValidGCCRegisterName(StringRef Name) const override { return true; }
   ArrayRef getGCCRegNames() const override { return None; }
 
   bool validateAsmConstraint(const char *,


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r325996 - bpf: Hook target feature "alu32" with LLVM

2018-02-24 Thread Yonghong Song via cfe-commits
Author: yhs
Date: Fri Feb 23 15:55:29 2018
New Revision: 325996

URL: http://llvm.org/viewvc/llvm-project?rev=325996=rev
Log:
bpf: Hook target feature "alu32" with LLVM

LLVM has supported a new target feature "alu32" which could be enabled or
disabled by "-mattr=[+|-]alu32" when using llc.

This patch link Clang with it, so it could be also done by passing related
options to Clang, for example:

  -Xclang -target-feature -Xclang +alu32

Signed-off-by: Jiong Wang 
Reviewed-by: Yonghong Song 

Modified:
cfe/trunk/lib/Basic/Targets/BPF.h

Modified: cfe/trunk/lib/Basic/Targets/BPF.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets/BPF.h?rev=325996=325995=325996=diff
==
--- cfe/trunk/lib/Basic/Targets/BPF.h (original)
+++ cfe/trunk/lib/Basic/Targets/BPF.h Fri Feb 23 15:55:29 2018
@@ -46,7 +46,14 @@ public:
   void getTargetDefines(const LangOptions ,
 MacroBuilder ) const override;
 
-  bool hasFeature(StringRef Feature) const override { return Feature == "bpf"; 
}
+  bool hasFeature(StringRef Feature) const override {
+return Feature == "bpf" || Feature == "alu32";
+  }
+
+  void setFeatureEnabled(llvm::StringMap , StringRef Name,
+ bool Enabled) const override {
+Features[Name] = Enabled;
+  }
 
   ArrayRef getTargetBuiltins() const override { return None; }
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r311523 - bpf: add -mcpu=# support for bpf

2017-08-23 Thread Yonghong Song via cfe-commits
Author: yhs
Date: Tue Aug 22 21:26:17 2017
New Revision: 311523

URL: http://llvm.org/viewvc/llvm-project?rev=311523=rev
Log:
bpf: add -mcpu=# support for bpf

-mcpu=# will support:
  . generic: the default insn set
  . v1: insn set version 1, the same as generic
  . v2: insn set version 2, version 1 + additional jmp insns
  . probe: the compiler will probe the underlying kernel to
   decide proper version of insn set.

Examples:
$ clang -target bpf -mcpu=v1 -c t.c
$ clang -target bpf -mcpu=v2 -c t.c
$ clang -target bpf -mcpu=generic -c t.c
$ clang -target bpf -mcpu=probe -c t.c
$ clang -target bpf -mcpu=v3 -c t.c
error: unknown target CPU 'v3'

Signed-off-by: Yonghong Song 
Acked-by: Alexei Starovoitov 

Modified:
cfe/trunk/lib/Basic/Targets/BPF.h
cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp

Modified: cfe/trunk/lib/Basic/Targets/BPF.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets/BPF.h?rev=311523=311522=311523=diff
==
--- cfe/trunk/lib/Basic/Targets/BPF.h (original)
+++ cfe/trunk/lib/Basic/Targets/BPF.h Tue Aug 22 21:26:17 2017
@@ -76,6 +76,18 @@ public:
   return CCCR_OK;
 }
   }
+
+  bool isValidCPUName(StringRef Name) const override {
+if (Name == "generic" || Name == "v1" ||
+Name == "v2" || Name == "probe")
+  return true;
+return false;
+  }
+
+  bool setCPU(const std::string ) override {
+StringRef CPUName(Name);
+return isValidCPUName(CPUName);
+  }
 };
 } // namespace targets
 } // namespace clang

Modified: cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp?rev=311523=311522=311523=diff
==
--- cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp Tue Aug 22 21:26:17 2017
@@ -320,6 +320,8 @@ std::string tools::getCPUName(const ArgL
 return TargetCPUName;
   }
 
+  case llvm::Triple::bpfel:
+  case llvm::Triple::bpfeb:
   case llvm::Triple::sparc:
   case llvm::Triple::sparcel:
   case llvm::Triple::sparcv9:


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits