dberris updated this revision to Diff 140735.
dberris added a comment.

- fixup: Fix tests for better coverage of settings


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/CodeGen/CodeGenModule.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,22 @@
+// 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 --check-prefixes CHECK,NOFUNCTION,NOCUSTOM %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 --check-prefixes CHECK,FUNCTION,NOCUSTOM %s
+// RUN: %clang_cc1 -fxray-instrument \
+// RUN:     -fxray-instrumentation-bundle=custom-only -x c++ \
+// RUN:     -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN:     | FileCheck --check-prefixes CHECK,NOFUNCTION,CUSTOM %s
+
+// CHECK: define void @_Z16alwaysInstrumentv() #[[ALWAYSATTR:[0-9]+]] {
+[[clang::xray_always_instrument]] void alwaysInstrument() {
+  static constexpr char kPhase[] = "always";
+  __xray_customevent(kPhase, 6);
+  // CUSTOM: call void @llvm.xray.customevent(i8*{{.*}}, i32 6)
+  // NOCUSTOM-NOT: call void @llvm.xray.customevent(i8*{{.*}}, i32 6)
+}
+
+// FUNCTION: attributes #[[ALWAYSATTR]] = {{.*}} "function-instrument"="xray-always" {{.*}}
+// NOFUNCTION-NOT: attributes #[[ALWAYSATTR]] = {{.*}} "function-instrument"="xray-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,18 @@
       Args.hasArg(OPT_finstrument_functions_after_inlining);
   Opts.InstrumentFunctionEntryBare =
       Args.hasArg(OPT_finstrument_function_entry_bare);
-  Opts.XRayInstrumentFunctions = Args.hasArg(OPT_fxray_instrument);
+
+  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.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/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -1846,9 +1846,23 @@
                                    StringRef Category) const {
   if (!LangOpts.XRayInstrument)
     return false;
+
+  // Here, check whether the codegen options say we shouldn't be instrumenting
+  // functions.
+  using XRayBundles = CodeGenOptions::XRayInstrumentationPointBundle;
+  auto Bundle = CodeGenOpts.getXRayInstrumentationBundle();
+  switch (Bundle) {
+    case XRayBundles::XRay_None:
+    case XRayBundles::XRay_CustomOnly:
+      return true;
+    case XRayBundles::XRay_Function:
+    case XRayBundles::XRay_All:
+      break;
+  }
+
   const auto &XRayFilter = getContext().getXRayFilter();
   using ImbueAttr = XRayFunctionFilter::ImbueAttribute;
-  auto Attr = XRayFunctionFilter::ImbueAttribute::NONE;
+  auto Attr = ImbueAttr::NONE;
   if (Loc.isValid())
     Attr = XRayFilter.shouldImbueLocation(Loc, Category);
   if (Attr == ImbueAttr::NONE)
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -468,7 +468,10 @@
 /// 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 ||
+          CGM.getCodeGenOpts().getXRayInstrumentationBundle() ==
+              CodeGenOptions::XRayInstrumentationPointBundle::XRay_CustomOnly);
 }
 
 llvm::Constant *
@@ -894,20 +897,30 @@
   // Apply xray attributes to the function (as a string, for now)
   bool InstrumentXray = ShouldXRayInstrumentFunction();
   if (D && InstrumentXray) {
-    if (const auto *XRayAttr = D->getAttr<XRayInstrumentAttr>()) {
-      if (XRayAttr->alwaysXRayInstrument())
-        Fn->addFnAttr("function-instrument", "xray-always");
-      if (XRayAttr->neverXRayInstrument())
-        Fn->addFnAttr("function-instrument", "xray-never");
-      if (const auto *LogArgs = D->getAttr<XRayLogArgsAttr>()) {
-        Fn->addFnAttr("xray-log-args",
-                      llvm::utostr(LogArgs->getArgumentCount()));
+    using XRayBundles = CodeGenOptions::XRayInstrumentationPointBundle;
+    auto Bundle = CGM.getCodeGenOpts().getXRayInstrumentationBundle();
+    switch (Bundle) {
+    case XRayBundles::XRay_All:
+    case XRayBundles::XRay_Function:
+      if (const auto *XRayAttr = D->getAttr<XRayInstrumentAttr>()) {
+        if (XRayAttr->alwaysXRayInstrument())
+          Fn->addFnAttr("function-instrument", "xray-always");
+        if (XRayAttr->neverXRayInstrument())
+          Fn->addFnAttr("function-instrument", "xray-never");
+        if (const auto *LogArgs = D->getAttr<XRayLogArgsAttr>()) {
+          Fn->addFnAttr("xray-log-args",
+                        llvm::utostr(LogArgs->getArgumentCount()));
+        }
+      } else {
+        if (!CGM.imbueXRayAttrs(Fn, Loc))
+          Fn->addFnAttr(
+              "xray-instruction-threshold",
+              llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));
       }
-    } else {
-      if (!CGM.imbueXRayAttrs(Fn, Loc))
-        Fn->addFnAttr(
-            "xray-instruction-threshold",
-            llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));
+      break;
+    case XRayBundles::XRay_None:
+    case XRayBundles::XRay_CustomOnly:
+      break;
     }
   }
 
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -3241,9 +3241,23 @@
   case Builtin::BI__xray_customevent: {
     if (!ShouldXRayInstrumentFunction())
       return RValue::getIgnored();
-    if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>())
-      if (XRayAttr->neverXRayInstrument() && !AlwaysEmitXRayCustomEvents())
+
+    using XRayBundles = CodeGenOptions::XRayInstrumentationPointBundle;
+    auto Bundle = CGM.getCodeGenOpts().getXRayInstrumentationBundle();
+    switch (Bundle) {
+      case XRayBundles::XRay_None:
+      case XRayBundles::XRay_Function:
         return RValue::getIgnored();
+      case XRayBundles::XRay_All:
+        if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>())
+          if (XRayAttr->neverXRayInstrument() && !AlwaysEmitXRayCustomEvents())
+            return RValue::getIgnored();
+        LLVM_FALLTHROUGH;
+      case XRayBundles::XRay_CustomOnly:
+        break;
+    }
+    assert(Bundle == XRayBundles::XRay_All ||
+           Bundle == XRayBundles::XRay_CustomOnly);
 
     Function *F = CGM.getIntrinsic(Intrinsic::xray_customevent);
     auto FTy = F->getFunctionType();
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