Skip to content

Commit 488f7c2

Browse files
committedApr 13, 2018
[XRay][clang] Add flag to choose instrumentation bundles
Summary: This change addresses http://llvm.org/PR36926 by allowing users to pick which instrumentation bundles to use, when instrumenting with XRay. In particular, the flag `-fxray-instrumentation-bundle=` has four valid values: - `all`: the default, emits all instrumentation kinds - `none`: equivalent to -fnoxray-instrument - `function`: emits the entry/exit instrumentation - `custom`: emits the custom event instrumentation These can be combined either as comma-separated values, or as repeated flag values. Reviewers: echristo, kpw, eizan, pelikan Reviewed By: pelikan Subscribers: mgorny, cfe-commits Differential Revision: https://reviews.llvm.org/D44970 llvm-svn: 329985
1 parent 35ad9ee commit 488f7c2

File tree

12 files changed

+221
-9
lines changed

12 files changed

+221
-9
lines changed
 

Diff for: ‎clang/include/clang/Basic/XRayInstr.h

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//===--- XRayInstr.h --------------------------------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
/// \file
11+
/// \brief Defines the clang::XRayInstrKind enum.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#ifndef LLVM_CLANG_BASIC_XRAYINSTR_H
16+
#define LLVM_CLANG_BASIC_XRAYINSTR_H
17+
18+
#include "clang/Basic/LLVM.h"
19+
#include "llvm/ADT/StringRef.h"
20+
#include "llvm/Support/MathExtras.h"
21+
#include <cassert>
22+
#include <cstdint>
23+
24+
namespace clang {
25+
26+
using XRayInstrMask = uint32_t;
27+
28+
namespace XRayInstrKind {
29+
30+
// TODO: Auto-generate these as we add more instrumentation kinds.
31+
enum XRayInstrOrdinal : XRayInstrMask {
32+
XRIO_Function,
33+
XRIO_Custom,
34+
XRIO_Count
35+
};
36+
37+
constexpr XRayInstrMask None = 0;
38+
constexpr XRayInstrMask Function = 1U << XRIO_Function;
39+
constexpr XRayInstrMask Custom = 1U << XRIO_Custom;
40+
constexpr XRayInstrMask All = Function | Custom;
41+
42+
} // namespace XRayInstrKind
43+
44+
struct XRayInstrSet {
45+
bool has(XRayInstrMask K) const {
46+
assert(llvm::isPowerOf2_32(K));
47+
return Mask & K;
48+
}
49+
50+
bool hasOneOf(XRayInstrMask K) const { return Mask & K; }
51+
52+
void set(XRayInstrMask K, bool Value) {
53+
assert(llvm::isPowerOf2_32(K));
54+
Mask = Value ? (Mask | K) : (Mask & ~K);
55+
}
56+
57+
void clear(XRayInstrMask K = XRayInstrKind::All) { Mask &= ~K; }
58+
59+
bool empty() const { return Mask == 0; }
60+
61+
XRayInstrMask Mask = 0;
62+
};
63+
64+
XRayInstrMask parseXRayInstrValue(StringRef Value);
65+
66+
} // namespace clang
67+
68+
#endif // LLVM_CLANG_BASIC_XRAYINSTR_H

Diff for: ‎clang/include/clang/Driver/Options.td

+5
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,11 @@ def fxray_link_deps : Flag<["-"], "fxray-link-deps">, Group<f_Group>,
11251125
def fnoxray_link_deps : Flag<["-"], "fnoxray-link-deps">, Group<f_Group>,
11261126
Flags<[CC1Option]>;
11271127

1128+
def fxray_instrumentation_bundle :
1129+
JoinedOrSeparate<["-"], "fxray-instrumentation-bundle=">,
1130+
Group<f_Group>, Flags<[CC1Option]>,
1131+
HelpText<"Select which XRay instrumentation points to emit. Options: all, none, function, custom. Default is 'all'.">;
1132+
11281133
def ffine_grained_bitfield_accesses : Flag<["-"],
11291134
"ffine-grained-bitfield-accesses">, Group<f_clang_Group>, Flags<[CC1Option]>,
11301135
HelpText<"Use separate accesses for bitfields with legal widths and alignments.">;

Diff for: ‎clang/include/clang/Driver/XRayArgs.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#ifndef LLVM_CLANG_DRIVER_XRAYARGS_H
1010
#define LLVM_CLANG_DRIVER_XRAYARGS_H
1111

