[PATCH] D145848: [Driver] Correct -f(no-)xray-function-index behavior

2023-03-11 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque accepted this revision.
ianlevesque added a comment.
This revision is now accepted and ready to land.

Good catch, thanks for the fix.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D145848

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


[PATCH] D129594: [InstrProf] Add options to profile function groups

2022-07-13 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque accepted this revision.
ianlevesque added a comment.
This revision is now accepted and ready to land.

lgtm


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129594

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


[PATCH] D129594: [InstrProf] Add options to profile function groups

2022-07-13 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque added inline comments.



Comment at: clang/lib/CodeGen/CodeGenModule.cpp:2871
+  if (NumGroups > 1) {
+auto Group = llvm::MD5Hash(Fn->getName()) % NumGroups;
+if (Group != getCodeGenOpts().ProfileSelectedFunctionGroup)

In D87953 I used crc32 to avoid computing an md5 hash on every function name.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129594

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


[PATCH] D89441: [xray] Honor xray-never function-instrument attribute

2021-01-19 Thread Ian Levesque via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG68a1f09107a4: [xray] Honor xray-never function-instrument 
attribute (authored by ianlevesque).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D89441

Files:
  llvm/lib/CodeGen/XRayInstrumentation.cpp
  llvm/test/CodeGen/AArch64/xray-attribute-instrumentation.ll

Index: llvm/test/CodeGen/AArch64/xray-attribute-instrumentation.ll
===
--- llvm/test/CodeGen/AArch64/xray-attribute-instrumentation.ll
+++ llvm/test/CodeGen/AArch64/xray-attribute-instrumentation.ll
@@ -1,6 +1,7 @@
 ; RUN: llc -filetype=asm -o - -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
 
 define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" {
+; CHECK-LABEL: foo:
 ; CHECK-LABEL: Lxray_sled_0:
 ; CHECK-NEXT:  b  #32
 ; CHECK-NEXT:  nop
@@ -24,8 +25,80 @@
 ; CHECK-LABEL: Ltmp1:
 ; CHECK-NEXT:  ret
 }
+
 ; CHECK-LABEL: xray_instr_map
 ; CHECK-LABEL: Lxray_sleds_start0
 ; CHECK:   .xword .Lxray_sled_0
 ; CHECK:   .xword .Lxray_sled_1
 ; CHECK-LABEL: Lxray_sleds_end0
+
+define i32 @bar() nounwind noinline uwtable "function-instrument"="xray-never" "function-instrument"="xray-always" {
+; CHECK-LABEL: bar:
+; CHECK-LABEL: Lxray_sled_2:
+; CHECK-NEXT:  b  #32
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-LABEL: Ltmp4:
+  ret i32 0
+; CHECK-LABEL: Lxray_sled_3:
+; CHECK-NEXT:  b  #32
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-LABEL: Ltmp5:
+; CHECK-NEXT:  ret
+}
+
+; CHECK-LABEL: xray_instr_map
+; CHECK-LABEL: Lxray_sleds_start1
+; CHECK:   .xword .Lxray_sled_2
+; CHECK:   .xword .Lxray_sled_3
+; CHECK-LABEL: Lxray_sleds_end1
+
+define i32 @instrumented() nounwind noinline uwtable "xray-instruction-threshold"="1" {
+; CHECK-LABEL: instrumented:
+; CHECK-LABEL: Lxray_sled_4:
+; CHECK-NEXT:  b  #32
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-LABEL: Ltmp8:
+  ret i32 0
+; CHECK-LABEL: Lxray_sled_5:
+; CHECK-NEXT:  b  #32
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-LABEL: Ltmp9:
+; CHECK-NEXT:  ret
+}
+
+; CHECK-LABEL: xray_instr_map
+; CHECK-LABEL: Lxray_sleds_start2
+; CHECK:   .xword .Lxray_sled_4
+; CHECK:   .xword .Lxray_sled_5
+; CHECK-LABEL: Lxray_sleds_end2
+
+define i32 @not_instrumented() nounwind noinline uwtable "xray-instruction-threshold"="1" "function-instrument"="xray-never" {
+; CHECK-LABEL: not_instrumented
+; CHECK-NOT: .Lxray_sled_6
+  ret i32 0
+; CHECK:  ret
+}
Index: llvm/lib/CodeGen/XRayInstrumentation.cpp
===
--- llvm/lib/CodeGen/XRayInstrumentation.cpp
+++ llvm/lib/CodeGen/XRayInstrumentation.cpp
@@ -147,6 +147,10 @@
   auto InstrAttr = F.getFnAttribute("function-instrument");
   bool AlwaysInstrument = InstrAttr.isStringAttribute() &&
   InstrAttr.getValueAsString() == "xray-always";
+  bool NeverInstrument = InstrAttr.isStringAttribute() &&
+ InstrAttr.getValueAsString() == "xray-never";
+  if (NeverInstrument && !AlwaysInstrument)
+return false;
   auto ThresholdAttr = F.getFnAttribute("xray-instruction-threshold");
   auto IgnoreLoopsAttr = F.getFnAttribute("xray-ignore-loops");
   unsigned int XRayThreshold = 0;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D89441: RFC: Potential fixes to function-instrument=xray-never

2020-10-15 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque updated this revision to Diff 298534.
ianlevesque added a comment.

Apply the fix in XRayInstrumentation, add test cases.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D89441

Files:
  llvm/lib/CodeGen/XRayInstrumentation.cpp
  llvm/test/CodeGen/AArch64/xray-attribute-instrumentation.ll

Index: llvm/test/CodeGen/AArch64/xray-attribute-instrumentation.ll
===
--- llvm/test/CodeGen/AArch64/xray-attribute-instrumentation.ll
+++ llvm/test/CodeGen/AArch64/xray-attribute-instrumentation.ll
@@ -1,6 +1,7 @@
 ; RUN: llc -filetype=asm -o - -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
 
 define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" {
+; CHECK-LABEL: foo:
 ; CHECK-LABEL: Lxray_sled_0:
 ; CHECK-NEXT:  b  #32
 ; CHECK-NEXT:  nop
@@ -24,8 +25,80 @@
 ; CHECK-LABEL: Ltmp1:
 ; CHECK-NEXT:  ret
 }
+
 ; CHECK-LABEL: xray_instr_map
 ; CHECK-LABEL: Lxray_sleds_start0
 ; CHECK:   .xword .Lxray_sled_0
 ; CHECK:   .xword .Lxray_sled_1
 ; CHECK-LABEL: Lxray_sleds_end0
+
+define i32 @bar() nounwind noinline uwtable "function-instrument"="xray-never" "function-instrument"="xray-always" {
+; CHECK-LABEL: bar:
+; CHECK-LABEL: Lxray_sled_2:
+; CHECK-NEXT:  b  #32
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-LABEL: Ltmp4:
+  ret i32 0
+; CHECK-LABEL: Lxray_sled_3:
+; CHECK-NEXT:  b  #32
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-LABEL: Ltmp5:
+; CHECK-NEXT:  ret
+}
+
+; CHECK-LABEL: xray_instr_map
+; CHECK-LABEL: Lxray_sleds_start1
+; CHECK:   .xword .Lxray_sled_2
+; CHECK:   .xword .Lxray_sled_3
+; CHECK-LABEL: Lxray_sleds_end1
+
+define i32 @instrumented() nounwind noinline uwtable "xray-instruction-threshold"="1" {
+; CHECK-LABEL: instrumented:
+; CHECK-LABEL: Lxray_sled_4:
+; CHECK-NEXT:  b  #32
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-LABEL: Ltmp8:
+  ret i32 0
+; CHECK-LABEL: Lxray_sled_5:
+; CHECK-NEXT:  b  #32
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-LABEL: Ltmp9:
+; CHECK-NEXT:  ret
+}
+
+; CHECK-LABEL: xray_instr_map
+; CHECK-LABEL: Lxray_sleds_start2
+; CHECK:   .xword .Lxray_sled_4
+; CHECK:   .xword .Lxray_sled_5
+; CHECK-LABEL: Lxray_sleds_end2
+
+define i32 @not_instrumented() nounwind noinline uwtable "xray-instruction-threshold"="1" "function-instrument"="xray-never" {
+; CHECK-LABEL: not_instrumented
+; CHECK-NOT: .Lxray_sled_6
+  ret i32 0
+; CHECK:  ret
+}
Index: llvm/lib/CodeGen/XRayInstrumentation.cpp
===
--- llvm/lib/CodeGen/XRayInstrumentation.cpp
+++ llvm/lib/CodeGen/XRayInstrumentation.cpp
@@ -147,6 +147,10 @@
   auto InstrAttr = F.getFnAttribute("function-instrument");
   bool AlwaysInstrument = InstrAttr.isStringAttribute() &&
   InstrAttr.getValueAsString() == "xray-always";
+  bool NeverInstrument = InstrAttr.isStringAttribute() &&
+ InstrAttr.getValueAsString() == "xray-never";
+  if (NeverInstrument && !AlwaysInstrument)
+return false;
   auto ThresholdAttr = F.getFnAttribute("xray-instruction-threshold");
   auto IgnoreLoopsAttr = F.getFnAttribute("xray-ignore-loops");
   unsigned int XRayThreshold = 0;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D89441: RFC: Potential fixes to function-instrument=xray-never

2020-10-14 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque created this revision.
ianlevesque added reviewers: dberris, MaskRay.
Herald added subscribers: llvm-commits, cfe-commits, hiraditya.
Herald added projects: clang, LLVM.
ianlevesque requested review of this revision.

When using https://reviews.llvm.org/D87953 I discovered that the 
function-instrument="xray-never" attribute doesn't actually do anything. The 
only reason [[clang::xray_never_instrument]] ever worked was that the code path 
that parses it coincidentally doesn't set the xray-instruction-threshold 
attribute on annotated functions. Do you think we should fix this by handling 
the xray-never attribute in XRayInstrumentation, or having CodeGenFunction 
remove the threshold if xray-never is set? Or something else? I included both 
possible fixes in this diff. I can code up either one with tests if we agree on 
an approach.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D89441

Files:
  clang/lib/CodeGen/CodeGenFunction.cpp
  llvm/lib/CodeGen/XRayInstrumentation.cpp


Index: llvm/lib/CodeGen/XRayInstrumentation.cpp
===
--- llvm/lib/CodeGen/XRayInstrumentation.cpp
+++ llvm/lib/CodeGen/XRayInstrumentation.cpp
@@ -145,6 +145,10 @@
 bool XRayInstrumentation::runOnMachineFunction(MachineFunction ) {
   auto  = MF.getFunction();
   auto InstrAttr = F.getFnAttribute("function-instrument");
+  bool NeverInstrument = InstrAttr.isStringAttribute() &&
+ InstrAttr.getValueAsString() == "xray-never";
+  if (NeverInstrument)
+return false;
   bool AlwaysInstrument = InstrAttr.isStringAttribute() &&
   InstrAttr.getValueAsString() == "xray-always";
   auto ThresholdAttr = F.getFnAttribute("xray-instruction-threshold");
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -817,8 +817,10 @@
   CurFn->getName().bytes_begin(), CurFn->getName().bytes_end());
   auto Group = crc32(FuncName) % FuncGroups;
   if (Group != CGM.getCodeGenOpts().XRaySelectedFunctionGroup &&
-  !AlwaysXRayAttr)
+  !AlwaysXRayAttr) {
+Fn->removeFnAttr("xray-instruction-threshold");
 Fn->addFnAttr("function-instrument", "xray-never");
+  }
 }
   }
 


Index: llvm/lib/CodeGen/XRayInstrumentation.cpp
===
--- llvm/lib/CodeGen/XRayInstrumentation.cpp
+++ llvm/lib/CodeGen/XRayInstrumentation.cpp
@@ -145,6 +145,10 @@
 bool XRayInstrumentation::runOnMachineFunction(MachineFunction ) {
   auto  = MF.getFunction();
   auto InstrAttr = F.getFnAttribute("function-instrument");
+  bool NeverInstrument = InstrAttr.isStringAttribute() &&
+ InstrAttr.getValueAsString() == "xray-never";
+  if (NeverInstrument)
+return false;
   bool AlwaysInstrument = InstrAttr.isStringAttribute() &&
   InstrAttr.getValueAsString() == "xray-always";
   auto ThresholdAttr = F.getFnAttribute("xray-instruction-threshold");
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -817,8 +817,10 @@
   CurFn->getName().bytes_begin(), CurFn->getName().bytes_end());
   auto Group = crc32(FuncName) % FuncGroups;
   if (Group != CGM.getCodeGenOpts().XRaySelectedFunctionGroup &&
-  !AlwaysXRayAttr)
+  !AlwaysXRayAttr) {
+Fn->removeFnAttr("xray-instruction-threshold");
 Fn->addFnAttr("function-instrument", "xray-never");
+  }
 }
   }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D87953: [xray] Function coverage groups

2020-09-24 Thread Ian Levesque via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6f7fbdd2857f: [xray] Function coverage groups (authored by 
ianlevesque).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87953

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/include/clang/Driver/XRayArgs.h
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/Driver/XRayArgs.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/xray-function-groups.cpp
  llvm/docs/XRay.rst

Index: llvm/docs/XRay.rst
===
--- llvm/docs/XRay.rst
+++ llvm/docs/XRay.rst
@@ -62,17 +62,18 @@
 
   clang -fxray-instrument ...
 
-By default, functions that have at least 200 instructions will get XRay
-instrumentation points. You can tweak that number through the
+By default, functions that have at least 200 instructions (or contain a loop) will
+get XRay instrumentation points. You can tweak that number through the
 ``-fxray-instruction-threshold=`` flag:
 
 ::
 
   clang -fxray-instrument -fxray-instruction-threshold=1 ...
 
-You can also specifically instrument functions in your binary to either always
-or never be instrumented using source-level attributes. You can do it using the
-GCC-style attributes or C++11-style attributes.
+The loop detection can be disabled with ``-fxray-ignore-loops`` to use only the
+instruction threshold. You can also specifically instrument functions in your
+binary to either always or never be instrumented using source-level attributes.
+You can do it using the GCC-style attributes or C++11-style attributes.
 
 .. code-block:: c++
 
