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