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 +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 =
+          Args.getLastArg(options::OPT_fxray_selected_function_group)) {
+    StringRef S = A->getValue();
+    if (S.getAsInteger(0, XRaySelectedFunctionGroup) ||
+        XRaySelectedFunctionGroup < 0 ||
+        XRaySelectedFunctionGroup >= XRayFunctionGroups)
+      D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
+  }
+
   // Then we want to sort and unique the modes we've collected.
   llvm::sort(Modes);
   Modes.erase(std::unique(Modes.begin(), Modes.end()), Modes.end());
@@ -210,6 +225,17 @@
   if (!XRayFunctionIndex)
     CmdArgs.push_back("-fno-xray-function-index");
 
+  if (XRayFunctionGroups > 1) {
+    CmdArgs.push_back(Args.MakeArgString(Twine("-fxray-function-groups=") +
+                                         Twine(XRayFunctionGroups)));
+  }
+
+  if (XRaySelectedFunctionGroup != 0) {
+    CmdArgs.push_back(
+        Args.MakeArgString(Twine("-fxray-selected-function-group=") +
+                           Twine(XRaySelectedFunctionGroup)));
+  }
+
   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
@@ -32,6 +32,7 @@
 #include "clang/Basic/TargetInfo.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/Dominators.h"
@@ -40,6 +41,7 @@
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/MDBuilder.h"
 #include "llvm/IR/Operator.h"
+#include "llvm/Support/CRC.h"
 #include "llvm/Transforms/Utils/PromoteMemToReg.h"
 using namespace clang;
 using namespace CodeGen;
@@ -772,13 +774,16 @@
         SanOpts.Mask &= ~SanitizerKind::Null;
 
   // Apply xray attributes to the function (as a string, for now)
+  bool AlwaysXRayAttr = false;
   if (const auto *XRayAttr = D ? D->getAttr<XRayInstrumentAttr>() : nullptr) {
     if (CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
             XRayInstrKind::FunctionEntry) ||
         CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
             XRayInstrKind::FunctionExit)) {
-      if (XRayAttr->alwaysXRayInstrument() && ShouldXRayInstrumentFunction())
+      if (XRayAttr->alwaysXRayInstrument() && ShouldXRayInstrumentFunction()) {
         Fn->addFnAttr("function-instrument", "xray-always");
+        AlwaysXRayAttr = true;
+      }
       if (XRayAttr->neverXRayInstrument())
         Fn->addFnAttr("function-instrument", "xray-never");
       if (const auto *LogArgs = D->getAttr<XRayLogArgsAttr>())
@@ -804,6 +809,16 @@
     if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
             XRayInstrKind::FunctionEntry))
       Fn->addFnAttr("xray-skip-entry");
+
+    auto FuncGroups = CGM.getCodeGenOpts().XRayTotalFunctionGroups;
+    if (FuncGroups > 1) {
+      const ArrayRef<uint8_t> FuncName(CurFn->getName().bytes_begin(),
+                                       CurFn->getName().bytes_end());
+      auto Group = crc32(FuncName) % FuncGroups;
+      if (Group != CGM.getCodeGenOpts().XRaySelectedFunctionGroup &&
+          !AlwaysXRayAttr)
+        Fn->addFnAttr("function-instrument", "xray-never");
+    }
   }
 
   unsigned Count, Offset;
Index: clang/include/clang/Driver/XRayArgs.h
===================================================================
--- clang/include/clang/Driver/XRayArgs.h
+++ clang/include/clang/Driver/XRayArgs.h
@@ -32,6 +32,8 @@
   bool XRayRT = true;
   bool XRayIgnoreLoops = false;
   bool XRayFunctionIndex;
+  int XRayFunctionGroups = 1;
+  int XRaySelectedFunctionGroup;
 
 public:
   /// Parses the XRay arguments from an argument list.
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1339,6 +1339,17 @@
   Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Select which XRay instrumentation points to emit. Options: all, none, function-entry, function-exit, function, custom. Default is 'all'.  'function' includes both 'function-entry' and 'function-exit'.">;
 
+def fxray_function_groups :
+  Joined<["-"], "fxray-function-groups=">,
+  Group<f_Group>, Flags<[CC1Option]>,
+  HelpText<"Only instrument 1 of N groups">;
+
+def fxray_selected_function_group :
+  Joined<["-"], "fxray-selected-function-group=">,
+  Group<f_Group>, Flags<[CC1Option]>,
+  HelpText<"When using -fxray-function-groups, select which group of functions to instrument. Valid range is 0 to fxray-function-groups - 1">;
+
+
 def ffine_grained_bitfield_accesses : Flag<["-"],
   "ffine-grained-bitfield-accesses">, Group<f_clang_Group>, Flags<[CC1Option]>,
   HelpText<"Use separate accesses for consecutive bitfield runs with legal widths and alignments.">;
Index: clang/include/clang/Basic/CodeGenOptions.def
===================================================================
--- clang/include/clang/Basic/CodeGenOptions.def
+++ clang/include/clang/Basic/CodeGenOptions.def
@@ -120,6 +120,12 @@
 ///< XRay instrumentation.
 VALUE_CODEGENOPT(XRayInstructionThreshold , 32, 200)
 
+///< Only instrument 1 in N functions, by dividing functions into N total groups and
+///< instrumenting only the specified group at a time. Group numbers start at 0
+///< and end at N-1.
+VALUE_CODEGENOPT(XRayTotalFunctionGroups, 32, 1)
+VALUE_CODEGENOPT(XRaySelectedFunctionGroup, 32, 0)
+
 VALUE_CODEGENOPT(PatchableFunctionEntryCount , 32, 0) ///< Number of NOPs at function entry
 VALUE_CODEGENOPT(PatchableFunctionEntryOffset , 32, 0)
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to