dberris created this revision.
dberris added reviewers: echristo, kpw, eizan, pelikan.

This change addresses http://llvm.org/PR36926 by allowing users to pick
which instrumentation bundles to use, when instrumenting with XRay. In
particular, the flag `-fxray-instrumentation-bundle=` has four valid
values:

- `all`: the default, which will emit all kinds of instrumentation

points.

- `none`: equivalent to -fnoxray-instrument
- `function-extents`: only emits the entry/exit sleds
- `custom-only`: only emits the custom event sleds


https://reviews.llvm.org/D44970

Files:
  clang/include/clang/Driver/Options.td
  clang/include/clang/Driver/XRayArgs.h
  clang/include/clang/Frontend/CodeGenOptions.def
  clang/include/clang/Frontend/CodeGenOptions.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Driver/XRayArgs.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/xray-instrumentation-bundles.cpp

Index: clang/test/CodeGen/xray-instrumentation-bundles.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGen/xray-instrumentation-bundles.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fxray-instrument -fxray-instrumentation-bundle=none -x c++ \
+// RUN:     -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN:     | FileCheck %s
+// RUN: %clang_cc1 -fxray-instrument \
+// RUN:     -fxray-instrumentation-bundle=function-extents -x c++ \
+// RUN:     -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN:     | FileCheck %s
+
+// CHECK-LABEL: alwaysInstrument
+[[clang::xray_always_instrument]] void alwaysInstrument() {
+  static constexpr char kPhase[] = "always";
+  __xray_customevent(kPhase, 6);
+  // CHECK-NOT: call void @llvm.xray.customevent(i8*{{.*}}, i32 6)
+}
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -446,6 +446,21 @@
   }
 }
 
+static CodeGenOptions::XRayInstrumentationPointBundle
+parseXRayInstrumentationBundle(Arg *A, ArgList &Args, DiagnosticsEngine &D) {
+  StringRef V = A->getValue();
+  if (V == "all")
+    return CodeGenOptions::XRayInstrumentationPointBundle::XRay_All;
+  if (V == "none")
+    return CodeGenOptions::XRayInstrumentationPointBundle::XRay_None;
+  if (V == "function-extents")
+    return CodeGenOptions::XRayInstrumentationPointBundle::XRay_FunctionExtents;
+  if (V == "custom-only")
+    return CodeGenOptions::XRayInstrumentationPointBundle::XRay_CustomOnly;
+  D.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << V;
+  return CodeGenOptions::XRayInstrumentationPointBundle::XRay_All;
+}
+
 // Set the profile kind for fprofile-instrument.
 static void setPGOInstrumentor(CodeGenOptions &Opts, ArgList &Args,
                                DiagnosticsEngine &Diags) {
@@ -853,6 +868,11 @@
       Args.hasArg(OPT_fxray_always_emit_customevents);
   Opts.XRayInstructionThreshold =
       getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
+
+  if (auto A = Args.getLastArg(OPT_fxray_instrumentation_bundle))
+    Opts.setXRayInstrumentationBundle(
+        parseXRayInstrumentationBundle(A, Args, Diags));
+
   Opts.InstrumentForProfiling = Args.hasArg(OPT_pg);
   Opts.CallFEntry = Args.hasArg(OPT_mfentry);
   Opts.EmitOpenCLArgMetadata = Args.hasArg(OPT_cl_kernel_arg_info);
Index: clang/lib/Driver/XRayArgs.cpp
===================================================================
--- clang/lib/Driver/XRayArgs.cpp
+++ clang/lib/Driver/XRayArgs.cpp
@@ -27,6 +27,8 @@
 constexpr char XRayInstrumentOption[] = "-fxray-instrument";
 constexpr char XRayInstructionThresholdOption[] =
     "-fxray-instruction-threshold=";
+constexpr char XRayInstrumentationBundleOption[] =
+    "-fxray-instrumentation-bundle=";
 } // namespace
 
 XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) {
@@ -50,13 +52,14 @@
             << (std::string(XRayInstrumentOption) + " on " + Triple.str());
       }
     } else if (Triple.getOS() == llvm::Triple::FreeBSD) {
-        if (Triple.getArch() != llvm::Triple::x86_64) {
-          D.Diag(diag::err_drv_clang_unsupported)
-              << (std::string(XRayInstrumentOption) + " on " + Triple.str());
-        }
+      if (Triple.getArch() != llvm::Triple::x86_64) {
+        D.Diag(diag::err_drv_clang_unsupported)
+            << (std::string(XRayInstrumentOption) + " on " + Triple.str());
+      }
     } else {
       D.Diag(diag::err_drv_clang_unsupported)
-          << (std::string(XRayInstrumentOption) + " on non-supported target OS");
+          << (std::string(XRayInstrumentOption) +
+              " on non-supported target OS");
     }
     XRayInstrument = true;
     if (const Arg *A =
@@ -75,6 +78,19 @@
                      options::OPT_fnoxray_always_emit_customevents, false))
       XRayAlwaysEmitCustomEvents = true;
 