@@ -309,6 +310,35 @@
   instrumentation map in XRay-instrumented object files and binaries. The
   ``extract`` and ``stack`` subcommands uses this particular library.
 
+
+Minimizing Binary Size
+--
+
+XRay supports several different instrumentation points including ``function-entry``,
+``function-exit``, ``custom``, and ``typed`` points. These can be enabled individually
+using the ``-fxray-instrumentaton-bundle=`` flag. For example if you only wanted to
+instrument function entry and custom points you could specify:
+
+::
+
+  clang -fxray-instrument -fxray-instrumentation-bundle=function-entry,custom ...
+
+This will omit the other sled types entirely, reducing the binary size. You can also
+instrument just a sampled subset of functions using instrumentation groups.
+For example, to instrument only a quarter of available functions invoke:
+
+::
+
+  clang -fxray-instrument -fxray-function-groups=4
+
+A subset will be chosen arbitrarily based on a hash of the function name. To sample a
+different subset you can specify ``-fxray-selected-function-group=`` with a group number
+in the range of 0 to ``xray-function-groups`` - 1.  Together these options could be used
+to produce multiple binaries with different instrumented subsets. If all you need is
+runtime control over which functions are being traced at any given time it is better
+to selectively patch and unpatch the individual functions you need using the XRay
+Runtime Library's ``__xray_patch_function()`` method.
+
 Future Work
 ===
 
Index: clang/test/CodeGen/xray-function-groups.cpp
===
--- /dev/null
+++ clang/test/CodeGen/xray-function-groups.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -fxray-instrument -fxray-instruction-threshold=1 -fxray-function-groups=3 -fxray-selected-function-group=0 \
+// RUN:-emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck --check-prefix=GROUP0 %s
+
+// RUN: %clang_cc1 -fxray-instrument -fxray-instruction-threshold=1 -fxray-function-groups=3 -fxray-selected-function-group=1 \
+// RUN:-emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck --check-prefix=GROUP1 %s
+
+// RUN: %clang_cc1 -fxray-instrument -fxray-instruction-threshold=1 -fxray-function-groups=3 -fxray-selected-function-group=2 \
+// RUN:-emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck --check-prefix=GROUP2 %s
+
+static int foo() { // part of group 0
+  return 1;
+}
+
+int bar() { // part of group 2
+  return 1;
+}
+
+int yarr() { // part of group 1
+  foo();
+  return 1;
+}
+
+[[clang::xray_always_instrument]] int always() { // part of group 0
+  return 1;
+}
+
+[[clang::xray_never_instrument]] int never() { // part of group 1
+  return 1;
+}
+
+// GROUP0: define{{.*}} i32 @_Z3barv() #[[ATTRS_BAR:[0-9]+]] {
+// GROUP0: define{{.*}} i32 @_Z4yarrv() #[[ATTRS_BAR]] {
+// GROUP0: define{{.*}} i32 @_ZL3foov() #[[ATTRS_FOO:[0-9]+]] {
+// GROUP0: define{{.*}} i32 @_Z6alwaysv() #[[ATTRS_ALWAYS:[0-9]+]] {
+// GROUP0: define{{.*}} i32 @_Z5neverv() #[[ATTRS_NEVER:[0-9]+]] {
+// GROUP0-DAG: attributes #[[ATTRS_BAR]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+// 

[PATCH] D87953: [xray] Function coverage groups

2020-09-24 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque updated this revision to Diff 294213.
ianlevesque added a comment.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Add static function to the test case, update documentation.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87953

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/include/clang/Driver/XRayArgs.h
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/Driver/XRayArgs.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/xray-function-groups.cpp
  llvm/docs/XRay.rst

Index: llvm/docs/XRay.rst
===
--- llvm/docs/XRay.rst
+++ llvm/docs/XRay.rst
@@ -62,17 +62,18 @@
 
   clang -fxray-instrument ...
 
-By default, functions that have at least 200 instructions will get XRay
-instrumentation points. You can tweak that number through the
+By default, functions that have at least 200 instructions (or contain a loop) will
+get XRay instrumentation points. You can tweak that number through the
 ``-fxray-instruction-threshold=`` flag:
 
 ::
 
   clang -fxray-instrument -fxray-instruction-threshold=1 ...
 
-You can also specifically instrument functions in your binary to either always
-or never be instrumented using source-level attributes. You can do it using the
-GCC-style attributes or C++11-style attributes.
+The loop detection can be disabled with ``-fxray-ignore-loops`` to use only the
+instruction threshold. You can also specifically instrument functions in your
+binary to either always or never be instrumented using source-level attributes.
+You can do it using the GCC-style attributes or C++11-style attributes.
 
 .. code-block:: c++
 
@@ -309,6 +310,35 @@
   instrumentation map in XRay-instrumented object files and binaries. The
   ``extract`` and ``stack`` subcommands uses this particular library.
 
+
+Minimizing Binary Size
+--
+
+XRay supports several different instrumentation points including ``function-entry``,
+``function-exit``, ``custom``, and ``typed`` points. These can be enabled individually
+using the ``-fxray-instrumentaton-bundle=`` flag. For example if you only wanted to
+instrument function entry and custom points you could specify:
+
+::
+
+  clang -fxray-instrument -fxray-instrumentation-bundle=function-entry,custom ...
+
+This will omit the other sled types entirely, reducing the binary size. You can also
+instrument just a sampled subset of functions using instrumentation groups.
+For example, to instrument only a quarter of available functions invoke:
+
+::
+
+  clang -fxray-instrument -fxray-function-groups=4
+
+A subset will be chosen arbitrarily based on a hash of the function name. To sample a
+different subset you can specify ``-fxray-selected-function-group=`` with a group number
+in the range of 0 to ``xray-function-groups`` - 1.  Together these options could be used
+to produce multiple binaries with different instrumented subsets. If all you need is
+runtime control over which functions are being traced at any given time it is better
+to selectively patch and unpatch the individual functions you need using the XRay
+Runtime Library's ``__xray_patch_function()`` method.
+
 Future Work
 ===
 
Index: clang/test/CodeGen/xray-function-groups.cpp
===
--- /dev/null
+++ clang/test/CodeGen/xray-function-groups.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -fxray-instrument -fxray-instruction-threshold=1 -fxray-function-groups=3 -fxray-selected-function-group=0 \
+// RUN:-emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck --check-prefix=GROUP0 %s
+
+// RUN: %clang_cc1 -fxray-instrument -fxray-instruction-threshold=1 -fxray-function-groups=3 -fxray-selected-function-group=1 \
+// RUN:-emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck --check-prefix=GROUP1 %s
+
+// RUN: %clang_cc1 -fxray-instrument -fxray-instruction-threshold=1 -fxray-function-groups=3 -fxray-selected-function-group=2 \
+// RUN:-emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck --check-prefix=GROUP2 %s
+
+static int foo() { // part of group 0
+  return 1;
+}
+
+int bar() { // part of group 2
+  return 1;
+}
+
+int yarr() { // part of group 1
+  foo();
+  return 1;
+}
+
+[[clang::xray_always_instrument]] int always() { // part of group 0
+  return 1;
+}
+
+[[clang::xray_never_instrument]] int never() { // part of group 1
+  return 1;
+}
+
+// GROUP0: define{{.*}} i32 @_Z3barv() #[[ATTRS_BAR:[0-9]+]] {
+// GROUP0: define{{.*}} i32 @_Z4yarrv() #[[ATTRS_BAR]] {
+// GROUP0: define{{.*}} i32 @_ZL3foov() #[[ATTRS_FOO:[0-9]+]] {
+// GROUP0: define{{.*}} i32 @_Z6alwaysv() #[[ATTRS_ALWAYS:[0-9]+]] {
+// GROUP0: define{{.*}} i32 @_Z5neverv() #[[ATTRS_NEVER:[0-9]+]] {
+// GROUP0-DAG: attributes #[[ATTRS_BAR]] = {{.*}} 

[PATCH] D87953: [xray] Function coverage groups

2020-09-24 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque added a comment.

I can update the docs @MaskRay, not a problem. I'll tweak the test a little too 
per your comment.

@dberris I think if we wanted to control it in a non-'random' (the crc32 was 
chosen so it would be consistent even though it's not really predictable up 
front) way we'd have to emit some lists of function attributes and use the 
-fxray-attr-list=FILE option to really dial that in. If we wanted entire 
modules we could have the build system apply xray's flags to each module 
differently, but we are unlikely to want to instrument every function of a 
module at the same time so we are back to having to use instruction thresholds 
to cut down on it.  Ultimately I think those two suggestions are legitimate 
alternative use cases but don't, for what we're trying to do, replace this 
strategy.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87953

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


[PATCH] D87953: [xray] Function coverage groups

2020-09-24 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque added a comment.

Thanks @MaskRay - I tried to answer that question in 
https://reviews.llvm.org/D87953#2286430. At present we are deploying 
instrumentation to an arbitrary subset of our application using the instruction 
threshold. I would like to make the selection of how many and which functions 
more deterministic, and be able to instrument different subsets over time.  The 
overhead we are concerned with is purely binary size as we are deploying to 
Android devices. We are using features from my previous XRay patches to omit 
the function index already, but the sheer number of sleds and size of the 
associated xray_instr_map are the limiting factor of how much we can instrument 
in any given app release.  For our use case it is fine to gradually over a 
period of weeks work our way across the entire app group by group.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87953

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


[PATCH] D87953: [xray] Function coverage groups

2020-09-23 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque updated this revision to Diff 293826.
ianlevesque added a comment.

Remove extraneous parameter validations.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87953

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/include/clang/Driver/XRayArgs.h
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/Driver/XRayArgs.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/xray-function-groups.cpp

Index: clang/test/CodeGen/xray-function-groups.cpp
===
--- /dev/null
+++ clang/test/CodeGen/xray-function-groups.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -fxray-instrument -fxray-instruction-threshold=1 -fxray-function-groups=3 -fxray-selected-function-group=0 \
+// RUN:-emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck --check-prefix=GROUP0 %s
+
+// RUN: %clang_cc1 -fxray-instrument -fxray-instruction-threshold=1 -fxray-function-groups=3 -fxray-selected-function-group=1 \
+// RUN:-emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck --check-prefix=GROUP1 %s
+
+// RUN: %clang_cc1 -fxray-instrument -fxray-instruction-threshold=1 -fxray-function-groups=3 -fxray-selected-function-group=2 \
+// RUN:-emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck --check-prefix=GROUP2 %s
+
+int foo() { // part of group 0
+  return 1;
+}
+
+int bar() { // part of group 2
+  return 1;
+}
+
+int yarr() { // part of group 1
+  return 1;
+}
+
+[[clang::xray_always_instrument]] int always() { // part of group 0
+  return 1;
+}
+
+[[clang::xray_never_instrument]] int never() { // part of group 1
+  return 1;
+}
+
+// GROUP0: define{{.*}} i32 @_Z3foov() #[[ATTRS_FOO:[0-9]+]] {
+// GROUP0: define{{.*}} i32 @_Z3barv() #[[ATTRS_BAR:[0-9]+]] {
+// GROUP0: define{{.*}} i32 @_Z4yarrv() #[[ATTRS_BAR]] {
+// GROUP0: define{{.*}} i32 @_Z6alwaysv() #[[ATTRS_ALWAYS:[0-9]+]] {
+// GROUP0: define{{.*}} i32 @_Z5neverv() #[[ATTRS_NEVER:[0-9]+]] {
+// GROUP0-DAG: attributes #[[ATTRS_BAR]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+// GROUP0-DAG: attributes #[[ATTRS_ALWAYS]] = {{.*}} "function-instrument"="xray-always" {{.*}}
+// GROUP0-DAG: attributes #[[ATTRS_NEVER]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+
+// GROUP1: define{{.*}} i32 @_Z3foov() #[[ATTRS_FOO:[0-9]+]] {
+// GROUP1: define{{.*}} i32 @_Z3barv() #[[ATTRS_FOO]] {
+// GROUP1: define{{.*}} i32 @_Z4yarrv() #[[ATTRS_YARR:[0-9]+]] {
+// GROUP1: define{{.*}} i32 @_Z6alwaysv() #[[ATTRS_ALWAYS:[0-9]+]] {
+// GROUP1: define{{.*}} i32 @_Z5neverv() #[[ATTRS_NEVER:[0-9]+]] {
+// GROUP1-DAG: attributes #[[ATTRS_FOO]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+// GROUP1-DAG: attributes #[[ATTRS_ALWAYS]] = {{.*}} "function-instrument"="xray-always" {{.*}}
+// GROUP1-DAG: attributes #[[ATTRS_NEVER]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+
+// GROUP2: define{{.*}} i32 @_Z3foov() #[[ATTRS_FOO:[0-9]+]] {
+// GROUP2: define{{.*}} i32 @_Z3barv() #[[ATTRS_BAR:[0-9]+]] {
+// GROUP2: define{{.*}} i32 @_Z4yarrv() #[[ATTRS_FOO]] {
+// GROUP2: define{{.*}} i32 @_Z6alwaysv() #[[ATTRS_ALWAYS:[0-9]+]] {
+// GROUP2: define{{.*}} i32 @_Z5neverv() #[[ATTRS_NEVER:[0-9]+]] {
+// GROUP2-DAG: attributes #[[ATTRS_FOO]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+// GROUP2-DAG: attributes #[[ATTRS_ALWAYS]] = {{.*}} "function-instrument"="xray-always" {{.*}}
+// GROUP2-DAG: attributes #[[ATTRS_NEVER]] = {{.*}} "function-instrument"="xray-never" {{.*}}
Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1130,6 +1130,10 @@
   getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
   Opts.XRayIgnoreLoops = Args.hasArg(OPT_fxray_ignore_loops);
   Opts.XRayOmitFunctionIndex = Args.hasArg(OPT_fno_xray_function_index);
