summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Wyss <wyssman@gmail.com>2018-04-17 21:32:43 +0000
committerKeith Wyss <wyssman@gmail.com>2018-04-17 21:32:43 +0000
commitf437e35671089ab3bdbf11b65a53fe22b9f24172 (patch)
tree9f8b082482b37dfca41de5824b722545c5198fc3
parent3d86823f3d22296f2eb9883d1b84d3fa90c73054 (diff)
downloadbcm5719-llvm-f437e35671089ab3bdbf11b65a53fe22b9f24172.tar.gz
bcm5719-llvm-f437e35671089ab3bdbf11b65a53fe22b9f24172.zip
[XRay] Add clang builtin for xray typed events.
Summary: A clang builtin for xray typed events. Differs from __xray_customevent(...) by the presence of a type tag that is vended by compiler-rt in typical usage. This allows xray handlers to expand logged events with their type description and plugins to process traced events based on type. This change depends on D45633 for the intrinsic definition. Reviewers: dberris, pelikan, rnk, eizan Subscribers: cfe-commits, llvm-commits Differential Revision: https://reviews.llvm.org/D45716 llvm-svn: 330220
-rw-r--r--clang/include/clang/Basic/Builtins.def1
-rw-r--r--clang/include/clang/Basic/LangOptions.def4
-rw-r--r--clang/include/clang/Basic/XRayInstr.h4
-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/Basic/XRayInstr.cpp1
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp38
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp9
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h4
-rw-r--r--clang/lib/Driver/XRayArgs.cpp7
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp7
-rw-r--r--clang/test/CodeGen/xray-always-emit-typedevent.cpp10
-rw-r--r--clang/test/CodeGen/xray-instrumentation-bundles.cpp35
-rw-r--r--clang/test/CodeGen/xray-typedevent.cpp34
15 files changed, 153 insertions, 11 deletions
diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def
index 4b7466277ba..189c8557356 100644
--- a/clang/include/clang/Basic/Builtins.def
+++ b/clang/include/clang/Basic/Builtins.def
@@ -1455,6 +1455,7 @@ LANGBUILTIN(omp_is_initial_device, "i", "nc", OMP_LANG)
// Builtins for XRay
BUILTIN(__xray_customevent, "vcC*z", "")
+BUILTIN(__xray_typedevent, "vzcC*z", "")
// Win64-compatible va_list functions
BUILTIN(__builtin_ms_va_start, "vc*&.", "nt")
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index c05f0dc545e..029e6516c0a 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -281,6 +281,9 @@ 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.")
+LANGOPT(XRayAlwaysEmitTypedEvents, 1, 0,
+ "controls whether to always emit intrinsic calls to "
+ "__xray_typedevent(...) builtin.")
BENIGN_LANGOPT(AllowEditorPlaceholders, 1, 0,
"allow editor placeholders in source")
@@ -298,4 +301,3 @@ ENUM_LANGOPT(ClangABICompat, ClangABI, 4, ClangABI::Latest,
#undef VALUE_LANGOPT
#undef COMPATIBLE_VALUE_LANGOPT
#undef BENIGN_VALUE_LANGOPT
-
diff --git a/clang/include/clang/Basic/XRayInstr.h b/clang/include/clang/Basic/XRayInstr.h
index a573ba1eca3..6a03c7b5e26 100644
--- a/clang/include/clang/Basic/XRayInstr.h
+++ b/clang/include/clang/Basic/XRayInstr.h
@@ -31,13 +31,15 @@ namespace XRayInstrKind {
enum XRayInstrOrdinal : XRayInstrMask {
XRIO_Function,
XRIO_Custom,
+ XRIO_Typed,
XRIO_Count
};
constexpr XRayInstrMask None = 0;
constexpr XRayInstrMask Function = 1U << XRIO_Function;
constexpr XRayInstrMask Custom = 1U << XRIO_Custom;
-constexpr XRayInstrMask All = Function | Custom;
+constexpr XRayInstrMask Typed = 1U << XRIO_Typed;
+constexpr XRayInstrMask All = Function | Custom | Typed;
} // namespace XRayInstrKind
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 09f759e9965..55e87287585 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1119,6 +1119,12 @@ def fxray_always_emit_customevents : Flag<["-"], "fxray-always-emit-customevents
def fnoxray_always_emit_customevents : Flag<["-"], "fno-xray-always-emit-customevents">, Group<f_Group>,
Flags<[CC1Option]>;
+def fxray_always_emit_typedevents : Flag<["-"], "fxray-always-emit-typedevents">, Group<f_Group>,
+ Flags<[CC1Option]>,
+ HelpText<"Determine whether to always emit __xray_typedevent(...) calls even if the function it appears in is not always instrumented.">;
+def fnoxray_always_emit_typedevents : Flag<["-"], "fno-xray-always-emit-typedevents">, Group<f_Group>,
+ Flags<[CC1Option]>;
+
def fxray_link_deps : Flag<["-"], "fxray-link-deps">, Group<f_Group>,
Flags<[CC1Option]>,
HelpText<"Tells clang to add the link dependencies for XRay.">;
diff --git a/clang/include/clang/Driver/XRayArgs.h b/clang/include/clang/Driver/XRayArgs.h
index fd041d9bc58..c7ca9452917 100644
--- a/clang/include/clang/Driver/XRayArgs.h
+++ b/clang/include/clang/Driver/XRayArgs.h
@@ -29,6 +29,7 @@ class XRayArgs {
bool XRayInstrument = false;
int InstructionThreshold = 200;
bool XRayAlwaysEmitCustomEvents = false;
+ bool XRayAlwaysEmitTypedEvents = false;
bool XRayRT = true;
public:
diff --git a/clang/include/clang/Frontend/CodeGenOptions.def b/clang/include/clang/Frontend/CodeGenOptions.def
index 8d710b0c6f9..684f99e1de3 100644
--- a/clang/include/clang/Frontend/CodeGenOptions.def
+++ b/clang/include/clang/Frontend/CodeGenOptions.def
@@ -96,6 +96,9 @@ CODEGENOPT(StackSizeSection , 1, 0) ///< Set when -fstack-size-section is enabl
///< Set when -fxray-always-emit-customevents is enabled.
CODEGENOPT(XRayAlwaysEmitCustomEvents , 1, 0)
+///< Set when -fxray-always-emit-typedevents is enabled.
+CODEGENOPT(XRayAlwaysEmitTypedEvents , 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/Basic/XRayInstr.cpp b/clang/lib/Basic/XRayInstr.cpp
index 42f9038890a..8cc36df7946 100644
--- a/clang/lib/Basic/XRayInstr.cpp
+++ b/clang/lib/Basic/XRayInstr.cpp
@@ -21,6 +21,7 @@ XRayInstrMask parseXRayInstrValue(StringRef Value) {
.Case("all", XRayInstrKind::All)
.Case("custom", XRayInstrKind::Custom)
.Case("function", XRayInstrKind::Function)
+ .Case("typed", XRayInstrKind::Typed)
.Case("none", XRayInstrKind::None)
.Default(XRayInstrKind::None);
return ParsedKind;
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index dd245dd5590..fffc2429fb1 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -3372,6 +3372,44 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
return RValue::get(Builder.CreateCall(F, {Arg0Val, Arg1}));
}
+ case Builtin::BI__xray_typedevent: {
+ // TODO: There should be a way to always emit events even if the current
+ // function is not instrumented. Losing events in a stream can cripple
+ // a trace.
+ if (!ShouldXRayInstrumentFunction())
+ return RValue::getIgnored();
+
+ if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
+ XRayInstrKind::Typed))
+ return RValue::getIgnored();
+
+ if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>())
+ if (XRayAttr->neverXRayInstrument() && !AlwaysEmitXRayTypedEvents())
+ return RValue::getIgnored();
+
+ Function *F = CGM.getIntrinsic(Intrinsic::xray_typedevent);
+ auto FTy = F->getFunctionType();
+ auto Arg0 = EmitScalarExpr(E->getArg(0));
+ auto PTy0 = FTy->getParamType(0);
+ if (PTy0 != Arg0->getType())
+ Arg0 = Builder.CreateTruncOrBitCast(Arg0, PTy0);
+ auto Arg1 = E->getArg(1);
+ auto Arg1Val = EmitScalarExpr(Arg1);
+ auto Arg1Ty = Arg1->getType();
+ auto PTy1 = FTy->getParamType(1);
+ if (PTy1 != Arg1Val->getType()) {
+ if (Arg1Ty->isArrayType())
+ Arg1Val = EmitArrayToPointerDecay(Arg1).getPointer();
+ else
+ Arg1Val = Builder.CreatePointerCast(Arg1Val, PTy1);
+ }
+ auto Arg2 = EmitScalarExpr(E->getArg(2));
+ auto PTy2 = FTy->getParamType(2);
+ if (PTy2 != Arg2->getType())
+ Arg2 = Builder.CreateTruncOrBitCast(Arg2, PTy2);
+ return RValue::get(Builder.CreateCall(F, {Arg0, Arg1Val, Arg2}));
+ }
+
case Builtin::BI__builtin_ms_va_start:
case Builtin::BI__builtin_ms_va_end:
return RValue::get(
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 92564043e07..bf5312550b7 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -466,7 +466,7 @@ bool CodeGenFunction::ShouldXRayInstrumentFunction() const {
}
/// AlwaysEmitXRayCustomEvents - Return true if we should emit IR for calls to
-/// the __xray_customevent(...) builin calls, when doing XRay instrumentation.
+/// the __xray_customevent(...) builtin calls, when doing XRay instrumentation.
bool CodeGenFunction::AlwaysEmitXRayCustomEvents() const {
return CGM.getCodeGenOpts().XRayInstrumentFunctions &&
(CGM.getCodeGenOpts().XRayAlwaysEmitCustomEvents ||
@@ -474,6 +474,13 @@ bool CodeGenFunction::AlwaysEmitXRayCustomEvents() const {
XRayInstrKind::Custom);
}
+bool CodeGenFunction::AlwaysEmitXRayTypedEvents() const {
+ return CGM.getCodeGenOpts().XRayInstrumentFunctions &&
+ (CGM.getCodeGenOpts().XRayAlwaysEmitTypedEvents ||
+ CGM.getCodeGenOpts().XRayInstrumentationBundle.Mask ==
+ XRayInstrKind::Typed);
+}
+
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 84118a50c1d..091fdc7ab7a 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -1804,6 +1804,10 @@ public:
/// XRay custom event handling calls.
bool AlwaysEmitXRayCustomEvents() const;
+ /// AlwaysEmitXRayTypedEvents - Return true if clang must unconditionally emit
+ /// XRay typed event handling calls.
+ bool AlwaysEmitXRayTypedEvents() 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 873693354d1..5caeffc9d6e 100644
--- a/clang/lib/Driver/XRayArgs.cpp
+++ b/clang/lib/Driver/XRayArgs.cpp
@@ -77,6 +77,10 @@ XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) {
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;
@@ -174,6 +178,9 @@ void XRayArgs::addArgs(const ToolChain &TC, const ArgList &Args,
if (XRayAlwaysEmitCustomEvents)
CmdArgs.push_back("-fxray-always-emit-customevents");
+ if (XRayAlwaysEmitTypedEvents)
+ CmdArgs.push_back("-fxray-always-emit-typedevents");
+
CmdArgs.push_back(Args.MakeArgString(Twine(XRayInstructionThresholdOption) +
Twine(InstructionThreshold)));
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 469497c485f..9146d2a36df 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -854,6 +854,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Args.hasArg(OPT_fxray_instrument);
Opts.XRayAlwaysEmitCustomEvents =
Args.hasArg(OPT_fxray_always_emit_customevents);
+ Opts.XRayAlwaysEmitTypedEvents =
+ Args.hasArg(OPT_fxray_always_emit_typedevents);
Opts.XRayInstructionThreshold =
getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
@@ -2678,6 +2680,11 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Args.hasFlag(OPT_fxray_always_emit_customevents,
OPT_fnoxray_always_emit_customevents, false);
+ // -fxray-always-emit-typedevents
+ Opts.XRayAlwaysEmitTypedEvents =
+ Args.hasFlag(OPT_fxray_always_emit_typedevents,
+ 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-typedevent.cpp b/clang/test/CodeGen/xray-always-emit-typedevent.cpp
new file mode 100644
index 00000000000..50593dd2032
--- /dev/null
+++ b/clang/test/CodeGen/xray-always-emit-typedevent.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fxray-instrument -fxray-always-emit-typedevents -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_typedevent(1, kPhase, 5);
+ // CHECK: call void @llvm.xray.typedevent(i16 {{.*}}, i8*{{.*}}, i32 5)
+}
diff --git a/clang/test/CodeGen/xray-instrumentation-bundles.cpp b/clang/test/CodeGen/xray-instrumentation-bundles.cpp
index 3e751834475..79286c2c8ae 100644
--- a/clang/test/CodeGen/xray-instrumentation-bundles.cpp
+++ b/clang/test/CodeGen/xray-instrumentation-bundles.cpp
@@ -1,30 +1,49 @@
// 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 --check-prefixes CHECK,NOFUNCTION,NOCUSTOM %s
-// RUN: %clang_cc1 -fxray-instrument \
-// RUN: -fxray-instrumentation-bundle=function -x c++ \
+// RUN: | FileCheck --check-prefixes CHECK,NOFUNCTION,NOCUSTOM,NOTYPED %s
+// RUN: %clang_cc1 -fxray-instrument -fxray-instrumentation-bundle=function -x c++ \
// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
-// RUN: | FileCheck --check-prefixes CHECK,FUNCTION,NOCUSTOM %s
+// RUN: | FileCheck --check-prefixes CHECK,FUNCTION,NOCUSTOM,NOTYPED %s
// RUN: %clang_cc1 -fxray-instrument \
// RUN: -fxray-instrumentation-bundle=custom -x c++ \
// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
-// RUN: | FileCheck --check-prefixes CHECK,NOFUNCTION,CUSTOM %s
+// RUN: | FileCheck --check-prefixes CHECK,NOFUNCTION,CUSTOM,NOTYPED %s
+// RUN: %clang_cc1 -fxray-instrument \
+// RUN: -fxray-instrumentation-bundle=typed -x c++ \
+// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN: | FileCheck --check-prefixes CHECK,NOFUNCTION,NOCUSTOM,TYPED %s
+// RUN: %clang_cc1 -fxray-instrument \
+// RUN: -fxray-instrumentation-bundle=custom,typed -x c++ \
+// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN: | FileCheck --check-prefixes CHECK,NOFUNCTION,CUSTOM,TYPED %s
// RUN: %clang_cc1 -fxray-instrument \
// RUN: -fxray-instrumentation-bundle=function,custom -x c++ \
// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
-// RUN: | FileCheck --check-prefixes CHECK,FUNCTION,CUSTOM %s
+// RUN: | FileCheck --check-prefixes CHECK,FUNCTION,CUSTOM,NOTYPED %s
+// RUN: %clang_cc1 -fxray-instrument \
+// RUN: -fxray-instrumentation-bundle=function,typed -x c++ \
+// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN: | FileCheck --check-prefixes CHECK,FUNCTION,NOCUSTOM,TYPED %s
+// RUN: %clang_cc1 -fxray-instrument \
+// RUN: -fxray-instrumentation-bundle=function,custom,typed -x c++ \
+// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN: | FileCheck --check-prefixes CHECK,FUNCTION,CUSTOM,TYPED %s
// RUN: %clang_cc1 -fxray-instrument \
// RUN: -fxray-instrumentation-bundle=function \
-// RUN: -fxray-instrumentation-bundle=custom -x c++ \
+// RUN: -fxray-instrumentation-bundle=custom \
+// RUN: -fxray-instrumentation-bundle=typed -x c++ \
// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
-// RUN: | FileCheck --check-prefixes CHECK,FUNCTION,CUSTOM %s
+// RUN: | FileCheck --check-prefixes CHECK,FUNCTION,CUSTOM,TYPED %s
// CHECK: define void @_Z16alwaysInstrumentv() #[[ALWAYSATTR:[0-9]+]] {
[[clang::xray_always_instrument]] void alwaysInstrument() {
static constexpr char kPhase[] = "always";
__xray_customevent(kPhase, 6);
+ __xray_typedevent(1, kPhase, 6);
// CUSTOM: call void @llvm.xray.customevent(i8*{{.*}}, i32 6)
// NOCUSTOM-NOT: call void @llvm.xray.customevent(i8*{{.*}}, i32 6)
+ // TYPED: call void @llvm.xray.typedevent(i16 {{.*}}, i8*{{.*}}, i32 6)
+ // NOTYPED-NOT: call void @llvm.xray.typedevent(i16 {{.*}}, i8*{{.*}}, i32 6)
}
// FUNCTION: attributes #[[ALWAYSATTR]] = {{.*}} "function-instrument"="xray-always" {{.*}}
diff --git a/clang/test/CodeGen/xray-typedevent.cpp b/clang/test/CodeGen/xray-typedevent.cpp
new file mode 100644
index 00000000000..e804b09dc2c
--- /dev/null
+++ b/clang/test/CodeGen/xray-typedevent.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fxray-instrument -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: @_Z16alwaysInstrumentv
+[[clang::xray_always_instrument]] void alwaysInstrument() {
+ // Event types would normally come from calling __xray_register_event_type
+ // from compiler-rt
+ auto EventType = 1;
+ static constexpr char kPhase[] = "instrument";
+ __xray_typedevent(EventType, kPhase, 10);
+ // CHECK: call void @llvm.xray.typedevent(i16 {{.*}}, i8*{{.*}}, i32 10)
+}
+
+// CHECK-LABEL: @_Z15neverInstrumentv
+[[clang::xray_never_instrument]] void neverInstrument() {
+ auto EventType = 2;
+ static constexpr char kPhase[] = "never";
+ __xray_typedevent(EventType, kPhase, 5);
+ // CHECK-NOT: call void @llvm.xray.typedevent(i16 {{.*}}, i8*{{.*}}, i32 5)
+}
+
+// CHECK-LABEL: @_Z21conditionalInstrumenti
+[[clang::xray_always_instrument]] void conditionalInstrument(int v) {
+ auto TrueEventType = 3;
+ auto UntrueEventType = 4;
+ static constexpr char kTrue[] = "true";
+ static constexpr char kUntrue[] = "untrue";
+ if (v % 2)
+ __xray_typedevent(TrueEventType, kTrue, 4);
+ else
+ __xray_typedevent(UntrueEventType, kUntrue, 6);
+
+ // CHECK: call void @llvm.xray.typedevent(i16 {{.*}}, i8*{{.*}}, i32 4)
+ // CHECK: call void @llvm.xray.typedevent(i16 {{.*}}, i8*{{.*}}, i32 6)
+}
OpenPOWER on IntegriCloud