r299041 - [XRay] Add -fxray-{always, never}-instrument= flags to clang

Dean Michael Berris via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 29 17:29:36 PDT 2017


Author: dberris
Date: Wed Mar 29 19:29:36 2017
New Revision: 299041

URL: http://llvm.org/viewvc/llvm-project?rev=299041&view=rev
Log:
[XRay] Add -fxray-{always,never}-instrument= flags to clang

Summary:
The -fxray-always-instrument= and -fxray-never-instrument= flags take
filenames that are used to imbue the XRay instrumentation attributes
using a whitelist mechanism (similar to the sanitizer special cases
list). We use the same syntax and semantics as the sanitizer blacklists
files in the implementation.

As implemented, we respect the attributes that are already defined in
the source file (i.e. those that have the
[[clang::xray_{always,never}_instrument]] attributes) before applying
the always/never instrument lists.

Reviewers: rsmith, chandlerc

Subscribers: jfb, mgorny, cfe-commits

Differential Revision: https://reviews.llvm.org/D30388

Added:
    cfe/trunk/include/clang/Basic/XRayLists.h
    cfe/trunk/include/clang/Driver/XRayArgs.h
    cfe/trunk/lib/Basic/XRayLists.cpp
    cfe/trunk/lib/Driver/XRayArgs.cpp
    cfe/trunk/test/CodeGen/xray-always-instrument.cpp
Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/Basic/LangOptions.def
    cfe/trunk/include/clang/Basic/LangOptions.h
    cfe/trunk/include/clang/Driver/Options.td
    cfe/trunk/include/clang/Driver/ToolChain.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/Basic/CMakeLists.txt
    cfe/trunk/lib/Basic/LangOptions.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/lib/Driver/CMakeLists.txt
    cfe/trunk/lib/Driver/ToolChain.cpp
    cfe/trunk/lib/Driver/ToolChains/Clang.cpp
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=299041&r1=299040&r2=299041&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Wed Mar 29 19:29:36 2017
@@ -39,6 +39,7 @@
 #include "clang/Basic/SanitizerBlacklist.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/Specifiers.h"
+#include "clang/Basic/XRayLists.h"
 #include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
@@ -475,6 +476,10 @@ private:
   /// entities should not be instrumented.
   std::unique_ptr<SanitizerBlacklist> SanitizerBL;
 
+  /// \breif Function filtering mehcanism to determine whether a given function
+  /// should be imbued with the XRay "always" or "never" attributes.
+  std::unique_ptr<XRayFunctionFilter> XRayFilter;
+
   /// \brief The allocator used to create AST objects.
   ///
   /// AST objects are never destructed; rather, all memory associated with the
@@ -657,6 +662,10 @@ public:
     return *SanitizerBL;
   }
 