+  Opts.XRayTotalFunctionGroups =
+  getLastArgIntValue(Args, OPT_fxray_function_groups, 1, Diags);
+  Opts.XRaySelectedFunctionGroup =
+  getLastArgIntValue(Args, OPT_fxray_selected_function_group, 0, Diags);
 
   auto XRayInstrBundles =
   Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
Index: clang/lib/Driver/XRayArgs.cpp
===
--- clang/lib/Driver/XRayArgs.cpp
+++ clang/lib/Driver/XRayArgs.cpp
@@ -186,6 +186,21 @@
   Modes.push_back(std::string(M));
 }
 
+  if (const Arg *A = Args.getLastArg(options::OPT_fxray_function_groups)) {
+StringRef S = A->getValue();
+if (S.getAsInteger(0, XRayFunctionGroups) || XRayFunctionGroups < 1)
+  D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
+  }
+
+  if (const Arg *A =
+  

[PATCH] D87953: [xray] Function coverage groups

2020-09-22 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque added a comment.

This is ready for another review, I think I addressed everything.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87953

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


[PATCH] D87953: [xray] Function coverage groups

2020-09-21 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque updated this revision to Diff 293289.
ianlevesque added a comment.

const


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87953

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/include/clang/Driver/XRayArgs.h
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/Driver/XRayArgs.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/xray-function-groups.cpp

Index: clang/test/CodeGen/xray-function-groups.cpp
===
--- /dev/null
+++ clang/test/CodeGen/xray-function-groups.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -fxray-instrument -fxray-instruction-threshold=1 -fxray-function-groups=3 -fxray-selected-function-group=0 \
+// RUN:-emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck --check-prefix=GROUP0 %s
+
+// RUN: %clang_cc1 -fxray-instrument -fxray-instruction-threshold=1 -fxray-function-groups=3 -fxray-selected-function-group=1 \
+// RUN:-emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck --check-prefix=GROUP1 %s
+
+// RUN: %clang_cc1 -fxray-instrument -fxray-instruction-threshold=1 -fxray-function-groups=3 -fxray-selected-function-group=2 \
+// RUN:-emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck --check-prefix=GROUP2 %s
+
+int foo() { // part of group 0
+  return 1;
+}
+
+int bar() { // part of group 2
+  return 1;
+}
+
+int yarr() { // part of group 1
+  return 1;
+}
+
+[[clang::xray_always_instrument]] int always() { // part of group 0
+  return 1;
+}
+
+[[clang::xray_never_instrument]] int never() { // part of group 1
+  return 1;
+}
+
+// GROUP0: define{{.*}} i32 @_Z3foov() #[[ATTRS_FOO:[0-9]+]] {
+// GROUP0: define{{.*}} i32 @_Z3barv() #[[ATTRS_BAR:[0-9]+]] {
+// GROUP0: define{{.*}} i32 @_Z4yarrv() #[[ATTRS_BAR]] {
+// GROUP0: define{{.*}} i32 @_Z6alwaysv() #[[ATTRS_ALWAYS:[0-9]+]] {
+// GROUP0: define{{.*}} i32 @_Z5neverv() #[[ATTRS_NEVER:[0-9]+]] {
+// GROUP0-DAG: attributes #[[ATTRS_BAR]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+// GROUP0-DAG: attributes #[[ATTRS_ALWAYS]] = {{.*}} "function-instrument"="xray-always" {{.*}}
+// GROUP0-DAG: attributes #[[ATTRS_NEVER]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+
+// GROUP1: define{{.*}} i32 @_Z3foov() #[[ATTRS_FOO:[0-9]+]] {
+// GROUP1: define{{.*}} i32 @_Z3barv() #[[ATTRS_FOO]] {
+// GROUP1: define{{.*}} i32 @_Z4yarrv() #[[ATTRS_YARR:[0-9]+]] {
+// GROUP1: define{{.*}} i32 @_Z6alwaysv() #[[ATTRS_ALWAYS:[0-9]+]] {
+// GROUP1: define{{.*}} i32 @_Z5neverv() #[[ATTRS_NEVER:[0-9]+]] {
+// GROUP1-DAG: attributes #[[ATTRS_FOO]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+// GROUP1-DAG: attributes #[[ATTRS_ALWAYS]] = {{.*}} "function-instrument"="xray-always" {{.*}}
+// GROUP1-DAG: attributes #[[ATTRS_NEVER]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+
+// GROUP2: define{{.*}} i32 @_Z3foov() #[[ATTRS_FOO:[0-9]+]] {
+// GROUP2: define{{.*}} i32 @_Z3barv() #[[ATTRS_BAR:[0-9]+]] {
+// GROUP2: define{{.*}} i32 @_Z4yarrv() #[[ATTRS_FOO]] {
+// GROUP2: define{{.*}} i32 @_Z6alwaysv() #[[ATTRS_ALWAYS:[0-9]+]] {
+// GROUP2: define{{.*}} i32 @_Z5neverv() #[[ATTRS_NEVER:[0-9]+]] {
+// GROUP2-DAG: attributes #[[ATTRS_FOO]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+// GROUP2-DAG: attributes #[[ATTRS_ALWAYS]] = {{.*}} "function-instrument"="xray-always" {{.*}}
+// GROUP2-DAG: attributes #[[ATTRS_NEVER]] = {{.*}} "function-instrument"="xray-never" {{.*}}
Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1130,6 +1130,20 @@
   getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
   Opts.XRayIgnoreLoops = Args.hasArg(OPT_fxray_ignore_loops);
   Opts.XRayOmitFunctionIndex = Args.hasArg(OPT_fno_xray_function_index);
+  Opts.XRayTotalFunctionGroups =
+  getLastArgIntValue(Args, OPT_fxray_function_groups, 1, Diags);
+  if (Opts.XRayTotalFunctionGroups < 1) {
+const Arg *A = Args.getLastArg(OPT_fxray_function_groups);
+Diags.Report(diag::err_drv_invalid_value)
+<< A->getAsString(Args) << A->getValue();
+  }
+  Opts.XRaySelectedFunctionGroup =
+  getLastArgIntValue(Args, OPT_fxray_selected_function_group, 0, Diags);
+  if (Opts.XRaySelectedFunctionGroup >= Opts.XRayTotalFunctionGroups) {
+const Arg *A = Args.getLastArg(OPT_fxray_selected_function_group);
+Diags.Report(diag::err_drv_invalid_value)
+<< A->getAsString(Args) << A->getValue();
+  }
 
   auto XRayInstrBundles =
   Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
Index: clang/lib/Driver/XRayArgs.cpp
===
--- clang/lib/Driver/XRayArgs.cpp
+++ clang/lib/Driver/XRayArgs.cpp
@@ -186,6 

[PATCH] D87953: [xray] Function coverage groups

2020-09-21 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque added a comment.

In D87953#2284071 , @MaskRay wrote:

> How large the overhead is? This is somewhat surprising to me.

It is the binary size overhead, not the runtime overhead, that we are limited 
on (when deployed on Android).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87953

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


[PATCH] D87953: [xray] Function coverage groups

2020-09-21 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque updated this revision to Diff 293278.
ianlevesque added a comment.

Address code review feedback


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87953

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/include/clang/Driver/XRayArgs.h
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/Driver/XRayArgs.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/xray-function-groups.cpp

Index: clang/test/CodeGen/xray-function-groups.cpp
===
--- /dev/null
+++ clang/test/CodeGen/xray-function-groups.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -fxray-instrument -fxray-instruction-threshold=1 -fxray-function-groups=3 -fxray-selected-function-group=0 \
+// RUN:-emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck --check-prefix=GROUP0 %s
+
+// RUN: %clang_cc1 -fxray-instrument -fxray-instruction-threshold=1 -fxray-function-groups=3 -fxray-selected-function-group=1 \
+// RUN:-emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck --check-prefix=GROUP1 %s
+
+// RUN: %clang_cc1 -fxray-instrument -fxray-instruction-threshold=1 -fxray-function-groups=3 -fxray-selected-function-group=2 \
+// RUN:-emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck --check-prefix=GROUP2 %s
+
+int foo() { // part of group 0
+  return 1;
+}
+
+int bar() { // part of group 2
+  return 1;
+}
+
+int yarr() { // part of group 1
+  return 1;
+}
+
+[[clang::xray_always_instrument]] int always() { // part of group 0
+  return 1;
+}
+
+[[clang::xray_never_instrument]] int never() { // part of group 1
+  return 1;
+}
+
+// GROUP0: define{{.*}} i32 @_Z3foov() #[[ATTRS_FOO:[0-9]+]] {
+// GROUP0: define{{.*}} i32 @_Z3barv() #[[ATTRS_BAR:[0-9]+]] {
+// GROUP0: define{{.*}} i32 @_Z4yarrv() #[[ATTRS_BAR]] {
+// GROUP0: define{{.*}} i32 @_Z6alwaysv() #[[ATTRS_ALWAYS:[0-9]+]] {
+// GROUP0: define{{.*}} i32 @_Z5neverv() #[[ATTRS_NEVER:[0-9]+]] {
+// GROUP0-DAG: attributes #[[ATTRS_BAR]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+// GROUP0-DAG: attributes #[[ATTRS_ALWAYS]] = {{.*}} "function-instrument"="xray-always" {{.*}}
+// GROUP0-DAG: attributes #[[ATTRS_NEVER]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+
+// GROUP1: define{{.*}} i32 @_Z3foov() #[[ATTRS_FOO:[0-9]+]] {
+// GROUP1: define{{.*}} i32 @_Z3barv() #[[ATTRS_FOO]] {
+// GROUP1: define{{.*}} i32 @_Z4yarrv() #[[ATTRS_YARR:[0-9]+]] {
+// GROUP1: define{{.*}} i32 @_Z6alwaysv() #[[ATTRS_ALWAYS:[0-9]+]] {
+// GROUP1: define{{.*}} i32 @_Z5neverv() #[[ATTRS_NEVER:[0-9]+]] {
+// GROUP1-DAG: attributes #[[ATTRS_FOO]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+// GROUP1-DAG: attributes #[[ATTRS_ALWAYS]] = {{.*}} "function-instrument"="xray-always" {{.*}}
+// GROUP1-DAG: attributes #[[ATTRS_NEVER]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+
+// GROUP2: define{{.*}} i32 @_Z3foov() #[[ATTRS_FOO:[0-9]+]] {
+// GROUP2: define{{.*}} i32 @_Z3barv() #[[ATTRS_BAR:[0-9]+]] {
+// GROUP2: define{{.*}} i32 @_Z4yarrv() #[[ATTRS_FOO]] {
+// GROUP2: define{{.*}} i32 @_Z6alwaysv() #[[ATTRS_ALWAYS:[0-9]+]] {
+// GROUP2: define{{.*}} i32 @_Z5neverv() #[[ATTRS_NEVER:[0-9]+]] {
+// GROUP2-DAG: attributes #[[ATTRS_FOO]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+// GROUP2-DAG: attributes #[[ATTRS_ALWAYS]] = {{.*}} "function-instrument"="xray-always" {{.*}}
+// GROUP2-DAG: attributes #[[ATTRS_NEVER]] = {{.*}} "function-instrument"="xray-never" {{.*}}
Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1130,6 +1130,20 @@
   getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
   Opts.XRayIgnoreLoops = Args.hasArg(OPT_fxray_ignore_loops);
   Opts.XRayOmitFunctionIndex = Args.hasArg(OPT_fno_xray_function_index);
+  Opts.XRayTotalFunctionGroups =
+  getLastArgIntValue(Args, OPT_fxray_function_groups, 1, Diags);
+  if (Opts.XRayTotalFunctionGroups < 1) {
+const Arg *A = Args.getLastArg(OPT_fxray_function_groups);
+Diags.Report(diag::err_drv_invalid_value)
+<< A->getAsString(Args) << A->getValue();
+  }
+  Opts.XRaySelectedFunctionGroup =
+  getLastArgIntValue(Args, OPT_fxray_selected_function_group, 0, Diags);
+  if (Opts.XRaySelectedFunctionGroup >= Opts.XRayTotalFunctionGroups) {
+const Arg *A = Args.getLastArg(OPT_fxray_selected_function_group);
+Diags.Report(diag::err_drv_invalid_value)
+<< A->getAsString(Args) << A->getValue();
+  }
 
   auto XRayInstrBundles =
   Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
Index: clang/lib/Driver/XRayArgs.cpp
===
--- clang/lib/Driver/XRayArgs.cpp
+++ 

[PATCH] D87953: [xray] Function coverage groups

2020-09-21 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque marked 7 inline comments as done.
ianlevesque added inline comments.



Comment at: clang/lib/CodeGen/CodeGenFunction.cpp:814
+auto FuncGroups = CGM.getCodeGenOpts().XRayTotalFunctionGroups;
+if (FuncGroups > 1) {
+  auto FuncName = ArrayRef(CurFn->getName().bytes_begin(),

MaskRay wrote:
> kyulee wrote:
> > MaskRay wrote:
> > > For one group, the branch is skipped, which does not seem correct
> > Should we check or assert `XRaySelectedFunctionGroups > 0` && 
> > `XRaySelectedFunctionGroup < XRaySelectedFunctionGroups` or the former at 
> > minimum?
> Such checks are usually done in Driver. In CodeGen, as long as it doesn't 
> crash, there is no need imposing stricter checks.
If there is only 1 group (the default value), then all functions that would be 
otherwise instrumented are. So there should be no need to do anything.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87953

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


[PATCH] D87953: [xray] Function coverage groups

2020-09-19 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque added inline comments.



Comment at: clang/lib/CodeGen/CodeGenFunction.cpp:817
+CurFn->getName().bytes_end());
+  auto Group = crc32(FuncName) % FuncGroups;
+  if (Group != CGM.getCodeGenOpts().XRaySelectedFunctionGroup &&

dberris wrote:
> I'm a little concerned that this is randomly determined. Could we think about 
> using a function attribute instead that opts functions into groups by name? 
> Or is the intent to have "sampling" in the coverage information instead of 
> full coverage?
The intention is to have something deterministic across builds but yeah 
sampled-ish across the entire codebase.  By iterating over the groups with 
different builds we are hoping to cover every function eventually.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D87953

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


[PATCH] D87953: [xray] Function coverage groups

2020-09-18 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque created this revision.
ianlevesque added reviewers: dberris, MaskRay, kyulee.
Herald added subscribers: cfe-commits, dang.
Herald added a project: clang.
ianlevesque requested review of this revision.

Add the ability to selectively instrument a subset of functions by dividing the 
functions into N logical groups and then selecting a group to cover. By 
selecting different groups over time you could cover the entire application 
incrementally with lower overhead than instrumenting the entire application at 
once.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D87953

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/include/clang/Driver/XRayArgs.h
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/Driver/XRayArgs.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/xray-function-groups.cpp

Index: clang/test/CodeGen/xray-function-groups.cpp
===
--- /dev/null
+++ clang/test/CodeGen/xray-function-groups.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -fxray-instrument -fxray-instruction-threshold=1 \
+// RUN:-fxray-function-groups=3 \
+// RUN:-fxray-selected-function-group=0 \
+// RUN:-x c++ -std=c++11 -emit-llvm -o - %s \
+// RUN:-triple x86_64-unknown-linux-gnu | FileCheck --check-prefix=GROUP0 %s
+
+// RUN: %clang_cc1 -fxray-instrument -fxray-instruction-threshold=1 \
+// RUN:-fxray-function-groups=3 \
+// RUN:-fxray-selected-function-group=1 \
+// RUN:-x c++ -std=c++11 -emit-llvm -o - %s \
+// RUN:-triple x86_64-unknown-linux-gnu | FileCheck --check-prefix=GROUP1 %s
+
+// RUN: %clang_cc1 -fxray-instrument -fxray-instruction-threshold=1 \
+// RUN:-fxray-function-groups=3 \
+// RUN:-fxray-selected-function-group=2 \
+// RUN:-x c++ -std=c++11 -emit-llvm -o - %s \
+// RUN:-triple x86_64-unknown-linux-gnu | FileCheck --check-prefix=GROUP2 %s
+
+int foo() { // part of group 0
+  return 1;
+}
+
+int bar() { // part of group 2
+  return 1;
+}
+
+int yarr() { // part of group 1
+  return 1;
+}
+
+[[clang::xray_always_instrument]] int always() { // part of group 0
+  return 1;
+}
+
+[[clang::xray_never_instrument]] int never() { // part of group 1
+  return 1;
+}
+
+// GROUP0: define{{.*}} i32 @_Z3foov() #[[ATTRS_FOO:[0-9]+]] {
+// GROUP0: define{{.*}} i32 @_Z3barv() #[[ATTRS_BAR:[0-9]+]] {
+// GROUP0: define{{.*}} i32 @_Z4yarrv() #[[ATTRS_BAR]] {
+// GROUP0: define{{.*}} i32 @_Z6alwaysv() #[[ATTRS_ALWAYS:[0-9]+]] {
+// GROUP0: define{{.*}} i32 @_Z5neverv() #[[ATTRS_NEVER:[0-9]+]] {
+// GROUP0-DAG: attributes #[[ATTRS_BAR]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+// GROUP0-DAG: attributes #[[ATTRS_ALWAYS]] = {{.*}} "function-instrument"="xray-always" {{.*}}
+// GROUP0-DAG: attributes #[[ATTRS_NEVER]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+
+// GROUP1: define{{.*}} i32 @_Z3foov() #[[ATTRS_FOO:[0-9]+]] {
+// GROUP1: define{{.*}} i32 @_Z3barv() #[[ATTRS_FOO]] {
+// GROUP1: define{{.*}} i32 @_Z4yarrv() #[[ATTRS_YARR:[0-9]+]] {
+// GROUP1: define{{.*}} i32 @_Z6alwaysv() #[[ATTRS_ALWAYS:[0-9]+]] {
+// GROUP1: define{{.*}} i32 @_Z5neverv() #[[ATTRS_NEVER:[0-9]+]] {
+// GROUP1-DAG: attributes #[[ATTRS_FOO]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+// GROUP1-DAG: attributes #[[ATTRS_ALWAYS]] = {{.*}} "function-instrument"="xray-always" {{.*}}
+// GROUP1-DAG: attributes #[[ATTRS_NEVER]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+
+// GROUP2: define{{.*}} i32 @_Z3foov() #[[ATTRS_FOO:[0-9]+]] {
+// GROUP2: define{{.*}} i32 @_Z3barv() #[[ATTRS_BAR:[0-9]+]] {
+// GROUP2: define{{.*}} i32 @_Z4yarrv() #[[ATTRS_FOO]] {
+// GROUP2: define{{.*}} i32 @_Z6alwaysv() #[[ATTRS_ALWAYS:[0-9]+]] {
+// GROUP2: define{{.*}} i32 @_Z5neverv() #[[ATTRS_NEVER:[0-9]+]] {
+// GROUP2-DAG: attributes #[[ATTRS_FOO]] = {{.*}} "function-instrument"="xray-never" {{.*}}
+// GROUP2-DAG: attributes #[[ATTRS_ALWAYS]] = {{.*}} "function-instrument"="xray-always" {{.*}}
+// GROUP2-DAG: attributes #[[ATTRS_NEVER]] = {{.*}} "function-instrument"="xray-never" {{.*}}
Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1130,6 +1130,20 @@
   getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
   Opts.XRayIgnoreLoops = Args.hasArg(OPT_fxray_ignore_loops);
   Opts.XRayOmitFunctionIndex = Args.hasArg(OPT_fno_xray_function_index);
+  Opts.XRayTotalFunctionGroups =
+  getLastArgIntValue(Args, OPT_fxray_function_groups, 1, Diags);
+  if (Opts.XRayTotalFunctionGroups < 1) {
+const Arg *A = Args.getLastArg(OPT_fxray_function_groups);
+Diags.Report(diag::err_drv_invalid_value)
+<< A->getAsString(Args) << A->getValue();
+  }
+  

[PATCH] D81995: [xray] Option to omit the function index

2020-06-17 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque marked 2 inline comments as done.
ianlevesque added inline comments.



Comment at: clang/include/clang/Basic/CodeGenOptions.def:114
+///< Set with -fno-xray-function-index to omit the index section.
+CODEGENOPT(XRayOmitFunctionIndex , 1, 0)
+

MaskRay wrote:
> ianlevesque wrote:
> > MaskRay wrote:
> > > ianlevesque wrote:
> > > > MaskRay wrote:
> > > > > Nit: a variable name with a positive meaning may be easier to 
> > > > > understand.
> > > > I had the entire patch that way at first, making the index something 
> > > > you would enable (defaulting to true) but it was much worse.
> > > The variable naming should be easily inferrable from the option name. The 
> > > option does not say `omit`. Doesn't `XRayFunctionIndex` work? How can it 
> > > be much worse?
> > Sure just changing the variable name is fine of course. I meant it was 
> > worse (many tests needing to be changed) when I tried to make the index 
> > opt-in not opt-out and just have the Driver set it by default.
> I mean you can use a variable named `XRayFunctionIndex` which defaults to 
> true. This is similar to an `XRayOmitFunctionIndex` which defaults to false.
Yep, saw your change - works for me. Thanks!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D81995



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


[PATCH] D81995: [xray] Option to omit the function index

2020-06-17 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque marked 4 inline comments as done.
ianlevesque added inline comments.



Comment at: clang/include/clang/Basic/CodeGenOptions.def:114
+///< Set with -fno-xray-function-index to omit the index section.
+CODEGENOPT(XRayOmitFunctionIndex , 1, 0)
+

MaskRay wrote:
> ianlevesque wrote:
> > MaskRay wrote:
> > > Nit: a variable name with a positive meaning may be easier to understand.
> > I had the entire patch that way at first, making the index something you 
> > would enable (defaulting to true) but it was much worse.
> The variable naming should be easily inferrable from the option name. The 
> option does not say `omit`. Doesn't `XRayFunctionIndex` work? How can it be 
> much worse?
Sure just changing the variable name is fine of course. I meant it was worse 
(many tests needing to be changed) when I tried to make the index opt-in not 
opt-out and just have the Driver set it by default.



Comment at: clang/include/clang/Driver/Options.td:1284
 
+def fxray_function_index : Flag<["-"], "fxray-function-index">,
+  Group, Flags<[CC1Option]>;

MaskRay wrote:
> This should use OptOutFFlag. I fixed it.
Thanks for the fixes!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D81995



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


[PATCH] D81995: [xray] Option to omit the function index

2020-06-17 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque marked 3 inline comments as done.
ianlevesque added inline comments.



Comment at: clang/include/clang/Basic/CodeGenOptions.def:114
+///< Set with -fno-xray-function-index to omit the index section.
+CODEGENOPT(XRayOmitFunctionIndex , 1, 0)
+

MaskRay wrote:
> Nit: a variable name with a positive meaning may be easier to understand.
I had the entire patch that way at first, making the index something you would 
enable (defaulting to true) but it was much worse.



Comment at: clang/test/Driver/XRay/xray-function-index-flags.cpp:20
+//
+// REQUIRES: x86_64 || x86_64h

MaskRay wrote:
> I know some tests may be inconsistent but the prevailing style is to place 
> `REQUIRES:` at the top.
I already committed this, but I can do a quick follow up for these nits.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D81995



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


[PATCH] D81995: [xray] Option to omit the function index

2020-06-17 Thread Ian Levesque via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG7c7c8e0da4e0: [xray] Option to omit the function index 
(authored by ianlevesque).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D81995

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/include/clang/Driver/XRayArgs.h
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/XRayArgs.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/Driver/XRay/xray-function-index-flags.cpp
  compiler-rt/lib/xray/xray_init.cpp
  compiler-rt/lib/xray/xray_interface.cpp
  compiler-rt/test/xray/TestCases/Posix/coverage-sample.cpp
  compiler-rt/test/xray/TestCases/Posix/func-id-utils.cpp
  compiler-rt/test/xray/TestCases/Posix/patching-unpatching.cpp
  llvm/include/llvm/CodeGen/CommandFlags.h
  llvm/include/llvm/Target/TargetOptions.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/CodeGen/CommandFlags.cpp
  llvm/test/CodeGen/AArch64/xray-omit-function-index.ll

Index: llvm/test/CodeGen/AArch64/xray-omit-function-index.ll
===
--- /dev/null
+++ llvm/test/CodeGen/AArch64/xray-omit-function-index.ll
@@ -0,0 +1,33 @@
+; RUN: llc -filetype=asm -no-xray-index -o - -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
+
+define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" {
+; CHECK-LABEL: Lxray_sled_0:
+; CHECK-NEXT:  b  #32
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-LABEL: Ltmp0:
+  ret i32 0
+; CHECK-LABEL: Lxray_sled_1:
+; CHECK-NEXT:  b  #32
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-LABEL: Ltmp1:
+; CHECK-NEXT:  ret
+}
+; CHECK-LABEL: xray_instr_map
+; CHECK-LABEL: Lxray_sleds_start0
+; CHECK:   .xword .Lxray_sled_0
+; CHECK:   .xword .Lxray_sled_1
+; CHECK-LABEL: Lxray_sleds_end0
+
+; CHECK-NOT: xray_fn_idx
\ No newline at end of file
Index: llvm/lib/CodeGen/CommandFlags.cpp
===
--- llvm/lib/CodeGen/CommandFlags.cpp
+++ llvm/lib/CodeGen/CommandFlags.cpp
@@ -86,6 +86,7 @@
 CGOPT(bool, EmitCallSiteInfo)
 CGOPT(bool, EnableDebugEntryValues)
 CGOPT(bool, ForceDwarfFrameSection)
+CGOPT(bool, XRayOmitFunctionIndex)
 
 codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
 #define CGBINDOPT(NAME)\
@@ -404,6 +405,11 @@
   cl::desc("Always emit a debug frame section."), cl::init(false));
   CGBINDOPT(ForceDwarfFrameSection);
 
+  static cl::opt XRayOmitFunctionIndex(
+  "no-xray-index", cl::desc("Don't emit xray_fn_idx section"),
+  cl::init(false));
+  CGBINDOPT(XRayOmitFunctionIndex);
+
 #undef CGBINDOPT
 
   mc::RegisterMCTargetOptionsFlags();
@@ -470,6 +476,7 @@
   Options.EmitCallSiteInfo = getEmitCallSiteInfo();
   Options.EnableDebugEntryValues = getEnableDebugEntryValues();
   Options.ForceDwarfFrameSection = getForceDwarfFrameSection();
+  Options.XRayOmitFunctionIndex = getXRayOmitFunctionIndex();
 
   Options.MCOptions = mc::InitMCTargetOptionsFromFlags();
 
Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
===
--- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -3235,14 +3235,17 @@
 InstMap = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS,
Flags, 0, GroupName,
MCSection::NonUniqueID, LinkedToSym);
-FnSledIndex = OutContext.getELFSection("xray_fn_idx", ELF::SHT_PROGBITS,
-   Flags | ELF::SHF_WRITE, 0, GroupName,
-   MCSection::NonUniqueID, LinkedToSym);
+
+if (!TM.Options.XRayOmitFunctionIndex)
+  FnSledIndex = OutContext.getELFSection(
+  "xray_fn_idx", ELF::SHT_PROGBITS, Flags | ELF::SHF_WRITE, 0,
+  GroupName, MCSection::NonUniqueID, LinkedToSym);
   } else if (MF->getSubtarget().getTargetTriple().isOSBinFormatMachO()) {
 InstMap = OutContext.getMachOSection("__DATA", "xray_instr_map", 0,
  SectionKind::getReadOnlyWithRel());
-FnSledIndex = OutContext.getMachOSection("__DATA", "xray_fn_idx", 0,
- SectionKind::getReadOnlyWithRel());
+if (!TM.Options.XRayOmitFunctionIndex)
+  FnSledIndex = OutContext.getMachOSection(
+  "__DATA", "xray_fn_idx", 0, SectionKind::getReadOnlyWithRel());
   } else {
 llvm_unreachable("Unsupported target");
   }