12+
#include "clang/Basic/XRayInstr.h"
1213
#include "clang/Driver/Types.h"
1314
#include "llvm/Option/Arg.h"
1415
#include "llvm/Option/ArgList.h"
@@ -24,6 +25,7 @@ class XRayArgs {
2425
std::vector<std::string> AttrListFiles;
2526
std::vector<std::string> ExtraDeps;
2627
std::vector<std::string> Modes;
28+
XRayInstrSet InstrumentationBundle;
2729
bool XRayInstrument = false;
2830
int InstructionThreshold = 200;
2931
bool XRayAlwaysEmitCustomEvents = false;
@@ -37,7 +39,7 @@ class XRayArgs {
3739

3840
bool needsXRayRt() const { return XRayInstrument && XRayRT; }
3941
llvm::ArrayRef<std::string> modeList() const { return Modes; }
40-
42+
XRayInstrSet instrumentationBundle() const { return InstrumentationBundle; }
4143
};
4244

4345
} // namespace driver

Diff for: ‎clang/include/clang/Frontend/CodeGenOptions.h

+4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "clang/Basic/DebugInfoOptions.h"
1818
#include "clang/Basic/Sanitizers.h"
19+
#include "clang/Basic/XRayInstr.h"
1920
#include "llvm/Support/CodeGen.h"
2021
#include "llvm/Support/Regex.h"
2122
#include "llvm/Target/TargetOptions.h"
@@ -255,6 +256,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
255256
/// registers.
256257
std::string PreferVectorWidth;
257258

259+
/// Set of XRay instrumentation kinds to emit.
260+
XRayInstrSet XRayInstrumentationBundle;
261+
258262
public:
259263
// Define accessors/mutators for code generation options of enumeration type.
260264
#define CODEGENOPT(Name, Bits, Default)

Diff for: ‎clang/lib/Basic/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ add_clang_library(clangBasic
9696
VersionTuple.cpp
9797
VirtualFileSystem.cpp
9898
Warnings.cpp
99+
XRayInstr.cpp
99100
XRayLists.cpp
100101
${version_inc}
101102
)

Diff for: ‎clang/lib/Basic/XRayInstr.cpp

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===--- XRayInstr.cpp ------------------------------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This is part of XRay, a function call instrumentation system.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "clang/Basic/XRayInstr.h"
15+
#include "llvm/ADT/StringSwitch.h"
16+
17+
namespace clang {
18+
19+
XRayInstrMask parseXRayInstrValue(StringRef Value) {
20+
XRayInstrMask ParsedKind = llvm::StringSwitch<XRayInstrMask>(Value)
21+
.Case("all", XRayInstrKind::All)
22+
.Case("custom", XRayInstrKind::Custom)
23+
.Case("function", XRayInstrKind::Function)
24+
.Case("none", XRayInstrKind::None)
25+
.Default(XRayInstrKind::None);
26+
return ParsedKind;
27+
}
28+
29+
} // namespace clang

Diff for: ‎clang/lib/CodeGen/CGBuiltin.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -3341,6 +3341,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
33413341
case Builtin::BI__xray_customevent: {
33423342
if (!ShouldXRayInstrumentFunction())
33433343
return RValue::getIgnored();
3344+
3345+
if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
3346+
XRayInstrKind::Custom))
3347+
return RValue::getIgnored();
3348+
33443349
if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>())
33453350
if (XRayAttr->neverXRayInstrument() && !AlwaysEmitXRayCustomEvents())
33463351
return RValue::getIgnored();

Diff for: ‎clang/lib/CodeGen/CodeGenFunction.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,10 @@ bool CodeGenFunction::ShouldXRayInstrumentFunction() const {
468468
/// AlwaysEmitXRayCustomEvents - Return true if we should emit IR for calls to
469469
/// the __xray_customevent(...) builin calls, when doing XRay instrumentation.
470470
bool CodeGenFunction::AlwaysEmitXRayCustomEvents() const {
471-
return CGM.getCodeGenOpts().XRayAlwaysEmitCustomEvents;
471+
return CGM.getCodeGenOpts().XRayInstrumentFunctions &&
472+
(CGM.getCodeGenOpts().XRayAlwaysEmitCustomEvents ||
473+
CGM.getCodeGenOpts().XRayInstrumentationBundle.Mask ==
474+
XRayInstrKind::Custom);
472475
}
473476

474477
llvm::Constant *
@@ -900,7 +903,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
900903
}
901904

