dberris updated this revision to Diff 140731.
dberris marked 8 inline comments as done.
dberris added a comment.

- fixup: address comments


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/CodeGen/CodeGenFunction.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,21 @@
+// 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
+// RUN: %clang_cc1 -fxray-instrument \
+// RUN:     -fxray-instrumentation-bundle=none -x c++ \
+// RUN:     -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN:     | FileCheck --check-prefixes CHECK,DISABLE %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)
+  // DISABLE-NOT: call void @llvm.xray.customevent(i8*{{.*}}, i32 6)
+}
+
+// DISABLE-NOT: function-instrument=always
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -446,6 +446,23 @@
   }
 }
 
+static CodeGenOptions::XRayInstrumentationPointBundle
+parseXRayInstrumentationBundle(Arg *A, ArgList &Args, DiagnosticsEngine &D) {
+  StringRef V = A->getValue();
+  auto Bundle =  llvm::StringSwitch<CodeGenOptions::XRayInstrumentationPointBundle>(V)
+      .Case("all", CodeGenOptions::XRayInstrumentationPointBundle::XRay_All)
+      .Case("none", CodeGenOptions::XRayInstrumentationPointBundle::XRay_None)
+      .Case("function-extents",
+            CodeGenOptions::XRayInstrumentationPointBundle::XRay_Function)
+      .Case("custom-only",
+            CodeGenOptions::XRayInstrumentationPointBundle::XRay_CustomOnly)
+      .Default(CodeGenOptions::XRayInstrumentationPointBundle::XRay_All);
+  if (Bundle == CodeGenOptions::XRayInstrumentationPointBundle::XRay_All &&
+      !V.empty() && V != "all")
+    D.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << V;
+  return Bundle;
+}
+
 // Set the profile kind for fprofile-instrument.
 static void setPGOInstrumentor(CodeGenOptions &Opts, ArgList &Args,
                                DiagnosticsEngine &Diags) {
@@ -821,11 +838,20 @@
       Args.hasArg(OPT_finstrument_functions_after_inlining);
   Opts.InstrumentFunctionEntryBare =
       Args.hasArg(OPT_finstrument_function_entry_bare);
-  Opts.XRayInstrumentFunctions = Args.hasArg(OPT_fxray_instrument);
   Opts.XRayAlwaysEmitCustomEvents =
       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.XRayInstrumentFunctions =
+      Args.hasArg(OPT_fxray_instrument) &&
+      Opts.getXRayInstrumentationBundle() !=
+          CodeGenOptions::XRayInstrumentationPointBundle::XRay_None;
+
   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,10 +52,10 @@
             << (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");
@@ -75,6 +77,23 @@
                      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 Bundle = A->getValue();
+      XRayBundle = llvm::StringSwitch<StringRef>(Bundle)
+                       .Case("all", "all")
+                       .Case("none", "none")
+                       .Case("function-extents", "function-extents")
+                       .Case("custom-only", "custom-only")
+                       .Default("error");
+      if (XRayBundle == "error")
+        D.Diag(clang::diag::err_drv_invalid_value)
+            << A->getAsString(Args) << Bundle;
+    }
+
     // Validate the always/never attribute files. We also make sure that they
     // are treated as actual dependencies.
     for (const auto &Filename :
@@ -109,6 +128,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/CodeGenFunction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -468,7 +468,8 @@
 /// AlwaysEmitXRayCustomEvents - Return true if we should emit IR for calls to
 /// the __xray_customevent(...) builin calls, when doing XRay instrumentation.
 bool CodeGenFunction::AlwaysEmitXRayCustomEvents() const {
-  return CGM.getCodeGenOpts().XRayAlwaysEmitCustomEvents;
+  return CGM.getCodeGenOpts().XRayInstrumentFunctions &&
+         CGM.getCodeGenOpts().XRayAlwaysEmitCustomEvents;
 }
 
 llvm::Constant *
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -3245,6 +3245,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::XRayInstrumentationPointBundle::XRay_None ||
+        XRayBundle ==
+            CodeGenOptions::XRayInstrumentationPointBundle::XRay_Function)
+      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_Function,   // 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