diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Driver/XRayArgs.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Driver/XRayArgs.cpp | 298 |
1 files changed, 158 insertions, 140 deletions
diff --git a/contrib/llvm-project/clang/lib/Driver/XRayArgs.cpp b/contrib/llvm-project/clang/lib/Driver/XRayArgs.cpp index a2dd63f9eb77..f00c3906df97 100644 --- a/contrib/llvm-project/clang/lib/Driver/XRayArgs.cpp +++ b/contrib/llvm-project/clang/lib/Driver/XRayArgs.cpp @@ -13,10 +13,10 @@ #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/ScopedPrinter.h" #include "llvm/Support/SpecialCaseList.h" +#include "llvm/Support/VirtualFileSystem.h" using namespace clang; using namespace clang::driver; @@ -32,157 +32,163 @@ constexpr const char *const XRaySupportedModes[] = {"xray-fdr", "xray-basic"}; 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 if (Triple.isOSFreeBSD() || - Triple.isOSOpenBSD() || - Triple.isOSNetBSD() || - Triple.isMacOSX()) { - if (Triple.getArch() != llvm::Triple::x86_64) { - D.Diag(diag::err_drv_clang_unsupported) - << (std::string(XRayInstrumentOption) + " on " + Triple.str()); - } - } else if (Triple.getOS() == llvm::Triple::Fuchsia) { - switch (Triple.getArch()) { - case llvm::Triple::x86_64: - case llvm::Triple::aarch64: - break; - default: - D.Diag(diag::err_drv_clang_unsupported) - << (std::string(XRayInstrumentOption) + " on " + Triple.str()); - } - } else { + if (!Args.hasFlag(options::OPT_fxray_instrument, + options::OPT_fno_xray_instrument, false)) + return; + 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()); } - - // Both XRay and -fpatchable-function-entry use - // TargetOpcode::PATCHABLE_FUNCTION_ENTER. - if (Arg *A = Args.getLastArg(options::OPT_fpatchable_function_entry_EQ)) - D.Diag(diag::err_drv_argument_not_allowed_with) - << "-fxray-instrument" << A->getSpelling(); - - 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; + } else if (Triple.isOSFreeBSD() || Triple.isOSOpenBSD() || + Triple.isOSNetBSD() || Triple.isMacOSX()) { + if (Triple.getArch() != llvm::Triple::x86_64) { + D.Diag(diag::err_drv_clang_unsupported) + << (std::string(XRayInstrumentOption) + " on " + Triple.str()); + } + } else if (Triple.getOS() == llvm::Triple::Fuchsia) { + switch (Triple.getArch()) { + case llvm::Triple::x86_64: + case llvm::Triple::aarch64: + 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 " + Triple.str()); + } + + // Both XRay and -fpatchable-function-entry use + // TargetOpcode::PATCHABLE_FUNCTION_ENTER. + if (Arg *A = Args.getLastArg(options::OPT_fpatchable_function_entry_EQ)) + D.Diag(diag::err_drv_argument_not_allowed_with) + << "-fxray-instrument" << A->getSpelling(); + + 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; + } + + // By default, the back-end will not emit the lowering for XRay customevent + // calls if the function is not instrumented. In the future we will change + // this default to be the reverse, but in the meantime we're going to + // introduce the new functionality behind a flag. + if (Args.hasFlag(options::OPT_fxray_always_emit_customevents, + options::OPT_fno_xray_always_emit_customevents, false)) + XRayAlwaysEmitCustomEvents = true; + + if (Args.hasFlag(options::OPT_fxray_always_emit_typedevents, + options::OPT_fno_xray_always_emit_typedevents, false)) + XRayAlwaysEmitTypedEvents = true; + + if (!Args.hasFlag(options::OPT_fxray_link_deps, + options::OPT_fnoxray_link_deps, true)) + XRayRT = false; - // By default, the back-end will not emit the lowering for XRay customevent - // calls if the function is not instrumented. In the future we will change - // this default to be the reverse, but in the meantime we're going to - // introduce the new functionality behind a flag. - if (Args.hasFlag(options::OPT_fxray_always_emit_customevents, - options::OPT_fnoxray_always_emit_customevents, false)) - XRayAlwaysEmitCustomEvents = true; - - if (Args.hasFlag(options::OPT_fxray_always_emit_typedevents, - options::OPT_fnoxray_always_emit_typedevents, false)) - XRayAlwaysEmitTypedEvents = true; - - if (!Args.hasFlag(options::OPT_fxray_link_deps, - 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; + if (Args.hasFlag(options::OPT_fxray_ignore_loops, + options::OPT_fno_xray_ignore_loops, false)) + XRayIgnoreLoops = true; + + XRayFunctionIndex = Args.hasFlag(options::OPT_fxray_function_index, + options::OPT_fno_xray_function_index, true); + + 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", "function-entry", + "function-exit", "custom", true) + .Default(false); + + if (!Valid) { + D.Diag(clang::diag::err_drv_invalid_value) + << "-fxray-instrumentation-bundle=" << P; + continue; } - } - // 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 (D.getVFS().exists(Filename)) { - AlwaysInstrumentFiles.push_back(Filename); - ExtraDeps.push_back(Filename); - } else - D.Diag(clang::diag::err_drv_no_such_file) << Filename; - } + auto Mask = parseXRayInstrValue(P); + if (Mask == XRayInstrKind::None) { + InstrumentationBundle.clear(); + break; + } - for (const auto &Filename : - Args.getAllArgValues(options::OPT_fxray_never_instrument)) { - if (D.getVFS().exists(Filename)) { - NeverInstrumentFiles.push_back(Filename); - ExtraDeps.push_back(Filename); - } else - D.Diag(clang::diag::err_drv_no_such_file) << Filename; + InstrumentationBundle.Mask |= Mask; + } } - for (const auto &Filename : - Args.getAllArgValues(options::OPT_fxray_attr_list)) { - if (D.getVFS().exists(Filename)) { - AttrListFiles.push_back(Filename); - ExtraDeps.push_back(Filename); - } else - D.Diag(clang::diag::err_drv_no_such_file) << Filename; - } + // 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 (D.getVFS().exists(Filename)) { + AlwaysInstrumentFiles.push_back(Filename); + ExtraDeps.push_back(Filename); + } else + D.Diag(clang::diag::err_drv_no_such_file) << Filename; + } - // Get the list of modes we want to support. - auto SpecifiedModes = Args.getAllArgValues(options::OPT_fxray_modes); - if (SpecifiedModes.empty()) - llvm::copy(XRaySupportedModes, std::back_inserter(Modes)); - else - for (const auto &Arg : SpecifiedModes) { - // Parse CSV values for -fxray-modes=... - llvm::SmallVector<StringRef, 2> ModeParts; - llvm::SplitString(Arg, ModeParts, ","); - for (const auto &M : ModeParts) - if (M == "none") - Modes.clear(); - else if (M == "all") - llvm::copy(XRaySupportedModes, std::back_inserter(Modes)); - else - Modes.push_back(M); - } + for (const auto &Filename : + Args.getAllArgValues(options::OPT_fxray_never_instrument)) { + if (D.getVFS().exists(Filename)) { + NeverInstrumentFiles.push_back(Filename); + ExtraDeps.push_back(Filename); + } else + D.Diag(clang::diag::err_drv_no_such_file) << Filename; + } - // Then we want to sort and unique the modes we've collected. - llvm::sort(Modes); - Modes.erase(std::unique(Modes.begin(), Modes.end()), Modes.end()); + for (const auto &Filename : + Args.getAllArgValues(options::OPT_fxray_attr_list)) { + if (D.getVFS().exists(Filename)) { + AttrListFiles.push_back(Filename); + ExtraDeps.push_back(Filename); + } else + D.Diag(clang::diag::err_drv_no_such_file) << Filename; } + + // Get the list of modes we want to support. + auto SpecifiedModes = Args.getAllArgValues(options::OPT_fxray_modes); + if (SpecifiedModes.empty()) + llvm::copy(XRaySupportedModes, std::back_inserter(Modes)); + else + for (const auto &Arg : SpecifiedModes) { + // Parse CSV values for -fxray-modes=... + llvm::SmallVector<StringRef, 2> ModeParts; + llvm::SplitString(Arg, ModeParts, ","); + for (const auto &M : ModeParts) + if (M == "none") + Modes.clear(); + else if (M == "all") + llvm::copy(XRaySupportedModes, std::back_inserter(Modes)); + else + Modes.push_back(std::string(M)); + } + + // Then we want to sort and unique the modes we've collected. + llvm::sort(Modes); + Modes.erase(std::unique(Modes.begin(), Modes.end()), Modes.end()); } void XRayArgs::addArgs(const ToolChain &TC, const ArgList &Args, @@ -198,6 +204,12 @@ void XRayArgs::addArgs(const ToolChain &TC, const ArgList &Args, if (XRayAlwaysEmitTypedEvents) CmdArgs.push_back("-fxray-always-emit-typedevents"); + if (XRayIgnoreLoops) + CmdArgs.push_back("-fxray-ignore-loops"); + + if (!XRayFunctionIndex) + CmdArgs.push_back("-fno-xray-function-index"); + CmdArgs.push_back(Args.MakeArgString(Twine(XRayInstructionThresholdOption) + Twine(InstructionThreshold))); @@ -237,8 +249,14 @@ void XRayArgs::addArgs(const ToolChain &TC, const ArgList &Args, } else if (InstrumentationBundle.empty()) { Bundle += "none"; } else { - if (InstrumentationBundle.has(XRayInstrKind::Function)) + if (InstrumentationBundle.has(XRayInstrKind::FunctionEntry) && + InstrumentationBundle.has(XRayInstrKind::FunctionExit)) Bundle += "function"; + else if (InstrumentationBundle.has(XRayInstrKind::FunctionEntry)) + Bundle += "function-entry"; + else if (InstrumentationBundle.has(XRayInstrKind::FunctionExit)) + Bundle += "function-exit"; + if (InstrumentationBundle.has(XRayInstrKind::Custom)) Bundle += "custom"; if (InstrumentationBundle.has(XRayInstrKind::Typed)) |