902905
// Apply xray attributes to the function (as a string, for now)
903-
bool InstrumentXray = ShouldXRayInstrumentFunction();
906+
bool InstrumentXray = ShouldXRayInstrumentFunction() &&
907+
CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
908+
XRayInstrKind::Function);
904909
if (D && InstrumentXray) {
905910
if (const auto *XRayAttr = D->getAttr<XRayInstrumentAttr>()) {
906911
if (XRayAttr->alwaysXRayInstrument())

Diff for: ‎clang/lib/CodeGen/CodeGenModule.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -1846,9 +1846,10 @@ bool CodeGenModule::imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc,
18461846
StringRef Category) const {
18471847
if (!LangOpts.XRayInstrument)
18481848
return false;
1849+
18491850
const auto &XRayFilter = getContext().getXRayFilter();
18501851
using ImbueAttr = XRayFunctionFilter::ImbueAttribute;
1851-
auto Attr = XRayFunctionFilter::ImbueAttribute::NONE;
1852+
auto Attr = ImbueAttr::NONE;
18521853
if (Loc.isValid())
18531854
Attr = XRayFilter.shouldImbueLocation(Loc, Category);
18541855
if (Attr == ImbueAttr::NONE)

Diff for: ‎clang/lib/Driver/XRayArgs.cpp

+32-3
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) {
5858
}
5959
} else {
6060
D.Diag(diag::err_drv_clang_unsupported)
61-
<< (std::string(XRayInstrumentOption) +
62-
" on non-supported target OS");
61+
<< (std::string(XRayInstrumentOption) + " on " + Triple.str());
6362
}
6463
XRayInstrument = true;
6564
if (const Arg *A =
@@ -82,6 +81,36 @@ XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) {
8281
options::OPT_fnoxray_link_deps, true))
8382
XRayRT = false;
8483