+  const XRayFunctionFilter &getXRayFilter() const {
+    return *XRayFilter;
+  }
+
   DiagnosticsEngine &getDiagnostics() const;
 
   FullSourceLoc getFullLoc(SourceLocation Loc) const {

Modified: cfe/trunk/include/clang/Basic/LangOptions.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.def?rev=299041&r1=299040&r2=299041&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/LangOptions.def (original)
+++ cfe/trunk/include/clang/Basic/LangOptions.def Wed Mar 29 19:29:36 2017
@@ -263,6 +263,8 @@ LANGOPT(SanitizeAddressFieldPadding, 2,
                                            "field padding (0: none, 1:least "
                                            "aggressive, 2: more aggressive)")
 
+LANGOPT(XRayInstrument, 1, 0, "controls whether to do XRay instrumentation")
+
 #undef LANGOPT
 #undef COMPATIBLE_LANGOPT
 #undef BENIGN_LANGOPT

Modified: cfe/trunk/include/clang/Basic/LangOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.h?rev=299041&r1=299040&r2=299041&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/LangOptions.h (original)
+++ cfe/trunk/include/clang/Basic/LangOptions.h Wed Mar 29 19:29:36 2017
@@ -102,6 +102,16 @@ public:
   /// (files, functions, variables) should not be instrumented.
   std::vector<std::string> SanitizerBlacklistFiles;
 
+  /// \brief Paths to the XRay "always instrument" files specifying which
+  /// objects (files, functions, variables) should be imbued with the XRay
+  /// "always instrument" attribute.
+  std::vector<std::string> XRayAlwaysInstrumentFiles;
+
+  /// \brief Paths to the XRay "never instrument" files specifying which
+  /// objects (files, functions, variables) should be imbued with the XRay
+  /// "never instrument" attribute.
+  std::vector<std::string> XRayNeverInstrumentFiles;
+
   clang::ObjCRuntime ObjCRuntime;
 
   std::string ObjCConstantStringClass;

Added: cfe/trunk/include/clang/Basic/XRayLists.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/XRayLists.h?rev=299041&view=auto
==============================================================================
--- cfe/trunk/include/clang/Basic/XRayLists.h (added)
+++ cfe/trunk/include/clang/Basic/XRayLists.h Wed Mar 29 19:29:36 2017
@@ -0,0 +1,54 @@
+//===--- XRayLists.h - XRay automatic attribution ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// User-provided filters for always/never XRay instrumenting certain functions.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_BASIC_XRAYLISTS_H
+#define LLVM_CLANG_BASIC_XRAYLISTS_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/SpecialCaseList.h"
+#include <memory>
+
+namespace clang {
+
+class XRayFunctionFilter {
+  std::unique_ptr<llvm::SpecialCaseList> AlwaysInstrument;
+  std::unique_ptr<llvm::SpecialCaseList> NeverInstrument;
+  SourceManager &SM;
+
+public:
+  XRayFunctionFilter(ArrayRef<std::string> AlwaysInstrumentPaths,
+                     ArrayRef<std::string> NeverInstrumentPaths,
+                     SourceManager &SM);
+
+  enum class ImbueAttribute {
+    NONE,
+    ALWAYS,
+    NEVER,
+  };
+
+  ImbueAttribute shouldImbueFunction(StringRef FunctionName) const;
+
+  ImbueAttribute
+  shouldImbueFunctionsInFile(StringRef Filename,
+                             StringRef Category = StringRef()) const;
+
+  ImbueAttribute shouldImbueLocation(SourceLocation Loc,
+                                     StringRef Category = StringRef()) const;
+};
+
+} // namespace clang
+
+#endif

Modified: cfe/trunk/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=299041&r1=299040&r2=299041&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Wed Mar 29 19:29:36 2017
@@ -962,6 +962,15 @@ def fxray_instruction_threshold_ :
   JoinedOrSeparate<["-"], "fxray-instruction-threshold">,
   Group<f_Group>, Flags<[CC1Option]>;
 
+def fxray_always_instrument :
+  JoinedOrSeparate<["-"], "fxray-always-instrument=">,
+  Group<f_Group>, Flags<[CC1Option]>,
+  HelpText<"Filename defining the whitelist for imbuing the 'always instrument' XRay attribute.">;
+def fxray_never_instrument :
+  JoinedOrSeparate<["-"], "fxray-never-instrument=">,
+  Group<f_Group>, Flags<[CC1Option]>,
+  HelpText<"Filename defining the whitelist for imbuing the 'never instrument' XRay attribute.">;
+
 def flat__namespace : Flag<["-"], "flat_namespace">;
 def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group<f_Group>;
 def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group<f_Group>;

Modified: cfe/trunk/include/clang/Driver/ToolChain.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/ToolChain.h?rev=299041&r1=299040&r2=299041&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/ToolChain.h (original)
+++ cfe/trunk/include/clang/Driver/ToolChain.h Wed Mar 29 19:29:36 2017
@@ -44,6 +44,7 @@ namespace driver {
   class RegisterEffectiveTriple;
   class SanitizerArgs;
   class Tool;
+  class XRayArgs;
 
 /// ToolChain - Access to tools for a single platform.
 class ToolChain {
@@ -94,6 +95,7 @@ private:
   Tool *getOffloadBundler() const;
 
   mutable std::unique_ptr<SanitizerArgs> SanitizerArguments;
+  mutable std::unique_ptr<XRayArgs> XRayArguments;
 
   /// The effective clang triple for the current Job.
   mutable llvm::Triple EffectiveTriple;
@@ -177,6 +179,8 @@ public:
 
   const SanitizerArgs& getSanitizerArgs() const;
 
+  const XRayArgs& getXRayArgs() const;
+
   // Returns the Arg * that explicitly turned on/off rtti, or nullptr.
   const llvm::opt::Arg *getRTTIArg() const { return CachedRTTIArg; }
 

Added: cfe/trunk/include/clang/Driver/XRayArgs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/XRayArgs.h?rev=299041&view=auto
==============================================================================
--- cfe/trunk/include/clang/Driver/XRayArgs.h (added)
+++ cfe/trunk/include/clang/Driver/XRayArgs.h Wed Mar 29 19:29:36 2017
@@ -0,0 +1,38 @@
+//===--- XRayArgs.h - Arguments for XRay ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_DRIVER_XRAYARGS_H
+#define LLVM_CLANG_DRIVER_XRAYARGS_H
+
+#include "clang/Driver/Types.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+
+namespace clang {
+namespace driver {
+
+class ToolChain;
+
+class XRayArgs {
+  std::vector<std::string> AlwaysInstrumentFiles;
+  std::vector<std::string> NeverInstrumentFiles;
+  std::vector<std::string> ExtraDeps;
+  bool XRayInstrument = false;
+  int InstructionThreshold = 200;
+
+public:
+  /// Parses the XRay arguments from an argument list.
+  XRayArgs(const ToolChain &TC, const llvm::opt::ArgList &Args);
+  void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
+               llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const;
+};
+
+} // namespace driver
+} // namespace clang
+
+#endif // LLVM_CLANG_DRIVER_XRAYARGS_H

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=299041&r1=299040&r2=299041&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Mar 29 19:29:36 2017
@@ -748,6 +748,8 @@ ASTContext::ASTContext(LangOptions &LOpt
       ExternCContext(nullptr), MakeIntegerSeqDecl(nullptr),
       TypePackElementDecl(nullptr), SourceMgr(SM), LangOpts(LOpts),
       SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)),
+      XRayFilter(new XRayFunctionFilter(LangOpts.XRayAlwaysInstrumentFiles,
+                                        LangOpts.XRayNeverInstrumentFiles, SM)),
       AddrSpaceMap(nullptr), Target(nullptr), AuxTarget(nullptr),
       PrintingPolicy(LOpts), Idents(idents), Selectors(sels),
       BuiltinInfo(builtins), DeclarationNames(*this), ExternalSource(nullptr),

Modified: cfe/trunk/lib/Basic/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/CMakeLists.txt?rev=299041&r1=299040&r2=299041&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/CMakeLists.txt (original)
+++ cfe/trunk/lib/Basic/CMakeLists.txt Wed Mar 29 19:29:36 2017
@@ -90,6 +90,7 @@ add_clang_library(clangBasic
   VersionTuple.cpp
   VirtualFileSystem.cpp
   Warnings.cpp
+  XRayLists.cpp
   ${version_inc}
   )
 

Modified: cfe/trunk/lib/Basic/LangOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/LangOptions.cpp?rev=299041&r1=299040&r2=299041&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/LangOptions.cpp (original)
+++ cfe/trunk/lib/Basic/LangOptions.cpp Wed Mar 29 19:29:36 2017
@@ -33,6 +33,8 @@ void LangOptions::resetNonModularOptions
   // sanitizer options (this affects __has_feature(address_sanitizer) etc).
   Sanitize.clear();
   SanitizerBlacklistFiles.clear();
+  XRayAlwaysInstrumentFiles.clear();
+  XRayNeverInstrumentFiles.clear();
 
   CurrentModule.clear();
   IsHeaderFile = false;

Added: cfe/trunk/lib/Basic/XRayLists.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/XRayLists.cpp?rev=299041&view=auto
==============================================================================
--- cfe/trunk/lib/Basic/XRayLists.cpp (added)
+++ cfe/trunk/lib/Basic/XRayLists.cpp Wed Mar 29 19:29:36 2017
@@ -0,0 +1,53 @@
+//===--- XRayFunctionFilter.cpp - XRay automatic-attribution --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// User-provided filters for always/never XRay instrumenting certain functions.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Basic/XRayLists.h"
+
+using namespace clang;
+
+XRayFunctionFilter::XRayFunctionFilter(
+    ArrayRef<std::string> AlwaysInstrumentPaths,
+    ArrayRef<std::string> NeverInstrumentPaths, SourceManager &SM)
+    : AlwaysInstrument(
+          llvm::SpecialCaseList::createOrDie(AlwaysInstrumentPaths)),
+      NeverInstrument(llvm::SpecialCaseList::createOrDie(NeverInstrumentPaths)),
+      SM(SM) {}
+
+XRayFunctionFilter::ImbueAttribute
+XRayFunctionFilter::shouldImbueFunction(StringRef FunctionName) const {
+  // First apply the always instrument list, than if it isn't an "always" see
+  // whether it's treated as a "never" instrument function.
+  if (AlwaysInstrument->inSection("fun", FunctionName))
+    return ImbueAttribute::ALWAYS;
+  if (NeverInstrument->inSection("fun", FunctionName))
+    return ImbueAttribute::NEVER;
+  return ImbueAttribute::NONE;
+}
+
+XRayFunctionFilter::ImbueAttribute
+XRayFunctionFilter::shouldImbueFunctionsInFile(StringRef Filename,
+                                               StringRef Category) const {
+  if (AlwaysInstrument->inSection("src", Filename, Category))
+    return ImbueAttribute::ALWAYS;
+  if (NeverInstrument->inSection("src", Filename, Category))
+    return ImbueAttribute::NEVER;
+  return ImbueAttribute::NONE;
+}
+
+XRayFunctionFilter::ImbueAttribute
+XRayFunctionFilter::shouldImbueLocation(SourceLocation Loc,
+                                        StringRef Category) const {
+  if (!Loc.isValid())
+    return ImbueAttribute::NONE;
+  return this->shouldImbueFunctionsInFile(SM.getFilename(SM.getFileLoc(Loc)),
+                                          Category);
+}

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=299041&r1=299040&r2=299041&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Wed Mar 29 19:29:36 2017
@@ -786,9 +786,10 @@ void CodeGenFunction::StartFunction(Glob
                       llvm::utostr(LogArgs->getArgumentCount()));
       }
     } else {
-      Fn->addFnAttr(
-          "xray-instruction-threshold",
-          llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));
+      if (!CGM.imbueXRayAttrs(Fn, Loc))
+        Fn->addFnAttr(
+            "xray-instruction-threshold",
+            llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold));
     }
   }
 

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=299041&r1=299040&r2=299041&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Mar 29 19:29:36 2017
@@ -1489,6 +1489,30 @@ bool CodeGenModule::isInSanitizerBlackli
   return false;
 }
 