@@ -3285,11 +3288,13 @@
   // that bound the instrumentation map as the range for a 

[PATCH] D81995: [xray] Option to omit the function index

2020-06-17 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque created this revision.
ianlevesque added reviewers: dberris, MaskRay, johnislarry.
Herald added subscribers: llvm-commits, Sanitizers, cfe-commits, arphaman, 
hiraditya.
Herald added projects: clang, Sanitizers, LLVM.

Add a flag to omit the xray_fn_idx to cut size overhead and relocations
roughly in half at the cost of reduced performance for single function
patching.  Minor additions to compiler-rt support per-function patching
without the index.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D81995

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/include/clang/Driver/XRayArgs.h
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/XRayArgs.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/Driver/XRay/xray-function-index-flags.cpp
  compiler-rt/lib/xray/xray_init.cpp
  compiler-rt/lib/xray/xray_interface.cpp
  compiler-rt/test/xray/TestCases/Posix/coverage-sample.cpp
  compiler-rt/test/xray/TestCases/Posix/func-id-utils.cpp
  compiler-rt/test/xray/TestCases/Posix/patching-unpatching.cpp
  llvm/include/llvm/CodeGen/CommandFlags.h
  llvm/include/llvm/Target/TargetOptions.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/CodeGen/CommandFlags.cpp
  llvm/test/CodeGen/AArch64/xray-omit-function-index.ll

