summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/LangOptions.def3
-rw-r--r--clang/include/clang/Driver/Options.td6
-rw-r--r--clang/include/clang/Driver/XRayArgs.h1
-rw-r--r--clang/include/clang/Frontend/CodeGenOptions.def3
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp6
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp6
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h4
-rw-r--r--clang/lib/Driver/XRayArgs.cpp18
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp7
-rw-r--r--clang/test/CodeGen/xray-always-emit-customevent.cpp10
10 files changed, 57 insertions, 7 deletions
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 5388c695fd1..f1487d1a180 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -272,6 +272,9 @@ LANGOPT(SanitizeAddressFieldPadding, 2, 0, "controls how aggressive is ASan "
"aggressive, 2: more aggressive)")
LANGOPT(XRayInstrument, 1, 0, "controls whether to do XRay instrumentation")
+LANGOPT(XRayAlwaysEmitCustomEvents, 1, 0,
+ "controls whether to always emit intrinsic calls to "
+ "__xray_customevent(...) builtin.")
BENIGN_LANGOPT(AllowEditorPlaceholders, 1, 0,
"allow editor placeholders in source")
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 7082fd26774..d155d703a79 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1060,6 +1060,12 @@ def fxray_never_instrument :
Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Filename defining the whitelist for imbuing the 'never instrument' XRay attribute.">;
+def fxray_always_emit_customevents : Flag<["-"], "fxray-always-emit-customevents">, Group<f_Group>,
+ Flags<[CC1Option]>,
+ HelpText<"Determine whether to always emit __xray_customevent(...) calls even if the function it appears in is not always instrumented.">;
+def fnoxray_always_emit_customevents : Flag<["-"], "fno-xray-always-emit-customevents">, Group<f_Group>,
+ Flags<[CC1Option]>;
+
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.">;
diff --git a/clang/include/clang/Driver/XRayArgs.h b/clang/include/clang/Driver/XRayArgs.h
index 83210d100a1..e5b76162de8 100644
--- a/clang/include/clang/Driver/XRayArgs.h
+++ b/clang/include/clang/Driver/XRayArgs.h
@@ -24,6 +24,7 @@ class XRayArgs {
std::vector<std::string> ExtraDeps;
bool XRayInstrument = false;
int InstructionThreshold = 200;
+ bool XRayAlwaysEmitCustomEvents = false;
public:
/// Parses the XRay arguments from an argument list.
diff --git a/clang/include/clang/Frontend/CodeGenOptions.def b/clang/include/clang/Frontend/CodeGenOptions.def
index e55550554e3..9dbdaea001b 100644
--- a/clang/include/clang/Frontend/CodeGenOptions.def
+++ b/clang/include/clang/Frontend/CodeGenOptions.def
@@ -84,6 +84,9 @@ CODEGENOPT(InstrumentFunctionEntryBare , 1, 0) ///< Set when
CODEGENOPT(XRayInstrumentFunctions , 1, 0) ///< Set when -fxray-instrument is
///< enabled.
+///< Set when -fxray-always-emit-customevents is enabled.
+CODEGENOPT(XRayAlwaysEmitCustomEvents , 1, 0)
+
///< Set the minimum number of instructions in a function to determine selective
///< XRay instrumentation.
VALUE_CODEGENOPT(XRayInstructionThreshold , 32, 200)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 809f7605991..34adc640b4e 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -3003,10 +3003,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
case Builtin::BI__xray_customevent: {
if (!ShouldXRayInstrumentFunction())
return RValue::getIgnored();
- if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>()) {
- if (XRayAttr->neverXRayInstrument())
+ if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>())
+ if (XRayAttr->neverXRayInstrument() && !AlwaysEmitXRayCustomEvents())
return RValue::getIgnored();
- }
+
Function *F = CGM.getIntrinsic(Intrinsic::xray_customevent);
auto FTy = F->getFunctionType();
auto Arg0 = E->getArg(0);
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 6b8359141be..6633320de18 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -458,6 +458,12 @@ bool CodeGenFunction::ShouldXRayInstrumentFunction() const {
return CGM.getCodeGenOpts().XRayInstrumentFunctions;
}
+/// 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;
+}
+
llvm::Constant *
CodeGenFunction::EncodeAddrForUseInPrologue(llvm::Function *F,
llvm::Constant *Addr) {
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 8a569fc0157..1c8c2a5e360 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -1771,6 +1771,10 @@ public:
/// instrumented with XRay nop sleds.
bool ShouldXRayInstrumentFunction() const;
+ /// AlwaysEmitXRayCustomEvents - Return true if we must unconditionally emit
+ /// XRay custom event handling calls.
+ bool AlwaysEmitXRayCustomEvents() const;
+
/// Encode an address into a form suitable for use in a function prologue.
llvm::Constant *EncodeAddrForUseInPrologue(llvm::Function *F,
llvm::Constant *Addr);
diff --git a/clang/lib/Driver/XRayArgs.cpp b/clang/lib/Driver/XRayArgs.cpp
index 8d68a8432d3..232bacd5f09 100644
--- a/clang/lib/Driver/XRayArgs.cpp
+++ b/clang/lib/Driver/XRayArgs.cpp
@@ -27,8 +27,6 @@ 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) {
@@ -63,6 +61,14 @@ XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) {
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_fnoxray_always_emit_customevents, false))
+ XRayAlwaysEmitCustomEvents = true;
+
// Validate the always/never attribute files. We also make sure that they
// are treated as actual dependencies.
for (const auto &Filename :
@@ -91,17 +97,21 @@ void XRayArgs::addArgs(const ToolChain &TC, const ArgList &Args,
return;
CmdArgs.push_back(XRayInstrumentOption);
+
+ if (XRayAlwaysEmitCustomEvents)
+ CmdArgs.push_back("-fxray-always-emit-customevents");
+
CmdArgs.push_back(Args.MakeArgString(Twine(XRayInstructionThresholdOption) +
Twine(InstructionThreshold)));
for (const auto &Always : AlwaysInstrumentFiles) {
- SmallString<64> AlwaysInstrumentOpt(XRayAlwaysInstrumentOption);
+ SmallString<64> AlwaysInstrumentOpt("-fxray-always-instrument=");
AlwaysInstrumentOpt += Always;
CmdArgs.push_back(Args.MakeArgString(AlwaysInstrumentOpt));
}
for (const auto &Never : NeverInstrumentFiles) {
- SmallString<64> NeverInstrumentOpt(XRayNeverInstrumentOption);
+ SmallString<64> NeverInstrumentOpt("-fxray-never-instrument=");
NeverInstrumentOpt += Never;
CmdArgs.push_back(Args.MakeArgString(NeverInstrumentOpt));
}
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index cdd53608f65..e1555da272b 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -785,6 +785,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.InstrumentFunctionEntryBare =
Args.hasArg(OPT_finstrument_function_entry_bare);
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);
Opts.InstrumentForProfiling = Args.hasArg(OPT_pg);
@@ -2503,6 +2505,11 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.XRayInstrument =
Args.hasFlag(OPT_fxray_instrument, OPT_fnoxray_instrument, false);
+ // -fxray-always-emit-customevents
+ Opts.XRayAlwaysEmitCustomEvents =
+ Args.hasFlag(OPT_fxray_always_emit_customevents,
+ OPT_fnoxray_always_emit_customevents, false);
+
// -fxray-{always,never}-instrument= filenames.
Opts.XRayAlwaysInstrumentFiles =
Args.getAllArgValues(OPT_fxray_always_instrument);
diff --git a/clang/test/CodeGen/xray-always-emit-customevent.cpp b/clang/test/CodeGen/xray-always-emit-customevent.cpp
new file mode 100644
index 00000000000..8ac22f2a1bc
--- /dev/null
+++ b/clang/test/CodeGen/xray-always-emit-customevent.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fxray-instrument -fxray-always-emit-customevents -x c++ \
+// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN: | FileCheck %s
+
+// CHECK-LABEL: @_Z15neverInstrumentv
+[[clang::xray_never_instrument]] void neverInstrument() {
+ static constexpr char kPhase[] = "never";
+ __xray_customevent(kPhase, 5);
+ // CHECK: call void @llvm.xray.customevent(i8*{{.*}}, i32 5)
+}
OpenPOWER on IntegriCloud