+bool CodeGenModule::imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc,
+                                   StringRef Category) const {
+  if (!LangOpts.XRayInstrument)
+    return false;
+  const auto &XRayFilter = getContext().getXRayFilter();
+  using ImbueAttr = XRayFunctionFilter::ImbueAttribute;
+  auto Attr = XRayFunctionFilter::ImbueAttribute::NONE;
+  if (Loc.isValid())
+    Attr = XRayFilter.shouldImbueLocation(Loc, Category);
+  if (Attr == ImbueAttr::NONE)
+    Attr = XRayFilter.shouldImbueFunction(Fn->getName());
+  switch (Attr) {
+  case ImbueAttr::NONE:
+    return false;
+  case ImbueAttr::ALWAYS:
+    Fn->addFnAttr("function-instrument", "xray-always");
+    break;
+  case ImbueAttr::NEVER:
+    Fn->addFnAttr("function-instrument", "xray-never");
+    break;
+  }
+  return true;
+}
+
 bool CodeGenModule::MustBeEmitted(const ValueDecl *Global) {
   // Never defer when EmitAllDecls is specified.
   if (LangOpts.EmitAllDecls)

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=299041&r1=299040&r2=299041&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Wed Mar 29 19:29:36 2017
@@ -28,6 +28,7 @@
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/SanitizerBlacklist.h"
+#include "clang/Basic/XRayLists.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
@@ -1125,6 +1126,12 @@ public:
                               QualType Ty,
                               StringRef Category = StringRef()) const;
 
