summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-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
6 files changed, 65 insertions, 1 deletions
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);
OpenPOWER on IntegriCloud