Index: llvm/test/CodeGen/AArch64/xray-omit-function-index.ll
===
--- /dev/null
+++ llvm/test/CodeGen/AArch64/xray-omit-function-index.ll
@@ -0,0 +1,33 @@
+; RUN: llc -filetype=asm -no-xray-index -o - -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
+
+define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" {
+; CHECK-LABEL: Lxray_sled_0:
+; CHECK-NEXT:  b  #32
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-LABEL: Ltmp0:
+  ret i32 0
+; CHECK-LABEL: Lxray_sled_1:
+; CHECK-NEXT:  b  #32
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-LABEL: Ltmp1:
+; CHECK-NEXT:  ret
+}
+; CHECK-LABEL: xray_instr_map
+; CHECK-LABEL: Lxray_sleds_start0
+; CHECK:   .xword .Lxray_sled_0
+; CHECK:   .xword .Lxray_sled_1
+; CHECK-LABEL: Lxray_sleds_end0
+
+; CHECK-NOT: xray_fn_idx
\ No newline at end of file
Index: llvm/lib/CodeGen/CommandFlags.cpp
===
--- llvm/lib/CodeGen/CommandFlags.cpp
+++ llvm/lib/CodeGen/CommandFlags.cpp
@@ -86,6 +86,7 @@
 CGOPT(bool, EmitCallSiteInfo)
 CGOPT(bool, EnableDebugEntryValues)
 CGOPT(bool, ForceDwarfFrameSection)
+CGOPT(bool, XRayOmitFunctionIndex)
 
 codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
 #define CGBINDOPT(NAME)\
@@ -404,6 +405,11 @@
   cl::desc("Always emit a debug frame section."), cl::init(false));
   CGBINDOPT(ForceDwarfFrameSection);
 
+  static cl::opt XRayOmitFunctionIndex(
+  "no-xray-index", cl::desc("Don't emit xray_fn_idx section"),
+  cl::init(false));
+  CGBINDOPT(XRayOmitFunctionIndex);
+
 #undef CGBINDOPT
 
   mc::RegisterMCTargetOptionsFlags();
@@ -470,6 +476,7 @@
   Options.EmitCallSiteInfo = getEmitCallSiteInfo();
   Options.EnableDebugEntryValues = getEnableDebugEntryValues();
   Options.ForceDwarfFrameSection = getForceDwarfFrameSection();
+  Options.XRayOmitFunctionIndex = getXRayOmitFunctionIndex();
 
   Options.MCOptions = mc::InitMCTargetOptionsFromFlags();
 
Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
===
--- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -3235,14 +3235,17 @@
 InstMap = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS,
Flags, 0, GroupName,
MCSection::NonUniqueID, LinkedToSym);
-FnSledIndex = OutContext.getELFSection("xray_fn_idx", ELF::SHT_PROGBITS,
-   Flags | ELF::SHF_WRITE, 0, GroupName,
-   MCSection::NonUniqueID, LinkedToSym);
+
+if (!TM.Options.XRayOmitFunctionIndex)
+  FnSledIndex = OutContext.getELFSection(
+  "xray_fn_idx", ELF::SHT_PROGBITS, Flags | ELF::SHF_WRITE, 0,
+  GroupName, MCSection::NonUniqueID, LinkedToSym);
   } else if (MF->getSubtarget().getTargetTriple().isOSBinFormatMachO()) {
 InstMap = OutContext.getMachOSection("__DATA", "xray_instr_map", 0,
  SectionKind::getReadOnlyWithRel());
-FnSledIndex = OutContext.getMachOSection("__DATA", "xray_fn_idx", 0,
- SectionKind::getReadOnlyWithRel());
+if (!TM.Options.XRayOmitFunctionIndex)
+  FnSledIndex = 

[PATCH] D77191: [clang][xray] Add xray attributes to functions without decls too

2020-03-31 Thread Ian Levesque via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGbb3111cbaf7b: [clang][xray] Add xray attributes to functions 
without decls too (authored by ianlevesque).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D77191

Files:
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/test/CodeGen/xray-global-init.cpp

Index: clang/test/CodeGen/xray-global-init.cpp
===
--- /dev/null
+++ clang/test/CodeGen/xray-global-init.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -fxray-instrument -fxray-instruction-threshold=1 %s -o - \
+// RUN:   | FileCheck %s
+
+struct A {
+  A();
+  ~A();
+};
+
+A a;
+
+// Check that the xray-instruction-threshold was applied
+// CHECK: define internal void @_GLOBAL__sub_I_xray_global_init.cpp() [[NUX:#[0-9]+]] section ".text.startup" {
+// CHECK: attributes [[NUX]] = { noinline nounwind {{.*}}"xray-instruction-threshold"="1"{{.*}} }
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -810,55 +810,54 @@
   FD->getBody()->getStmtClass() == Stmt::CoroutineBodyStmtClass)
 SanOpts.Mask &= ~SanitizerKind::Null;
 
-  if (D) {
-// Apply xray attributes to the function (as a string, for now)
-if (const auto *XRayAttr = D->getAttr()) {
-  if (CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
-  XRayInstrKind::FunctionEntry) ||
-  CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
-  XRayInstrKind::FunctionExit)) {
-if (XRayAttr->alwaysXRayInstrument() && ShouldXRayInstrumentFunction())
-  Fn->addFnAttr("function-instrument", "xray-always");
-if (XRayAttr->neverXRayInstrument())
-  Fn->addFnAttr("function-instrument", "xray-never");
-if (const auto *LogArgs = D->getAttr())
-  if (ShouldXRayInstrumentFunction())
-Fn->addFnAttr("xray-log-args",
-  llvm::utostr(LogArgs->getArgumentCount()));
-  }
-} else {
-  if (ShouldXRayInstrumentFunction() && !CGM.imbueXRayAttrs(Fn, Loc))
-Fn->addFnAttr(
-"xray-instruction-threshold",
-llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));
+  // Apply xray attributes to the function (as a string, for now)
+  if (const auto *XRayAttr = D ? D->getAttr() : nullptr) {
+if (CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
+XRayInstrKind::FunctionEntry) ||
+CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
+XRayInstrKind::FunctionExit)) {
+  if (XRayAttr->alwaysXRayInstrument() && ShouldXRayInstrumentFunction())
+Fn->addFnAttr("function-instrument", "xray-always");
+  if (XRayAttr->neverXRayInstrument())
+Fn->addFnAttr("function-instrument", "xray-never");
+  if (const auto *LogArgs = D->getAttr())
+if (ShouldXRayInstrumentFunction())
+  Fn->addFnAttr("xray-log-args",
+llvm::utostr(LogArgs->getArgumentCount()));
 }
+  } else {
+if (ShouldXRayInstrumentFunction() && !CGM.imbueXRayAttrs(Fn, Loc))
+  Fn->addFnAttr(
+  "xray-instruction-threshold",
+  llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));
+  }
 
-if (ShouldXRayInstrumentFunction()) {
-  if (CGM.getCodeGenOpts().XRayIgnoreLoops)
-Fn->addFnAttr("xray-ignore-loops");
+  if (ShouldXRayInstrumentFunction()) {
+if (CGM.getCodeGenOpts().XRayIgnoreLoops)
+  Fn->addFnAttr("xray-ignore-loops");
 
-  if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
-  XRayInstrKind::FunctionExit))
-Fn->addFnAttr("xray-skip-exit");
+if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
+XRayInstrKind::FunctionExit))
+  Fn->addFnAttr("xray-skip-exit");
 
-  if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
-  XRayInstrKind::FunctionEntry))
-Fn->addFnAttr("xray-skip-entry");
-}
+if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
+XRayInstrKind::FunctionEntry))
+  Fn->addFnAttr("xray-skip-entry");
+  }
 
-unsigned Count, Offset;
-if (const auto *Attr = D->getAttr()) {
-  Count = Attr->getCount();
-  Offset = Attr->getOffset();
-} else {
-  Count = CGM.getCodeGenOpts().PatchableFunctionEntryCount;
-  Offset = CGM.getCodeGenOpts().PatchableFunctionEntryOffset;
-}
-if (Count && Offset <= Count) {
-  Fn->addFnAttr("patchable-function-entry", std::to_string(Count - Offset));
-  if (Offset)
-Fn->addFnAttr("patchable-function-prefix", std::to_string(Offset));
-}
+  unsigned Count, Offset;
+  if (const auto *Attr =
+  D ? D->getAttr() : nullptr) {
+Count 

[PATCH] D77191: [clang][xray] Add xray attributes to functions without decls too

2020-03-31 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque created this revision.
ianlevesque added reviewers: dberris, MaskRay, smeenai.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This allows instrumenting things like global initializers


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D77191

Files:
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/test/CodeGen/xray-global-init.cpp

Index: clang/test/CodeGen/xray-global-init.cpp
===
--- /dev/null
+++ clang/test/CodeGen/xray-global-init.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -fxray-instrument -fxray-instruction-threshold=1 %s -o - \
+// RUN:   | FileCheck %s
+
+struct A {
+  A();
+  ~A();
+};
+
+A a;
+
+// Check that the xray-instruction-threshold was applied
+// CHECK: define internal void @_GLOBAL__sub_I_xray_global_init.cpp() [[NUX:#[0-9]+]] section ".text.startup" {
+// CHECK: attributes [[NUX]] = { noinline nounwind {{.*}}"xray-instruction-threshold"="1"{{.*}} }
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -810,55 +810,54 @@
   FD->getBody()->getStmtClass() == Stmt::CoroutineBodyStmtClass)
 SanOpts.Mask &= ~SanitizerKind::Null;
 
-  if (D) {
-// Apply xray attributes to the function (as a string, for now)
-if (const auto *XRayAttr = D->getAttr()) {
-  if (CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
-  XRayInstrKind::FunctionEntry) ||
-  CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
-  XRayInstrKind::FunctionExit)) {
-if (XRayAttr->alwaysXRayInstrument() && ShouldXRayInstrumentFunction())
-  Fn->addFnAttr("function-instrument", "xray-always");
-if (XRayAttr->neverXRayInstrument())
-  Fn->addFnAttr("function-instrument", "xray-never");
-if (const auto *LogArgs = D->getAttr())
-  if (ShouldXRayInstrumentFunction())
-Fn->addFnAttr("xray-log-args",
-  llvm::utostr(LogArgs->getArgumentCount()));
-  }
-} else {
-  if (ShouldXRayInstrumentFunction() && !CGM.imbueXRayAttrs(Fn, Loc))
-Fn->addFnAttr(
-"xray-instruction-threshold",
-llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));
+  // Apply xray attributes to the function (as a string, for now)
+  if (const auto *XRayAttr = D ? D->getAttr() : nullptr) {
+if (CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
+XRayInstrKind::FunctionEntry) ||
+CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
+XRayInstrKind::FunctionExit)) {
+  if (XRayAttr->alwaysXRayInstrument() && ShouldXRayInstrumentFunction())
+Fn->addFnAttr("function-instrument", "xray-always");
+  if (XRayAttr->neverXRayInstrument())
+Fn->addFnAttr("function-instrument", "xray-never");
+  if (const auto *LogArgs = D->getAttr())
+if (ShouldXRayInstrumentFunction())
+  Fn->addFnAttr("xray-log-args",
+llvm::utostr(LogArgs->getArgumentCount()));
 }
+  } else {
+if (ShouldXRayInstrumentFunction() && !CGM.imbueXRayAttrs(Fn, Loc))
+  Fn->addFnAttr(
+  "xray-instruction-threshold",
+  llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));
+  }
 
-if (ShouldXRayInstrumentFunction()) {
-  if (CGM.getCodeGenOpts().XRayIgnoreLoops)
-Fn->addFnAttr("xray-ignore-loops");
+  if (ShouldXRayInstrumentFunction()) {
+if (CGM.getCodeGenOpts().XRayIgnoreLoops)
+  Fn->addFnAttr("xray-ignore-loops");
 
-  if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
-  XRayInstrKind::FunctionExit))
-Fn->addFnAttr("xray-skip-exit");
+if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
+XRayInstrKind::FunctionExit))
+  Fn->addFnAttr("xray-skip-exit");
 
-  if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
-  XRayInstrKind::FunctionEntry))
-Fn->addFnAttr("xray-skip-entry");
-}
+if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
+XRayInstrKind::FunctionEntry))
+  Fn->addFnAttr("xray-skip-entry");
+  }
 