+  /// Imbue XRay attributes to a function, applying the always/never attribute
+  /// lists in the process. Returns true if we did imbue attributes this way,
+  /// false otherwise.
+  bool imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc,
+                      StringRef Category = StringRef()) const;
+
   SanitizerMetadata *getSanitizerMetadata() {
     return SanitizerMD.get();
   }

Modified: cfe/trunk/lib/Driver/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/CMakeLists.txt?rev=299041&r1=299040&r2=299041&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/CMakeLists.txt (original)
+++ cfe/trunk/lib/Driver/CMakeLists.txt Wed Mar 29 19:29:36 2017
@@ -58,6 +58,7 @@ add_clang_library(clangDriver
   ToolChains/WebAssembly.cpp
   ToolChains/XCore.cpp
   Types.cpp
+  XRayArgs.cpp
 
   DEPENDS
   ClangDriverOptions

Modified: cfe/trunk/lib/Driver/ToolChain.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChain.cpp?rev=299041&r1=299040&r2=299041&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChain.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChain.cpp Wed Mar 29 19:29:36 2017
@@ -19,6 +19,7 @@
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
 #include "clang/Driver/SanitizerArgs.h"
+#include "clang/Driver/XRayArgs.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
@@ -100,6 +101,12 @@ const SanitizerArgs& ToolChain::getSanit
   return *SanitizerArguments.get();
 }
 
