summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDean Michael Berris <dberris@google.com>2017-11-30 00:04:54 +0000
committerDean Michael Berris <dberris@google.com>2017-11-30 00:04:54 +0000
commit1a5b10d5b415dca17c666dbf9c02b5d3238d085a (patch)
treebe7bdd19857bba6fe39e34e0a8a895ace301535e
parent943aca3c2796ed01453f715dbd3c2c8d2b73c9eb (diff)
downloadbcm5719-llvm-1a5b10d5b415dca17c666dbf9c02b5d3238d085a.tar.gz
bcm5719-llvm-1a5b10d5b415dca17c666dbf9c02b5d3238d085a.zip
[XRay][clang] Introduce -fxray-always-emit-customevents
Summary: The -fxray-always-emit-customevents flag instructs clang to always emit the LLVM IR for calls to the `__xray_customevent(...)` built-in function. The default behaviour currently respects whether the function has an `[[clang::xray_never_instrument]]` attribute, and thus not lower the appropriate IR code for the custom event built-in. This change allows users calling through to the `__xray_customevent(...)` built-in to always see those calls lowered to the corresponding LLVM IR to lay down instrumentation points for these custom event calls. Using this flag enables us to emit even just the user-provided custom events even while never instrumenting the start/end of the function where they appear. This is useful in cases where "phase markers" using __xray_customevent(...) can have very few instructions, must never be instrumented when entered/exited. Reviewers: rnk, dblaikie, kpw Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D40601 llvm-svn: 319388
-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