-unsigned Count, Offset;
-if (const auto *Attr = D->getAttr()) {
-  Count = Attr->getCount();
-  Offset = Attr->getOffset();
-} else {
-  Count = CGM.getCodeGenOpts().PatchableFunctionEntryCount;
-  Offset = CGM.getCodeGenOpts().PatchableFunctionEntryOffset;
-}
-if (Count && Offset <= Count) {
-  Fn->addFnAttr("patchable-function-entry", std::to_string(Count - Offset));
-  if (Offset)
-Fn->addFnAttr("patchable-function-prefix", std::to_string(Offset));
-}
+  unsigned Count, Offset;
+  if (const auto *Attr =
+  D ? D->getAttr() : nullptr) {
+Count = Attr->getCount();
+Offset = 

[PATCH] D73842: [xray][clang] Always add xray-skip-entry/exit and xray-ignore-loops attrs

2020-02-11 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque added a comment.

In D73842#1869890 , @smeenai wrote:

> Is it worth adding a test that a function with an explicit xray-instrument 
> attribute also has these other attributes applied?


The existing tests from when the feature was added covered that case well. It 
was the driver passing the flag and the case without the xray-instrument 
attribute that weren't working.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D73842



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


[PATCH] D73842: [xray][clang] Always add xray-skip-entry/exit and xray-ignore-loops attrs

2020-02-11 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque updated this revision to Diff 243981.
ianlevesque added a comment.

Address code review feedback on the tests.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D73842

Files:
  clang/include/clang/Driver/XRayArgs.h
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/Driver/XRayArgs.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/xray-attributes-skip-entry-exit.cpp
  clang/test/CodeGen/xray-ignore-loops.cpp
  clang/test/Driver/XRay/xray-ignore-loops-flags.cpp

Index: clang/test/Driver/XRay/xray-ignore-loops-flags.cpp
===
--- /dev/null
+++ clang/test/Driver/XRay/xray-ignore-loops-flags.cpp
@@ -0,0 +1,10 @@
+// This test ensures that when we invoke the clang compiler, that the -cc1
+// options include the -fxray-ignore-loops flag we provide in the
+// invocation.
+//
+// RUN: %clang -fxray-instrument -fxray-ignore-loops -target x86_64-linux- -### \
+// RUN: -x c++ -std=c++11 -emit-llvm -c -o - %s 2>&1 \
+// RUN: | FileCheck %s
+// CHECK:  -fxray-ignore-loops
+//
+// REQUIRES: x86_64 || x86_64h
Index: clang/test/CodeGen/xray-ignore-loops.cpp
===
--- clang/test/CodeGen/xray-ignore-loops.cpp
+++ clang/test/CodeGen/xray-ignore-loops.cpp
@@ -4,5 +4,5 @@
   return 1;
 }
 
-// CHECK: define i32 @_Z3foov() #[[ATTRS:[0-9]+]] {
+// CHECK: define{{.*}} i32 @_Z3foov() #[[ATTRS:[0-9]+]] {
 // CHECK-DAG: attributes #[[ATTRS]] = {{.*}} "xray-ignore-loops" {{.*}}
Index: clang/test/CodeGen/xray-attributes-skip-entry-exit.cpp
===
--- /dev/null
+++ clang/test/CodeGen/xray-attributes-skip-entry-exit.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fxray-instrument \
+// RUN: -fxray-instrumentation-bundle=function-entry -x c++ \
+// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN: | FileCheck --check-prefixes CHECK,SKIPEXIT %s
+// RUN: %clang_cc1 -fxray-instrument \
+// RUN: -fxray-instrumentation-bundle=function-exit -x c++ \
+// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN: | FileCheck --check-prefixes CHECK,SKIPENTRY %s
+// RUN: %clang_cc1 -fxray-instrument \
+// RUN: -fxray-instrumentation-bundle=function-entry,function-exit -x c++ \
+// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN: | FileCheck --check-prefixes CHECK,NOSKIPENTRY,NOSKIPEXIT %s
+
+// CHECK: define void @_Z13justAFunctionv() #[[ATTR:[0-9]+]] {
+void justAFunction() {
+}
+
+// SKIPENTRY: attributes #[[ATTR]] = {{.*}} "xray-skip-entry" {{.*}}
+// SKIPEXIT: attributes #[[ATTR]] = {{.*}} "xray-skip-exit" {{.*}}
+
+// NOSKIPENTRY-NOT: attributes #[[ATTR]] = {{.*}} "xray-skip-entry" {{.*}}
+// NOSKIPEXIT-NOT: attributes #[[ATTR]] = {{.*}} "xray-skip-exit" {{.*}}
Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1099,8 +1099,7 @@
   Args.hasArg(OPT_fxray_always_emit_typedevents);
   Opts.XRayInstructionThreshold =
   getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
-  Opts.XRayIgnoreLoops =
-  Args.hasArg(OPT_fxray_ignore_loops, OPT_fno_xray_ignore_loops, false);
+  Opts.XRayIgnoreLoops = Args.hasArg(OPT_fxray_ignore_loops);
 
   auto XRayInstrBundles =
   Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
Index: clang/lib/Driver/XRayArgs.cpp
===
--- clang/lib/Driver/XRayArgs.cpp
+++ clang/lib/Driver/XRayArgs.cpp
@@ -101,6 +101,10 @@
 options::OPT_fnoxray_link_deps, true))
 XRayRT = false;
 
+  if (Args.hasFlag(options::OPT_fxray_ignore_loops,
+   options::OPT_fno_xray_ignore_loops, false))
+XRayIgnoreLoops = true;
+
   auto Bundles =
   Args.getAllArgValues(options::OPT_fxray_instrumentation_bundle);
   if (Bundles.empty())
@@ -197,6 +201,9 @@
   if (XRayAlwaysEmitTypedEvents)
 CmdArgs.push_back("-fxray-always-emit-typedevents");
 
+  if (XRayIgnoreLoops)
+CmdArgs.push_back("-fxray-ignore-loops");
+
   CmdArgs.push_back(Args.MakeArgString(Twine(XRayInstructionThresholdOption) +
Twine(InstructionThreshold)));
 
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -814,23 +814,25 @@
   if (ShouldXRayInstrumentFunction())
 Fn->addFnAttr("xray-log-args",
   llvm::utostr(LogArgs->getArgumentCount()));
-if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
-

[PATCH] D73842: [xray][clang] Always add xray-skip-entry/exit and xray-ignore-loops attrs

2020-02-10 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque updated this revision to Diff 243749.
ianlevesque added a comment.

Now with 100% more tests.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D73842

Files:
  clang/include/clang/Driver/XRayArgs.h
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/Driver/XRayArgs.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/xray-attributes-skip-entry-exit.cpp
  clang/test/CodeGen/xray-ignore-loops.cpp
  clang/test/Driver/XRay/xray-ignore-loops-flags.cpp

Index: clang/test/Driver/XRay/xray-ignore-loops-flags.cpp
===
--- /dev/null
+++ clang/test/Driver/XRay/xray-ignore-loops-flags.cpp
@@ -0,0 +1,10 @@
+// This test ensures that when we invoke the clang compiler, that the -cc1
+// options include the -fxray-ignore-loops flag we provide in the
+// invocation.
+//
+// RUN: %clang -fxray-instrument -fxray-ignore-loops -target x86_64-linux- -### \
+// RUN: -x c++ -std=c++11 -emit-llvm -c -o - %s 2>&1 \
+// RUN: | FileCheck %s
+// CHECK:  -fxray-ignore-loops
+//
+// REQUIRES: x86_64 || x86_64h
\ No newline at end of file
Index: clang/test/CodeGen/xray-ignore-loops.cpp
===
--- clang/test/CodeGen/xray-ignore-loops.cpp
+++ clang/test/CodeGen/xray-ignore-loops.cpp
@@ -1,8 +1,9 @@
 // RUN: %clang_cc1 -fxray-instrument -fxray-ignore-loops -x c++ -std=c++11 -emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck %s
+// RUN: %clang -fxray-instrument -fxray-ignore-loops -x c++ -std=c++11 -S -emit-llvm -o - %s -target x86_64-unknown-linux-gnu | FileCheck %s
 
 int foo() {
   return 1;
 }
 
-// CHECK: define i32 @_Z3foov() #[[ATTRS:[0-9]+]] {
+// CHECK: define{{.*}} i32 @_Z3foov() #[[ATTRS:[0-9]+]] {
 // CHECK-DAG: attributes #[[ATTRS]] = {{.*}} "xray-ignore-loops" {{.*}}
Index: clang/test/CodeGen/xray-attributes-skip-entry-exit.cpp
===
--- /dev/null
+++ clang/test/CodeGen/xray-attributes-skip-entry-exit.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fxray-instrument \
+// RUN: -fxray-instrumentation-bundle=function-entry -x c++ \
+// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN: | FileCheck --check-prefixes CHECK,NOCUSTOM,NOTYPED,SKIPEXIT %s
+// RUN: %clang_cc1 -fxray-instrument \
+// RUN: -fxray-instrumentation-bundle=function-exit -x c++ \
+// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN: | FileCheck --check-prefixes CHECK,NOCUSTOM,NOTYPED,SKIPENTRY %s
+// RUN: %clang_cc1 -fxray-instrument \
+// RUN: -fxray-instrumentation-bundle=function-entry,function-exit -x c++ \
+// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN: | FileCheck --check-prefixes CHECK,FUNCTION,NOCUSTOM,NOTYPED %s
+
+// CHECK: define void @_Z13justAFunctionv() #[[ATTR:[0-9]+]] {
+void justAFunction() {
+}
+
+// SKIPENTRY: attributes #[[ATTR]] = {{.*}} "xray-skip-entry" {{.*}}
+// SKIPEXIT: attributes #[[ATTR]] = {{.*}} "xray-skip-exit" {{.*}}
Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1099,8 +1099,7 @@
   Args.hasArg(OPT_fxray_always_emit_typedevents);
   Opts.XRayInstructionThreshold =
   getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
-  Opts.XRayIgnoreLoops =
-  Args.hasArg(OPT_fxray_ignore_loops, OPT_fno_xray_ignore_loops, false);
+  Opts.XRayIgnoreLoops = Args.hasArg(OPT_fxray_ignore_loops);
 
   auto XRayInstrBundles =
   Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
Index: clang/lib/Driver/XRayArgs.cpp
===
--- clang/lib/Driver/XRayArgs.cpp
+++ clang/lib/Driver/XRayArgs.cpp
@@ -101,6 +101,10 @@
 options::OPT_fnoxray_link_deps, true))
 XRayRT = false;
 
+  if (Args.hasFlag(options::OPT_fxray_ignore_loops,
+   options::OPT_fno_xray_ignore_loops, false))
+XRayIgnoreLoops = true;
+
   auto Bundles =
   Args.getAllArgValues(options::OPT_fxray_instrumentation_bundle);
   if (Bundles.empty())
@@ -197,6 +201,9 @@
   if (XRayAlwaysEmitTypedEvents)
 CmdArgs.push_back("-fxray-always-emit-typedevents");
 
+  if (XRayIgnoreLoops)
+CmdArgs.push_back("-fxray-ignore-loops");
+
   CmdArgs.push_back(Args.MakeArgString(Twine(XRayInstructionThresholdOption) +
Twine(InstructionThreshold)));
 
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -814,23 +814,25 @@
   if (ShouldXRayInstrumentFunction())
 

[PATCH] D73842: [xray][clang] Always add xray-skip-entry/exit and xray-ignore-loops attrs

2020-02-06 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque added a comment.

@hiraditya or @smeenai can i get a merge?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D73842



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


[PATCH] D73842: [xray][clang] Always add xray-skip-entry/exit and xray-ignore-loops attrs

2020-02-05 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque updated this revision to Diff 242800.
ianlevesque added a comment.

Address code review nits


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D73842

Files:
  clang/include/clang/Driver/XRayArgs.h
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/Driver/XRayArgs.cpp
  clang/lib/Frontend/CompilerInvocation.cpp


Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1099,8 +1099,7 @@
   Args.hasArg(OPT_fxray_always_emit_typedevents);
   Opts.XRayInstructionThreshold =
   getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
-  Opts.XRayIgnoreLoops =
-  Args.hasArg(OPT_fxray_ignore_loops, OPT_fno_xray_ignore_loops, false);
+  Opts.XRayIgnoreLoops = Args.hasArg(OPT_fxray_ignore_loops);
 
   auto XRayInstrBundles =
   Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
Index: clang/lib/Driver/XRayArgs.cpp
===
--- clang/lib/Driver/XRayArgs.cpp
+++ clang/lib/Driver/XRayArgs.cpp
@@ -101,6 +101,10 @@
 options::OPT_fnoxray_link_deps, true))
 XRayRT = false;
 
+  if (Args.hasFlag(options::OPT_fxray_ignore_loops,
+   options::OPT_fno_xray_ignore_loops, false))
+XRayIgnoreLoops = true;
+
   auto Bundles =
   Args.getAllArgValues(options::OPT_fxray_instrumentation_bundle);
   if (Bundles.empty())
@@ -197,6 +201,9 @@
   if (XRayAlwaysEmitTypedEvents)
 CmdArgs.push_back("-fxray-always-emit-typedevents");
 
+  if (XRayIgnoreLoops)
+CmdArgs.push_back("-fxray-ignore-loops");
+
   CmdArgs.push_back(Args.MakeArgString(Twine(XRayInstructionThresholdOption) +
Twine(InstructionThreshold)));
 
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -814,23 +814,25 @@
   if (ShouldXRayInstrumentFunction())
 Fn->addFnAttr("xray-log-args",
   llvm::utostr(LogArgs->getArgumentCount()));
-if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
-XRayInstrKind::FunctionExit)) {
-  Fn->addFnAttr("xray-skip-exit");
-}
-if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
-XRayInstrKind::FunctionEntry)) {
-  Fn->addFnAttr("xray-skip-entry");
-}
   }
 } else {
   if (ShouldXRayInstrumentFunction() && !CGM.imbueXRayAttrs(Fn, Loc))
 Fn->addFnAttr(
 "xray-instruction-threshold",
 llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));