+const XRayArgs& ToolChain::getXRayArgs() const {
+  if (!XRayArguments.get())
+    XRayArguments.reset(new XRayArgs(*this, Args));
+  return *XRayArguments.get();
+}
+
 namespace {
 struct DriverSuffix {
   const char *Suffix;

Modified: cfe/trunk/lib/Driver/ToolChains/Clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Clang.cpp?rev=299041&r1=299040&r2=299041&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains/Clang.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains/Clang.cpp Wed Mar 29 19:29:36 2017
@@ -27,6 +27,7 @@
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
 #include "clang/Driver/SanitizerArgs.h"
+#include "clang/Driver/XRayArgs.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/CodeGen.h"
@@ -2818,37 +2819,6 @@ void Clang::ConstructJob(Compilation &C,
 
   Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
 
-  if (Args.hasFlag(options::OPT_fxray_instrument,
-                   options::OPT_fnoxray_instrument, false)) {
-    const char *const XRayInstrumentOption = "-fxray-instrument";
-    if (Triple.getOS() == llvm::Triple::Linux)
-      switch (Triple.getArch()) {
-      case llvm::Triple::x86_64:
-      case llvm::Triple::arm:
-      case llvm::Triple::aarch64:
-      case llvm::Triple::ppc64le:
-      case llvm::Triple::mips:
-      case llvm::Triple::mipsel:
-      case llvm::Triple::mips64:
-      case llvm::Triple::mips64el:
-        // Supported.
-        break;
-      default:
-        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-Linux target OS");
-    CmdArgs.push_back(XRayInstrumentOption);
-    if (const Arg *A =
-            Args.getLastArg(options::OPT_fxray_instruction_threshold_,
-                            options::OPT_fxray_instruction_threshold_EQ)) {
-      CmdArgs.push_back("-fxray-instruction-threshold");
-      CmdArgs.push_back(A->getValue());
-    }
-  }
-
   addPGOAndCoverageFlags(C, D, Output, Args, CmdArgs);
 
   // Add runtime flag for PS4 when PGO or Coverage are enabled.
@@ -3238,6 +3208,9 @@ void Clang::ConstructJob(Compilation &C,
   const SanitizerArgs &Sanitize = getToolChain().getSanitizerArgs();
   Sanitize.addArgs(getToolChain(), Args, CmdArgs, InputType);
 
+  const XRayArgs &XRay = getToolChain().getXRayArgs();
+  XRay.addArgs(getToolChain(), Args, CmdArgs, InputType);
+
   if (getToolChain().SupportsProfiling())
     Args.AddLastArg(CmdArgs, options::OPT_pg);
 

Added: cfe/trunk/lib/Driver/XRayArgs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/XRayArgs.cpp?rev=299041&view=auto
==============================================================================
--- cfe/trunk/lib/Driver/XRayArgs.cpp (added)
+++ cfe/trunk/lib/Driver/XRayArgs.cpp Wed Mar 29 19:29:36 2017
@@ -0,0 +1,113 @@
+//===--- XRayArgs.cpp - Arguments for XRay --------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Driver/XRayArgs.h"
+#include "ToolChains/CommonArgs.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "clang/Driver/ToolChain.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/SpecialCaseList.h"
+
+using namespace clang;
+using namespace clang::driver;
+using namespace llvm::opt;
+
+namespace {
+constexpr char XRayInstrumentOption[] = "-fxray-instrument";
+constexpr char XRayInstructionThresholdOption[] =
+    "-fxray-instruction-threshold=";
+constexpr char XRayAlwaysInstrumentOption[] = "-fxray-always-instrument=";
+constexpr char XRayNeverInstrumentOption[] = "-fxray-never-instrument=";
+} // namespace
+
+XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) {
+  const Driver &D = TC.getDriver();
+  const llvm::Triple &Triple = TC.getTriple();
+  if (Args.hasFlag(options::OPT_fxray_instrument,
+                   options::OPT_fnoxray_instrument, false)) {
+    if (Triple.getOS() == llvm::Triple::Linux)
+      switch (Triple.getArch()) {
+      case llvm::Triple::x86_64:
+      case llvm::Triple::arm:
+      case llvm::Triple::aarch64:
+      case llvm::Triple::ppc64le:
+      case llvm::Triple::mips:
+      case llvm::Triple::mipsel:
+      case llvm::Triple::mips64:
+      case llvm::Triple::mips64el:
+        break;
+      default:
+        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-Linux target OS");
+    XRayInstrument = true;
+    if (const Arg *A =
+            Args.getLastArg(options::OPT_fxray_instruction_threshold_,
+                            options::OPT_fxray_instruction_threshold_EQ)) {
+      StringRef S = A->getValue();
+      if (S.getAsInteger(0, InstructionThreshold) || InstructionThreshold < 0)
+        D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
+    }
+
+    // Validate the always/never attribute files. We also make sure that they
+    // are treated as actual dependencies.
+    for (const auto &Filename :
+         Args.getAllArgValues(options::OPT_fxray_always_instrument)) {
+      if (llvm::sys::fs::exists(Filename)) {
+        AlwaysInstrumentFiles.push_back(Filename);
+        ExtraDeps.push_back(Filename);
+      } else
+        D.Diag(clang::diag::err_drv_no_such_file) << Filename;
+    }
+
+    for (const auto &Filename :
+         Args.getAllArgValues(options::OPT_fxray_never_instrument)) {
+      if (llvm::sys::fs::exists(Filename)) {
+        NeverInstrumentFiles.push_back(Filename);
+        ExtraDeps.push_back(Filename);
+      } else
+        D.Diag(clang::diag::err_drv_no_such_file) << Filename;
+    }
+  }
+}
+
+void XRayArgs::addArgs(const ToolChain &TC, const ArgList &Args,
+                       ArgStringList &CmdArgs, types::ID InputType) const {
+  if (!XRayInstrument)
+    return;
+
+  CmdArgs.push_back(XRayInstrumentOption);
+  CmdArgs.push_back(Args.MakeArgString(XRayInstructionThresholdOption +
+                                       std::to_string(InstructionThreshold)));
+
+  for (const auto &Always : AlwaysInstrumentFiles) {
+    SmallString<64> AlwaysInstrumentOpt(XRayAlwaysInstrumentOption);
+    AlwaysInstrumentOpt += Always;
+    CmdArgs.push_back(Args.MakeArgString(AlwaysInstrumentOpt));
+  }
+
+  for (const auto &Never : NeverInstrumentFiles) {
+    SmallString<64> NeverInstrumentOpt(XRayNeverInstrumentOption);
+    NeverInstrumentOpt += Never;
+    CmdArgs.push_back(Args.MakeArgString(NeverInstrumentOpt));
+  }
+
+  for (const auto &Dep : ExtraDeps) {
+    SmallString<64> ExtraDepOpt("-fdepfile-entry=");
+    ExtraDepOpt += Dep;
+    CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt));
+  }
+}

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=299041&r1=299040&r2=299041&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Wed Mar 29 19:29:36 2017
@@ -2307,6 +2307,14 @@ static void ParseLangArgs(LangOptions &O
   Opts.SanitizeAddressFieldPadding =
       getLastArgIntValue(Args, OPT_fsanitize_address_field_padding, 0, Diags);
   Opts.SanitizerBlacklistFiles = Args.getAllArgValues(OPT_fsanitize_blacklist);
+
+  // -fxray-{always,never}-instrument= filenames.
+  Opts.XRayInstrument =
+      Args.hasFlag(OPT_fxray_instrument, OPT_fnoxray_instrument, false);
+  Opts.XRayAlwaysInstrumentFiles =
+      Args.getAllArgValues(OPT_fxray_always_instrument);
+  Opts.XRayNeverInstrumentFiles =
+      Args.getAllArgValues(OPT_fxray_never_instrument);
 }
 
 static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,

Added: cfe/trunk/test/CodeGen/xray-always-instrument.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/xray-always-instrument.cpp?rev=299041&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/xray-always-instrument.cpp (added)
+++ cfe/trunk/test/CodeGen/xray-always-instrument.cpp Wed Mar 29 19:29:36 2017
@@ -0,0 +1,15 @@
+// RUN: echo "fun:*foo*" > %t.always-instrument
+// RUN: echo "src:*xray-always-instrument.cpp" >> %t.always-instrument
+// RUN: %clang_cc1 -fxray-instrument -x c++ -std=c++11 -fxray-always-instrument=%t.always-instrument -emit-llvm -o - %s -triple x86_64-unknown-linux-gnu | FileCheck %s
+
+void foo() {}
+
+[[clang::xray_never_instrument]] void bar() {}
+
+void baz() {}
+
+// CHECK: define void @_Z3foov() #[[ALWAYSATTR:[0-9]+]] {
+// CHECK: define void @_Z3barv() #[[NEVERATTR:[0-9]+]] {
+// CHECK: define void @_Z3bazv() #[[ALWAYSATTR:[0-9]+]] {
+// CHECK: attributes #[[ALWAYSATTR]] = {{.*}} "function-instrument"="xray-always" {{.*}}
+// CHECK: attributes #[[NEVERATTR]] = {{.*}} "function-instrument"="xray-never" {{.*}}




More information about the cfe-commits mailing list