diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Basic/CMakeLists.txt | 1 | ||||
-rw-r--r-- | clang/lib/Basic/XRayInstr.cpp | 29 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGBuiltin.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 9 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Driver/XRayArgs.cpp | 35 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 36 |
7 files changed, 110 insertions, 8 deletions
diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt index 823b908184c..2e394916b52 100644 --- a/clang/lib/Basic/CMakeLists.txt +++ b/clang/lib/Basic/CMakeLists.txt @@ -96,6 +96,7 @@ add_clang_library(clangBasic VersionTuple.cpp VirtualFileSystem.cpp Warnings.cpp + XRayInstr.cpp XRayLists.cpp ${version_inc} ) diff --git a/clang/lib/Basic/XRayInstr.cpp b/clang/lib/Basic/XRayInstr.cpp new file mode 100644 index 00000000000..42f9038890a --- /dev/null +++ b/clang/lib/Basic/XRayInstr.cpp @@ -0,0 +1,29 @@ +//===--- XRayInstr.cpp ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is part of XRay, a function call instrumentation system. +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/XRayInstr.h" +#include "llvm/ADT/StringSwitch.h" + +namespace clang { + +XRayInstrMask parseXRayInstrValue(StringRef Value) { + XRayInstrMask ParsedKind = llvm::StringSwitch<XRayInstrMask>(Value) + .Case("all", XRayInstrKind::All) + .Case("custom", XRayInstrKind::Custom) + .Case("function", XRayInstrKind::Function) + .Case("none", XRayInstrKind::None) + .Default(XRayInstrKind::None); + return ParsedKind; +} + +} // namespace clang diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 73b95d981f4..4baa5aff72e 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -3341,6 +3341,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, case Builtin::BI__xray_customevent: { if (!ShouldXRayInstrumentFunction()) return RValue::getIgnored(); + + if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has( + XRayInstrKind::Custom)) + return RValue::getIgnored(); + if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>()) if (XRayAttr->neverXRayInstrument() && !AlwaysEmitXRayCustomEvents()) return RValue::getIgnored(); diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 57b1c4b4db1..5367c2addec 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -468,7 +468,10 @@ bool CodeGenFunction::ShouldXRayInstrumentFunction() const { /// 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().XRayInstrumentationBundle.Mask == + XRayInstrKind::Custom); } llvm::Constant * @@ -900,7 +903,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, } // Apply xray attributes to the function (as a string, for now) - bool InstrumentXray = ShouldXRayInstrumentFunction(); + bool InstrumentXray = ShouldXRayInstrumentFunction() && + CGM.getCodeGenOpts().XRayInstrumentationBundle.has( + XRayInstrKind::Function); if (D && InstrumentXray) { if (const auto *XRayAttr = D->getAttr<XRayInstrumentAttr>()) { if (XRayAttr->alwaysXRayInstrument()) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index c3de87021f5..701412f4f10 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1846,9 +1846,10 @@ 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; + auto Attr = ImbueAttr::NONE; if (Loc.isValid()) Attr = XRayFilter.shouldImbueLocation(Loc, Category); if (Attr == ImbueAttr::NONE) diff --git a/clang/lib/Driver/XRayArgs.cpp b/clang/lib/Driver/XRayArgs.cpp index bfc5053dcdc..e25259ca6d6 100644 --- a/clang/lib/Driver/XRayArgs.cpp +++ b/clang/lib/Driver/XRayArgs.cpp @@ -58,8 +58,7 @@ XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) { } } else { D.Diag(diag::err_drv_clang_unsupported) - << (std::string(XRayInstrumentOption) + - " on non-supported target OS"); + << (std::string(XRayInstrumentOption) + " on " + Triple.str()); } XRayInstrument = true; if (const Arg *A = @@ -82,6 +81,36 @@ XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) { options::OPT_fnoxray_link_deps, true)) XRayRT = false; + auto Bundles = + Args.getAllArgValues(options::OPT_fxray_instrumentation_bundle); + if (Bundles.empty()) + InstrumentationBundle.Mask = XRayInstrKind::All; + else + for (const auto &B : Bundles) { + llvm::SmallVector<StringRef, 2> BundleParts; + llvm::SplitString(B, BundleParts, ","); + for (const auto &P : BundleParts) { + // TODO: Automate the generation of the string case table. + auto Valid = llvm::StringSwitch<bool>(P) + .Cases("none", "all", "function", "custom", true) + .Default(false); + + if (!Valid) { + D.Diag(clang::diag::err_drv_invalid_value) + << "-fxray-instrumentation-bundle=" << P; + continue; + } + + auto Mask = parseXRayInstrValue(P); + if (Mask == XRayInstrKind::None) { + InstrumentationBundle.clear(); + break; + } + + InstrumentationBundle.Mask |= Mask; + } + } + // Validate the always/never attribute files. We also make sure that they // are treated as actual dependencies. for (const auto &Filename : @@ -165,7 +194,7 @@ void XRayArgs::addArgs(const ToolChain &TC, const ArgList &Args, CmdArgs.push_back(Args.MakeArgString(NeverInstrumentOpt)); } - for (const auto& AttrFile : AttrListFiles) { + for (const auto &AttrFile : AttrListFiles) { SmallString<64> AttrListFileOpt("-fxray-attr-list="); AttrListFileOpt += AttrFile; CmdArgs.push_back(Args.MakeArgString(AttrListFileOpt)); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 52603466e7e..147657f62fc 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -26,6 +26,7 @@ #include "clang/Basic/VersionTuple.h" #include "clang/Basic/VirtualFileSystem.h" #include "clang/Basic/Visibility.h" +#include "clang/Basic/XRayInstr.h" #include "clang/Config/config.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" @@ -75,9 +76,9 @@ #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/Regex.h" +#include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Support/ScopedPrinter.h" #include <algorithm> #include <atomic> #include <cassert> @@ -446,6 +447,25 @@ static void parseSanitizerKinds(StringRef FlagName, } } +static void parseXRayInstrumentationBundle(StringRef FlagName, StringRef Bundle, + ArgList &Args, DiagnosticsEngine &D, + XRayInstrSet &S) { + llvm::SmallVector<StringRef, 2> BundleParts; + llvm::SplitString(Bundle, BundleParts, ","); + for (const auto B : BundleParts) { + auto Mask = parseXRayInstrValue(B); + if (Mask == XRayInstrKind::None) + if (B != "none") + D.Report(diag::err_drv_invalid_value) << FlagName << Bundle; + else + S.Mask = Mask; + else if (Mask == XRayInstrKind::All) + S.Mask = Mask; + else + S.set(Mask, true); + } +} + // Set the profile kind for fprofile-instrument. static void setPGOInstrumentor(CodeGenOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags) { @@ -820,11 +840,23 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, 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); + + auto XRayInstrBundles = + Args.getAllArgValues(OPT_fxray_instrumentation_bundle); + if (XRayInstrBundles.empty()) + Opts.XRayInstrumentationBundle.Mask = XRayInstrKind::All; + else + for (const auto &A : XRayInstrBundles) + parseXRayInstrumentationBundle("-fxray-instrumentation-bundle=", A, Args, + Diags, Opts.XRayInstrumentationBundle); + Opts.InstrumentForProfiling = Args.hasArg(OPT_pg); Opts.CallFEntry = Args.hasArg(OPT_mfentry); Opts.EmitOpenCLArgMetadata = Args.hasArg(OPT_cl_kernel_arg_info); |