-  if (CGM.getCodeGenOpts().XRayIgnoreLoops) {
+}
+
+if (ShouldXRayInstrumentFunction()) {
+  if (CGM.getCodeGenOpts().XRayIgnoreLoops)
 Fn->addFnAttr("xray-ignore-loops");
-  }
+
+  if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
+  XRayInstrKind::FunctionExit))
+Fn->addFnAttr("xray-skip-exit");
+
+  if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
+  XRayInstrKind::FunctionEntry))
+Fn->addFnAttr("xray-skip-entry");
 }
 
 unsigned Count, Offset;
Index: clang/include/clang/Driver/XRayArgs.h
===
--- clang/include/clang/Driver/XRayArgs.h
+++ clang/include/clang/Driver/XRayArgs.h
@@ -30,6 +30,7 @@
   bool XRayAlwaysEmitCustomEvents = false;
   bool XRayAlwaysEmitTypedEvents = false;
   bool XRayRT = true;
+  bool XRayIgnoreLoops = false;
 
 public:
   /// Parses the XRay arguments from an argument list.


Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1099,8 +1099,7 @@
   Args.hasArg(OPT_fxray_always_emit_typedevents);
   Opts.XRayInstructionThreshold =
   getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
-  Opts.XRayIgnoreLoops =
-  Args.hasArg(OPT_fxray_ignore_loops, OPT_fno_xray_ignore_loops, false);
+  Opts.XRayIgnoreLoops = Args.hasArg(OPT_fxray_ignore_loops);
 
   auto XRayInstrBundles =
   Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
Index: clang/lib/Driver/XRayArgs.cpp
===
--- clang/lib/Driver/XRayArgs.cpp
+++ clang/lib/Driver/XRayArgs.cpp
@@ -101,6 +101,10 @@
 options::OPT_fnoxray_link_deps, true))
 XRayRT = false;
 
+  if (Args.hasFlag(options::OPT_fxray_ignore_loops,
+   options::OPT_fno_xray_ignore_loops, false))
+XRayIgnoreLoops = true;
+
   auto Bundles =
   

[PATCH] D73842: [xray][clang] Always add xray-skip-entry/exit and xray-ignore-loops attrs

2020-02-03 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque marked 2 inline comments as done.
ianlevesque added inline comments.



Comment at: clang/lib/CodeGen/CodeGenFunction.cpp:832
+Fn->addFnAttr("xray-skip-exit");
+  }
+  if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(

@hiraditya I realize on a previous diff you suggested dropping the brackets. 
I'll do that here too.



Comment at: clang/lib/Frontend/CompilerInvocation.cpp:1103
   Opts.XRayIgnoreLoops =
-  Args.hasArg(OPT_fxray_ignore_loops, OPT_fno_xray_ignore_loops, false);
+  Args.hasFlag(OPT_fxray_ignore_loops, OPT_fno_xray_ignore_loops, false);
 

MaskRay wrote:
> `Args.hasArg(OPT_fxray_ignore_loops);`
> 
> There is no need to check a fno option in cc1, if the option is always 
> enabled/disabled by default.
Will update.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D73842



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


[PATCH] D73842: [xray][clang] Always add xray-skip-entry/exit and xray-ignore-loops attrs

2020-02-01 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque created this revision.
ianlevesque added reviewers: hiraditya, smeenai, dberris.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The function attributes xray-skip-entry, xray-skip-exit, and
xray-ignore-loops were only being applied if a function had an
xray-instrument attribute, but they should apply if xray is enabled
globally too.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D73842

Files:
  clang/include/clang/Driver/XRayArgs.h
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/Driver/XRayArgs.cpp
  clang/lib/Frontend/CompilerInvocation.cpp


Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1100,7 +1100,7 @@
   Opts.XRayInstructionThreshold =
   getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
   Opts.XRayIgnoreLoops =
-  Args.hasArg(OPT_fxray_ignore_loops, OPT_fno_xray_ignore_loops, false);
+  Args.hasFlag(OPT_fxray_ignore_loops, OPT_fno_xray_ignore_loops, false);
 
   auto XRayInstrBundles =
   Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
Index: clang/lib/Driver/XRayArgs.cpp
===
--- clang/lib/Driver/XRayArgs.cpp
+++ clang/lib/Driver/XRayArgs.cpp
@@ -101,6 +101,10 @@
 options::OPT_fnoxray_link_deps, true))
 XRayRT = false;
 
+  if (Args.hasFlag(options::OPT_fxray_ignore_loops,
+   options::OPT_fno_xray_ignore_loops, false))
+XRayIgnoreLoops = true;
+
   auto Bundles =
   Args.getAllArgValues(options::OPT_fxray_instrumentation_bundle);
   if (Bundles.empty())
@@ -197,6 +201,9 @@
   if (XRayAlwaysEmitTypedEvents)
 CmdArgs.push_back("-fxray-always-emit-typedevents");
 
+  if (XRayIgnoreLoops)
+CmdArgs.push_back("-fxray-ignore-loops");
+
   CmdArgs.push_back(Args.MakeArgString(Twine(XRayInstructionThresholdOption) +
Twine(InstructionThreshold)));
 
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -814,23 +814,26 @@
   if (ShouldXRayInstrumentFunction())
 Fn->addFnAttr("xray-log-args",
   llvm::utostr(LogArgs->getArgumentCount()));
-if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
-XRayInstrKind::FunctionExit)) {
-  Fn->addFnAttr("xray-skip-exit");
-}
-if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
-XRayInstrKind::FunctionEntry)) {
-  Fn->addFnAttr("xray-skip-entry");
-}
   }
 } else {
   if (ShouldXRayInstrumentFunction() && !CGM.imbueXRayAttrs(Fn, Loc))
 Fn->addFnAttr(
 "xray-instruction-threshold",
 llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));
+}
+
+if (ShouldXRayInstrumentFunction()) {
   if (CGM.getCodeGenOpts().XRayIgnoreLoops) {
 Fn->addFnAttr("xray-ignore-loops");
   }
+  if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
+  XRayInstrKind::FunctionExit)) {
+Fn->addFnAttr("xray-skip-exit");
+  }
+  if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
+  XRayInstrKind::FunctionEntry)) {
+Fn->addFnAttr("xray-skip-entry");
+  }
 }
 
 unsigned Count, Offset;
Index: clang/include/clang/Driver/XRayArgs.h
===
--- clang/include/clang/Driver/XRayArgs.h
+++ clang/include/clang/Driver/XRayArgs.h
@@ -30,6 +30,7 @@
   bool XRayAlwaysEmitCustomEvents = false;
   bool XRayAlwaysEmitTypedEvents = false;
   bool XRayRT = true;
+  bool XRayIgnoreLoops = false;
 
 public:
   /// Parses the XRay arguments from an argument list.


Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1100,7 +1100,7 @@
   Opts.XRayInstructionThreshold =
   getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
   Opts.XRayIgnoreLoops =
-  Args.hasArg(OPT_fxray_ignore_loops, OPT_fno_xray_ignore_loops, false);
+  Args.hasFlag(OPT_fxray_ignore_loops, OPT_fno_xray_ignore_loops, false);
 
   auto XRayInstrBundles =
   Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
Index: clang/lib/Driver/XRayArgs.cpp
===
--- clang/lib/Driver/XRayArgs.cpp
+++ clang/lib/Driver/XRayArgs.cpp
@@ -101,6 +101,10 @@
 options::OPT_fnoxray_link_deps, true))
 XRayRT = false;
 
+  if (Args.hasFlag(options::OPT_fxray_ignore_loops,
+   

[PATCH] D72890: [xray] Allow instrumenting only function entry and/or only function exit

2020-01-17 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque updated this revision to Diff 238866.
ianlevesque added a comment.

Add x86 tests


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D72890

Files:
  clang/include/clang/Basic/XRayInstr.h
  clang/include/clang/Driver/Options.td
  clang/lib/Basic/XRayInstr.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/Driver/XRayArgs.cpp
  clang/test/CodeGen/xray-instrumentation-bundles.cpp
  llvm/lib/CodeGen/XRayInstrumentation.cpp
  llvm/test/CodeGen/AArch64/xray-partial-instrumentation-skip-entry.ll
  llvm/test/CodeGen/AArch64/xray-partial-instrumentation-skip-exit.ll
  llvm/test/CodeGen/X86/xray-partial-instrumentation-skip-entry.ll
  llvm/test/CodeGen/X86/xray-partial-instrumentation-skip-exit.ll

Index: llvm/test/CodeGen/X86/xray-partial-instrumentation-skip-exit.ll
===
--- /dev/null
+++ llvm/test/CodeGen/X86/xray-partial-instrumentation-skip-exit.ll
@@ -0,0 +1,49 @@
+; RUN: llc -verify-machineinstrs -filetype=asm -o - -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -filetype=asm -o - \
+; RUN: -mtriple=x86_64-unknown-linux-gnu -relocation-model=pic < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -filetype=asm -o - -mtriple=x86_64-darwin-unknown< %s | FileCheck %s
+
+define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" "xray-skip-exit" {
+; CHECK:   .p2align 1, 0x90
+; CHECK-LABEL: Lxray_sled_0:
+; CHECK:   .ascii "\353\t"
+; CHECK-NEXT:  nopw 512(%rax,%rax)
+  ret i32 0
+; CHECK-NOT: Lxray_sled_1:
+; CHECK:   retq
+}
+; CHECK-LABEL: xray_instr_map
+; CHECK-LABEL: Lxray_sleds_start0:
+; CHECK:   .quad {{.*}}xray_sled_0
+; CHECK-LABEL: Lxray_sleds_end0:
+; CHECK-LABEL: xray_fn_idx
+; CHECK:   .quad {{.*}}xray_sleds_start0
+; CHECK-NEXT:  .quad {{.*}}xray_sleds_end0
+
+
+; We test multiple returns in a single function to make sure we're skipping all
+; of them with XRay instrumentation.
+define i32 @bar(i32 %i) nounwind noinline uwtable "function-instrument"="xray-always" "xray-skip-exit" {
+; CHECK:   .p2align 1, 0x90
+; CHECK-LABEL: Lxray_sled_1:
+; CHECK:   .ascii "\353\t"
+; CHECK-NEXT:  nopw 512(%rax,%rax)
+Test:
+  %cond = icmp eq i32 %i, 0
+  br i1 %cond, label %IsEqual, label %NotEqual
+IsEqual:
+  ret i32 0
+; CHECK-NOT: Lxray_sled_{{.*}}:
+; CHECK:   retq
+NotEqual:
+  ret i32 1
+; CHECK-NOT: Lxray_sled_{{.*}}:
+; CHECK:   retq
+}
+; CHECK-LABEL: xray_instr_map
+; CHECK-LABEL: Lxray_sleds_start1:
+; CHECK:   .quad {{.*}}xray_sled_1
+; CHECK-LABEL: Lxray_sleds_end1:
+; CHECK-LABEL: xray_fn_idx
+; CHECK:   .quad {{.*}}xray_sleds_start1
+; CHECK-NEXT:  .quad {{.*}}xray_sleds_end1
Index: llvm/test/CodeGen/X86/xray-partial-instrumentation-skip-entry.ll
===
--- /dev/null
+++ llvm/test/CodeGen/X86/xray-partial-instrumentation-skip-entry.ll
@@ -0,0 +1,50 @@
+; RUN: llc -verify-machineinstrs -filetype=asm -o - -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -filetype=asm -o - \
+; RUN: -mtriple=x86_64-unknown-linux-gnu -relocation-model=pic < %s | FileCheck %s
+; RUN: llc -verify-machineinstrs -filetype=asm -o - -mtriple=x86_64-darwin-unknown< %s | FileCheck %s
+
+define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" "xray-skip-entry" {
+; CHECK-NOT: Lxray_sled_0:
+  ret i32 0
+; CHECK:   .p2align 1, 0x90
+; CHECK-LABEL: Lxray_sled_0:
+; CHECK:   retq
+; CHECK-NEXT:  nopw %cs:512(%rax,%rax)
+}
+; CHECK-LABEL: xray_instr_map
+; CHECK-LABEL: Lxray_sleds_start0:
+; CHECK:   .quad {{.*}}xray_sled_0
+; CHECK-LABEL: Lxray_sleds_end0:
+; CHECK-LABEL: xray_fn_idx
+; CHECK:   .quad {{.*}}xray_sleds_start0
+; CHECK-NEXT:  .quad {{.*}}xray_sleds_end0
+
+
+; We test multiple returns in a single function to make sure we're getting all
+; of them with XRay instrumentation.
+define i32 @bar(i32 %i) nounwind noinline uwtable "function-instrument"="xray-always" "xray-skip-entry" {
+; CHECK-NOT: Lxray_sled_1:
+Test:
+  %cond = icmp eq i32 %i, 0
+  br i1 %cond, label %IsEqual, label %NotEqual
+IsEqual:
+  ret i32 0
+; CHECK:   .p2align 1, 0x90
+; CHECK-LABEL: Lxray_sled_1:
+; CHECK:   retq
+; CHECK-NEXT:  nopw %cs:512(%rax,%rax)
+NotEqual:
+  ret i32 1
+; CHECK:   .p2align 1, 0x90
+; CHECK-LABEL: Lxray_sled_2:
+; CHECK:   retq
+; CHECK-NEXT:  nopw %cs:512(%rax,%rax)
+}
+; CHECK-LABEL: xray_instr_map
+; CHECK-LABEL: Lxray_sleds_start1:
+; CHECK:   .quad {{.*}}xray_sled_1
+; CHECK:   .quad {{.*}}xray_sled_2
+; CHECK-LABEL: Lxray_sleds_end1:
+; CHECK-LABEL: xray_fn_idx
+; CHECK:   .quad {{.*}}xray_sleds_start1
+; CHECK-NEXT:  .quad {{.*}}xray_sleds_end1
Index: llvm/test/CodeGen/AArch64/xray-partial-instrumentation-skip-exit.ll

[PATCH] D72873: [clang][xray] Add -fxray-ignore-loops option

2020-01-17 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque marked an inline comment as done.
ianlevesque added inline comments.