+    // We check the bundle of instrumentation that we let users choose. This
+    // coarse grained control is used to determine which instrumentation points
+    // to actually emit.
+    if (const Arg *A =
+            Args.getLastArg(options::OPT_fxray_instrumentation_bundle)) {
+      StringRef B = A->getValue();
+      if (B != "all" && B != "none" && B != "function-extents" &&
+          B != "custom-only")
+        D.Diag(diag::err_drv_invalid_value) << A->getAsString(Args) << B;
+      else
+        XRayBundle = B;
+    }
+
     // Validate the always/never attribute files. We also make sure that they
     // are treated as actual dependencies.
     for (const auto &Filename :
@@ -109,6 +125,8 @@
 
   CmdArgs.push_back(Args.MakeArgString(Twine(XRayInstructionThresholdOption) +
                                        Twine(InstructionThreshold)));
+  CmdArgs.push_back(Args.MakeArgString(Twine(XRayInstrumentationBundleOption) +
+                                       Twine(XRayBundle)));
 
   for (const auto &Always : AlwaysInstrumentFiles) {
     SmallString<64> AlwaysInstrumentOpt("-fxray-always-instrument=");
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -3243,6 +3243,15 @@
       if (XRayAttr->neverXRayInstrument() && !AlwaysEmitXRayCustomEvents())
         return RValue::getIgnored();
 
+    // Check first whether the bundle of XRay instrumentation includes this
+    // custom events.
+    {
+      auto XRayBundle = CGM.getCodeGenOpts().getXRayInstrumentationBundle();
+      if (XRayBundle == CodeGenOptions::XRay_None ||
+          XRayBundle == CodeGenOptions::XRay_FunctionExtents)
+        return RValue::getIgnored();
+    }
+
     Function *F = CGM.getIntrinsic(Intrinsic::xray_customevent);
     auto FTy = F->getFunctionType();
     auto Arg0 = E->getArg(0);
Index: clang/include/clang/Frontend/CodeGenOptions.h
===================================================================
--- clang/include/clang/Frontend/CodeGenOptions.h
+++ clang/include/clang/Frontend/CodeGenOptions.h
@@ -107,6 +107,14 @@
     Embed_Marker    // Embed a marker as a placeholder for bitcode.
   };
 
+  enum XRayInstrumentationPointBundle {
+    XRay_All,             // Always emit all the instrumentation points.
+    XRay_None,            // Emit none of the instrumentation points.
+    XRay_FunctionExtents, // Only emit function entry/exit instrumentation
+                          // points.
+    XRay_CustomOnly,      // Only emit custom event instrumentation points.
+  };
+
   /// The code model to use (-mcmodel).
   std::string CodeModel;
 
Index: clang/include/clang/Frontend/CodeGenOptions.def
===================================================================
--- clang/include/clang/Frontend/CodeGenOptions.def
+++ clang/include/clang/Frontend/CodeGenOptions.def
@@ -95,6 +95,10 @@
 ///< Set when -fxray-always-emit-customevents is enabled.
 CODEGENOPT(XRayAlwaysEmitCustomEvents , 1, 0)
 
+///< Filter the instrumentation points we emit, to predefined groupings.
+ENUM_CODEGENOPT(XRayInstrumentationBundle, XRayInstrumentationPointBundle, 4,
+                XRayInstrumentationPointBundle::XRay_All)
+
 ///< Set the minimum number of instructions in a function to determine selective
 ///< XRay instrumentation.
 VALUE_CODEGENOPT(XRayInstructionThreshold , 32, 200)
Index: clang/include/clang/Driver/XRayArgs.h
===================================================================
--- clang/include/clang/Driver/XRayArgs.h
+++ clang/include/clang/Driver/XRayArgs.h
@@ -25,6 +25,7 @@
   bool XRayInstrument = false;
   int InstructionThreshold = 200;
   bool XRayAlwaysEmitCustomEvents = false;
+  std::string XRayBundle = "all";
 
 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
@@ -1107,6 +1107,10 @@
 def fnoxray_always_emit_customevents : Flag<["-"], "fno-xray-always-emit-customevents">, Group<f_Group>,
   Flags<[CC1Option]>;
 
+def fxray_instrumentation_bundle : Joined<["-"], "fxray-instrumentation-bundle=">,
+  Group<f_Group>, Flags<[CC1Option]>,
+  HelpText<"Select which bundle of XRay instrumentation points to emit. Options: all, none, function-extents, custom-only.">;
+
 def ffine_grained_bitfield_accesses : Flag<["-"],
   "ffine-grained-bitfield-accesses">, Group<f_clang_Group>, Flags<[CC1Option]>,
   HelpText<"Use separate accesses for bitfields with legal widths and alignments.">;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to