84+
auto Bundles =
85+
Args.getAllArgValues(options::OPT_fxray_instrumentation_bundle);
86+
if (Bundles.empty())
87+
InstrumentationBundle.Mask = XRayInstrKind::All;
88+
else
89+
for (const auto &B : Bundles) {
90+
llvm::SmallVector<StringRef, 2> BundleParts;
91+
llvm::SplitString(B, BundleParts, ",");
92+
for (const auto &P : BundleParts) {
93+
// TODO: Automate the generation of the string case table.
94+
auto Valid = llvm::StringSwitch<bool>(P)
95+
.Cases("none", "all", "function", "custom", true)
96+
.Default(false);
97+
98+
if (!Valid) {
99+
D.Diag(clang::diag::err_drv_invalid_value)
100+
<< "-fxray-instrumentation-bundle=" << P;
101+
continue;
102+
}
103+
104+
auto Mask = parseXRayInstrValue(P);
105+
if (Mask == XRayInstrKind::None) {
106+
InstrumentationBundle.clear();
107+
break;
108+
}
109+
110+
InstrumentationBundle.Mask |= Mask;
111+
}
112+
}
113+
85114
// Validate the always/never attribute files. We also make sure that they
86115
// are treated as actual dependencies.
87116
for (const auto &Filename :
@@ -165,7 +194,7 @@ void XRayArgs::addArgs(const ToolChain &TC, const ArgList &Args,
165194
CmdArgs.push_back(Args.MakeArgString(NeverInstrumentOpt));
166195
}
167196

168-
for (const auto& AttrFile : AttrListFiles) {
197+
for (const auto &AttrFile : AttrListFiles) {
169198
SmallString<64> AttrListFileOpt("-fxray-attr-list=");
170199
AttrListFileOpt += AttrFile;
171200
CmdArgs.push_back(Args.MakeArgString(AttrListFileOpt));

Diff for: ‎clang/lib/Frontend/CompilerInvocation.cpp

+34-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "clang/Basic/VersionTuple.h"
2727
#include "clang/Basic/VirtualFileSystem.h"
2828
#include "clang/Basic/Visibility.h"
29+
#include "clang/Basic/XRayInstr.h"
2930
#include "clang/Config/config.h"
3031
#include "clang/Driver/DriverDiagnostic.h"
3132
#include "clang/Driver/Options.h"
@@ -75,9 +76,9 @@
7576
#include "llvm/Support/Path.h"
7677
#include "llvm/Support/Process.h"
7778
#include "llvm/Support/Regex.h"
79+
#include "llvm/Support/ScopedPrinter.h"
7880
#include "llvm/Support/raw_ostream.h"
7981
#include "llvm/Target/TargetOptions.h"
80-
#include "llvm/Support/ScopedPrinter.h"
8182
#include <algorithm>
8283
#include <atomic>
8384
#include <cassert>
@@ -446,6 +447,25 @@ static void parseSanitizerKinds(StringRef FlagName,
446447
}
447448
}
448449

450+
static void parseXRayInstrumentationBundle(StringRef FlagName, StringRef Bundle,
451+
ArgList &Args, DiagnosticsEngine &D,
452+
XRayInstrSet &S) {
453+
llvm::SmallVector<StringRef, 2> BundleParts;
454+
llvm::SplitString(Bundle, BundleParts, ",");
455+
for (const auto B : BundleParts) {
456+
auto Mask = parseXRayInstrValue(B);
457+
if (Mask == XRayInstrKind::None)
458+
if (B != "none")
459+
D.Report(diag::err_drv_invalid_value) << FlagName << Bundle;
460+
else
461+
S.Mask = Mask;
462+
else if (Mask == XRayInstrKind::All)
463+
S.Mask = Mask;
464+
else
465+
S.set(Mask, true);
466+
}
467+
}
468+
449469
// Set the profile kind for fprofile-instrument.
450470
static void setPGOInstrumentor(CodeGenOptions &Opts, ArgList &Args,
451471
DiagnosticsEngine &Diags) {
@@ -820,11 +840,23 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
820840
Args.hasArg(OPT_finstrument_functions_after_inlining);
821841
Opts.InstrumentFunctionEntryBare =
822842
Args.hasArg(OPT_finstrument_function_entry_bare);
823-
Opts.XRayInstrumentFunctions = Args.hasArg(OPT_fxray_instrument);
843+
844+
Opts.XRayInstrumentFunctions =
845+
Args.hasArg(OPT_fxray_instrument);
824846
Opts.XRayAlwaysEmitCustomEvents =
825847
Args.hasArg(OPT_fxray_always_emit_customevents);
826848
Opts.XRayInstructionThreshold =
827849
getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
850+
851+
auto XRayInstrBundles =
852+
Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
853+
if (XRayInstrBundles.empty())
854+
Opts.XRayInstrumentationBundle.Mask = XRayInstrKind::All;
855+
else
856+
for (const auto &A : XRayInstrBundles)
857+
parseXRayInstrumentationBundle("-fxray-instrumentation-bundle=", A, Args,
858+
Diags, Opts.XRayInstrumentationBundle);
859+
828860
Opts.InstrumentForProfiling = Args.hasArg(OPT_pg);
829861
Opts.CallFEntry = Args.hasArg(OPT_mfentry);
830862
Opts.EmitOpenCLArgMetadata = Args.hasArg(OPT_cl_kernel_arg_info);

Diff for: ‎clang/test/CodeGen/xray-instrumentation-bundles.cpp

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %clang_cc1 -fxray-instrument -fxray-instrumentation-bundle=none -x c++ \
2+
// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
3+
// RUN: | FileCheck --check-prefixes CHECK,NOFUNCTION,NOCUSTOM %s
4+
// RUN: %clang_cc1 -fxray-instrument \
5+
// RUN: -fxray-instrumentation-bundle=function -x c++ \
6+
// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
7+
// RUN: | FileCheck --check-prefixes CHECK,FUNCTION,NOCUSTOM %s
8+
// RUN: %clang_cc1 -fxray-instrument \
9+
// RUN: -fxray-instrumentation-bundle=custom -x c++ \
10+
// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
11+
// RUN: | FileCheck --check-prefixes CHECK,NOFUNCTION,CUSTOM %s
12+
// RUN: %clang_cc1 -fxray-instrument \
13+
// RUN: -fxray-instrumentation-bundle=function,custom -x c++ \
14+
// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
15+
// RUN: | FileCheck --check-prefixes CHECK,FUNCTION,CUSTOM %s
16+
// RUN: %clang_cc1 -fxray-instrument \
17+
// RUN: -fxray-instrumentation-bundle=function \
18+
// RUN: -fxray-instrumentation-bundle=custom -x c++ \
19+
// RUN: -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
20+
// RUN: | FileCheck --check-prefixes CHECK,FUNCTION,CUSTOM %s
21+
22+
// CHECK: define void @_Z16alwaysInstrumentv() #[[ALWAYSATTR:[0-9]+]] {
23+
[[clang::xray_always_instrument]] void alwaysInstrument() {
24+
static constexpr char kPhase[] = "always";
25+
__xray_customevent(kPhase, 6);
26+
// CUSTOM: call void @llvm.xray.customevent(i8*{{.*}}, i32 6)
27+
// NOCUSTOM-NOT: call void @llvm.xray.customevent(i8*{{.*}}, i32 6)
28+
}
29+
30+
// FUNCTION: attributes #[[ALWAYSATTR]] = {{.*}} "function-instrument"="xray-always" {{.*}}
31+
// NOFUNCTION-NOT: attributes #[[ALWAYSATTR]] = {{.*}} "function-instrument"="xray-always" {{.*}}

0 commit comments

Comments
 (0)
Please sign in to comment.