Comment at: clang/test/CodeGen/xray-ignore-loops.cpp:5
+  return 1;
+}
+

hiraditya wrote:
> I think we need one more test case of a function having a loop.
I'm not opposed but the logic to actually ignore loops has a test on D72659


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D72873



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


[PATCH] D72890: [xray] Allow instrumenting only function entry and/or only function exit

2020-01-16 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque created this revision.
ianlevesque added a reviewer: dberris.
Herald added subscribers: llvm-commits, cfe-commits, hiraditya.
Herald added projects: clang, LLVM.

Extend -fxray-instrumentation-bundle to split function-entry and
function-exit into two separate options, so that it is possible to
instrument only function entry or only function exit.  For use cases
that only care about one or the other this will save significant overhead
and code size.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D72890

Files:
  clang/include/clang/Basic/XRayInstr.h
  clang/include/clang/Driver/Options.td
  clang/lib/Basic/XRayInstr.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/Driver/XRayArgs.cpp
  clang/test/CodeGen/xray-instrumentation-bundles.cpp
  llvm/lib/CodeGen/XRayInstrumentation.cpp
  llvm/test/CodeGen/AArch64/xray-partial-instrumentation-skip-entry.ll
  llvm/test/CodeGen/AArch64/xray-partial-instrumentation-skip-exit.ll

Index: llvm/test/CodeGen/AArch64/xray-partial-instrumentation-skip-exit.ll
===
--- /dev/null
+++ llvm/test/CodeGen/AArch64/xray-partial-instrumentation-skip-exit.ll
@@ -0,0 +1,21 @@
+; RUN: llc -filetype=asm -o - -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
+
+define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" "xray-skip-exit" {
+; CHECK-LABEL: Lxray_sled_0:
+; CHECK-NEXT:  b  #32
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-LABEL: Ltmp0:
+  ret i32 0
+; CHECK-NOT: Lxray_sled_1:
+; CHECK:  ret
+}
+; CHECK-LABEL: xray_instr_map
+; CHECK-LABEL: Lxray_sleds_start0
+; CHECK:   .xword .Lxray_sled_0
+; CHECK-LABEL: Lxray_sleds_end0
Index: llvm/test/CodeGen/AArch64/xray-partial-instrumentation-skip-entry.ll
===
--- /dev/null
+++ llvm/test/CodeGen/AArch64/xray-partial-instrumentation-skip-entry.ll
@@ -0,0 +1,21 @@
+; RUN: llc -filetype=asm -o - -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
+
+define i32 @foo() nounwind noinline uwtable "function-instrument"="xray-always" "xray-skip-entry" {
+; CHECK-NOT: Lxray_sled_0:
+  ret i32 0
+; CHECK-LABEL: Lxray_sled_0:
+; CHECK-NEXT:  b  #32
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-NEXT:  nop
+; CHECK-LABEL: Ltmp0:
+; CHECK-NEXT:  ret
+}
+; CHECK-LABEL: xray_instr_map
+; CHECK-LABEL: Lxray_sleds_start0
+; CHECK:   .xword .Lxray_sled_0
+; CHECK-LABEL: Lxray_sleds_end0
Index: llvm/lib/CodeGen/XRayInstrumentation.cpp
===
--- llvm/lib/CodeGen/XRayInstrumentation.cpp
+++ llvm/lib/CodeGen/XRayInstrumentation.cpp
@@ -201,43 +201,47 @@
 return false;
   }
 
-  // First, insert an PATCHABLE_FUNCTION_ENTER as the first instruction of the
-  // MachineFunction.
-  BuildMI(FirstMBB, FirstMI, FirstMI.getDebugLoc(),
-  TII->get(TargetOpcode::PATCHABLE_FUNCTION_ENTER));
-
-  switch (MF.getTarget().getTargetTriple().getArch()) {
-  case Triple::ArchType::arm:
-  case Triple::ArchType::thumb:
-  case Triple::ArchType::aarch64:
-  case Triple::ArchType::mips:
-  case Triple::ArchType::mipsel:
-  case Triple::ArchType::mips64:
-  case Triple::ArchType::mips64el: {
-// For the architectures which don't have a single return instruction
-InstrumentationOptions op;
-op.HandleTailcall = false;
-op.HandleAllReturns = true;
-prependRetWithPatchableExit(MF, TII, op);
-break;
-  }
-  case Triple::ArchType::ppc64le: {
-// PPC has conditional returns. Turn them into branch and plain returns.
-InstrumentationOptions op;
-op.HandleTailcall = false;
-op.HandleAllReturns = true;
-replaceRetWithPatchableRet(MF, TII, op);
-break;
-  }
-  default: {
-// For the architectures that have a single return instruction (such as
-//   RETQ on x86_64).
-InstrumentationOptions op;
-op.HandleTailcall = true;
-op.HandleAllReturns = false;
-replaceRetWithPatchableRet(MF, TII, op);
-break;
+  if (!F.hasFnAttribute("xray-skip-entry")) {
+// First, insert an PATCHABLE_FUNCTION_ENTER as the first instruction of the
+// MachineFunction.
+BuildMI(FirstMBB, FirstMI, FirstMI.getDebugLoc(),
+TII->get(TargetOpcode::PATCHABLE_FUNCTION_ENTER));
   }
+
+  if (!F.hasFnAttribute("xray-skip-exit")) {
+switch (MF.getTarget().getTargetTriple().getArch()) {
+case Triple::ArchType::arm:
+case Triple::ArchType::thumb:
+case Triple::ArchType::aarch64:
+case Triple::ArchType::mips:
+case Triple::ArchType::mipsel:
+case Triple::ArchType::mips64:
+case Triple::ArchType::mips64el: {
+  // For the architectures which don't have a single return instruction
+  InstrumentationOptions op;
+  op.HandleTailcall = 

[PATCH] D72873: [clang][xray] Add -fxray-ignore-loops option

2020-01-16 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque created this revision.
ianlevesque added a reviewer: dberris.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
ianlevesque updated this revision to Diff 238600.
ianlevesque added a comment.

fix clang-format


XRay allows tuning by minimum function size, but also always instruments
functions with loops in them. If the minimum function size is set to a
large value the loop instrumention ends up causing most functions to be
instrumented anyway. This adds a new flag, -fxray-ignore-loops, to disable
the loop detection logic.

The LLVM change to take the new function attribute into account is in D72659 



Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D72873

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/xray-ignore-loops.cpp


Index: clang/test/CodeGen/xray-ignore-loops.cpp
===
--- /dev/null
+++ clang/test/CodeGen/xray-ignore-loops.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fxray-instrument -fxray-ignore-loops -x c++ -std=c++11 
-emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck %s
+
+int foo() {
+  return 1;
+}
+
+// CHECK: define i32 @_Z3foov() #[[ATTRS:[0-9]+]] {
+// CHECK-DAG: attributes #[[ATTRS]] = {{.*}} "xray-ignore-loops" {{.*}}
Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1091,6 +1091,8 @@
   Args.hasArg(OPT_fxray_always_emit_typedevents);
   Opts.XRayInstructionThreshold =
   getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
+  Opts.XRayIgnoreLoops =
+  Args.hasArg(OPT_fxray_ignore_loops, OPT_fno_xray_ignore_loops, false);
 
   auto XRayInstrBundles =
   Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -818,6 +818,9 @@
 Fn->addFnAttr(
 "xray-instruction-threshold",
 llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));
+  if (CGM.getCodeGenOpts().XRayIgnoreLoops) {
+Fn->addFnAttr("xray-ignore-loops");
+  }
 }
 
 if (const auto *Attr = D->getAttr()) {
Index: clang/include/clang/Driver/Options.td
===
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1292,6 +1292,13 @@
 def fnoxray_always_emit_typedevents : Flag<["-"], 
"fno-xray-always-emit-typedevents">, Group,
   Flags<[CC1Option]>;
 
+def fxray_ignore_loops : Flag<["-"], "fxray-ignore-loops">, Group,
+  Flags<[CC1Option]>,
+  HelpText<"Don't instrument functions with loops unless they also meet the 
minimum function size">;
+def fno_xray_ignore_loops : Flag<["-"], "fno-xray-ignore-loops">, 
Group,
+  Flags<[CC1Option]>;
+
+
 def fxray_link_deps : Flag<["-"], "fxray-link-deps">, Group,
   Flags<[CC1Option]>,
   HelpText<"Tells clang to add the link dependencies for XRay.">;
Index: clang/include/clang/Basic/CodeGenOptions.def
===
--- clang/include/clang/Basic/CodeGenOptions.def
+++ clang/include/clang/Basic/CodeGenOptions.def
@@ -106,6 +106,10 @@
 ///< Set when -fxray-always-emit-typedevents is enabled.
 CODEGENOPT(XRayAlwaysEmitTypedEvents , 1, 0)
 
+///< Set when -fxray-ignore-loops is enabled.
+CODEGENOPT(XRayIgnoreLoops , 1, 0)
+
+
 ///< Set the minimum number of instructions in a function to determine 
selective
 ///< XRay instrumentation.
 VALUE_CODEGENOPT(XRayInstructionThreshold , 32, 200)


Index: clang/test/CodeGen/xray-ignore-loops.cpp
===
--- /dev/null
+++ clang/test/CodeGen/xray-ignore-loops.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fxray-instrument -fxray-ignore-loops -x c++ -std=c++11 -emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck %s
+
+int foo() {
+  return 1;
+}
+
+// CHECK: define i32 @_Z3foov() #[[ATTRS:[0-9]+]] {
+// CHECK-DAG: attributes #[[ATTRS]] = {{.*}} "xray-ignore-loops" {{.*}}
Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1091,6 +1091,8 @@
   Args.hasArg(OPT_fxray_always_emit_typedevents);
   Opts.XRayInstructionThreshold =
   getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
+  Opts.XRayIgnoreLoops =
+  Args.hasArg(OPT_fxray_ignore_loops, OPT_fno_xray_ignore_loops, false);
 
   auto XRayInstrBundles =
   

[PATCH] D72873: [clang][xray] Add -fxray-ignore-loops option

2020-01-16 Thread Ian Levesque via Phabricator via cfe-commits
ianlevesque updated this revision to Diff 238600.
ianlevesque added a comment.

fix clang-format


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D72873

Files:
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/xray-ignore-loops.cpp


Index: clang/test/CodeGen/xray-ignore-loops.cpp
===
--- /dev/null
+++ clang/test/CodeGen/xray-ignore-loops.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fxray-instrument -fxray-ignore-loops -x c++ -std=c++11 
-emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck %s
+
+int foo() {
+  return 1;
+}
+
+// CHECK: define i32 @_Z3foov() #[[ATTRS:[0-9]+]] {
+// CHECK-DAG: attributes #[[ATTRS]] = {{.*}} "xray-ignore-loops" {{.*}}
Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1091,6 +1091,8 @@
   Args.hasArg(OPT_fxray_always_emit_typedevents);
   Opts.XRayInstructionThreshold =
   getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
+  Opts.XRayIgnoreLoops =
+  Args.hasArg(OPT_fxray_ignore_loops, OPT_fno_xray_ignore_loops, false);
 
   auto XRayInstrBundles =
   Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -818,6 +818,9 @@
 Fn->addFnAttr(
 "xray-instruction-threshold",
 llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));
+  if (CGM.getCodeGenOpts().XRayIgnoreLoops) {
+Fn->addFnAttr("xray-ignore-loops");
+  }
 }
 
 if (const auto *Attr = D->getAttr()) {
Index: clang/include/clang/Driver/Options.td
===
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1292,6 +1292,13 @@
 def fnoxray_always_emit_typedevents : Flag<["-"], 
"fno-xray-always-emit-typedevents">, Group,
   Flags<[CC1Option]>;
 
+def fxray_ignore_loops : Flag<["-"], "fxray-ignore-loops">, Group,
+  Flags<[CC1Option]>,
+  HelpText<"Don't instrument functions with loops unless they also meet the 
minimum function size">;
+def fno_xray_ignore_loops : Flag<["-"], "fno-xray-ignore-loops">, 
Group,
+  Flags<[CC1Option]>;
+
+
 def fxray_link_deps : Flag<["-"], "fxray-link-deps">, Group,
   Flags<[CC1Option]>,
   HelpText<"Tells clang to add the link dependencies for XRay.">;
Index: clang/include/clang/Basic/CodeGenOptions.def
===
--- clang/include/clang/Basic/CodeGenOptions.def
+++ clang/include/clang/Basic/CodeGenOptions.def
@@ -106,6 +106,10 @@
 ///< Set when -fxray-always-emit-typedevents is enabled.
 CODEGENOPT(XRayAlwaysEmitTypedEvents , 1, 0)
 
+///< Set when -fxray-ignore-loops is enabled.
+CODEGENOPT(XRayIgnoreLoops , 1, 0)
+
+
 ///< Set the minimum number of instructions in a function to determine 
selective
 ///< XRay instrumentation.
 VALUE_CODEGENOPT(XRayInstructionThreshold , 32, 200)


Index: clang/test/CodeGen/xray-ignore-loops.cpp
===
--- /dev/null
+++ clang/test/CodeGen/xray-ignore-loops.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fxray-instrument -fxray-ignore-loops -x c++ -std=c++11 -emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck %s
+
+int foo() {
+  return 1;
+}
+
+// CHECK: define i32 @_Z3foov() #[[ATTRS:[0-9]+]] {
+// CHECK-DAG: attributes #[[ATTRS]] = {{.*}} "xray-ignore-loops" {{.*}}
Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1091,6 +1091,8 @@
   Args.hasArg(OPT_fxray_always_emit_typedevents);
   Opts.XRayInstructionThreshold =
   getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
+  Opts.XRayIgnoreLoops =
+  Args.hasArg(OPT_fxray_ignore_loops, OPT_fno_xray_ignore_loops, false);
 
   auto XRayInstrBundles =
   Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -818,6 +818,9 @@
 Fn->addFnAttr(
 "xray-instruction-threshold",
 llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));
+  if (CGM.getCodeGenOpts().XRayIgnoreLoops) {
+