clang  7.0.0svn
XRayArgs.cpp
Go to the documentation of this file.
1 //===--- XRayArgs.cpp - Arguments for XRay --------------------------------===//
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 //===----------------------------------------------------------------------===//
10 #include "ToolChains/CommonArgs.h"
11 #include "clang/Driver/Driver.h"
13 #include "clang/Driver/Options.h"
14 #include "clang/Driver/ToolChain.h"
15 #include "llvm/ADT/StringExtras.h"
16 #include "llvm/ADT/StringSwitch.h"
17 #include "llvm/Support/FileSystem.h"
18 #include "llvm/Support/Path.h"
19 #include "llvm/Support/ScopedPrinter.h"
20 #include "llvm/Support/SpecialCaseList.h"
21 
22 using namespace clang;
23 using namespace clang::driver;
24 using namespace llvm::opt;
25 
26 namespace {
27 constexpr char XRayInstrumentOption[] = "-fxray-instrument";
28 constexpr char XRayInstructionThresholdOption[] =
29  "-fxray-instruction-threshold=";
30 constexpr const char *const XRaySupportedModes[] = {"xray-fdr", "xray-basic"};
31 } // namespace
32 
33 XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) {
34  const Driver &D = TC.getDriver();
35  const llvm::Triple &Triple = TC.getTriple();
36  if (Args.hasFlag(options::OPT_fxray_instrument,
37  options::OPT_fnoxray_instrument, false)) {
38  if (Triple.getOS() == llvm::Triple::Linux) {
39  switch (Triple.getArch()) {
40  case llvm::Triple::x86_64:
41  case llvm::Triple::arm:
42  case llvm::Triple::aarch64:
43  case llvm::Triple::ppc64le:
44  case llvm::Triple::mips:
45  case llvm::Triple::mipsel:
46  case llvm::Triple::mips64:
47  case llvm::Triple::mips64el:
48  break;
49  default:
50  D.Diag(diag::err_drv_clang_unsupported)
51  << (std::string(XRayInstrumentOption) + " on " + Triple.str());
52  }
53  } else if (Triple.getOS() == llvm::Triple::FreeBSD ||
54  Triple.getOS() == llvm::Triple::OpenBSD ||
55  Triple.getOS() == llvm::Triple::NetBSD) {
56  if (Triple.getArch() != llvm::Triple::x86_64) {
57  D.Diag(diag::err_drv_clang_unsupported)
58  << (std::string(XRayInstrumentOption) + " on " + Triple.str());
59  }
60  } else {
61  D.Diag(diag::err_drv_clang_unsupported)
62  << (std::string(XRayInstrumentOption) + " on " + Triple.str());
63  }
64  XRayInstrument = true;
65  if (const Arg *A =
66  Args.getLastArg(options::OPT_fxray_instruction_threshold_,
67  options::OPT_fxray_instruction_threshold_EQ)) {
68  StringRef S = A->getValue();
69  if (S.getAsInteger(0, InstructionThreshold) || InstructionThreshold < 0)
70  D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
71  }
72 
73  // By default, the back-end will not emit the lowering for XRay customevent
74  // calls if the function is not instrumented. In the future we will change
75  // this default to be the reverse, but in the meantime we're going to
76  // introduce the new functionality behind a flag.
77  if (Args.hasFlag(options::OPT_fxray_always_emit_customevents,
78  options::OPT_fnoxray_always_emit_customevents, false))
79  XRayAlwaysEmitCustomEvents = true;
80 
81  if (Args.hasFlag(options::OPT_fxray_always_emit_typedevents,
82  options::OPT_fnoxray_always_emit_typedevents, false))
83  XRayAlwaysEmitTypedEvents = true;
84 
85  if (!Args.hasFlag(options::OPT_fxray_link_deps,
86  options::OPT_fnoxray_link_deps, true))
87  XRayRT = false;
88 
89  auto Bundles =
90  Args.getAllArgValues(options::OPT_fxray_instrumentation_bundle);
91  if (Bundles.empty())
92  InstrumentationBundle.Mask = XRayInstrKind::All;
93  else
94  for (const auto &B : Bundles) {
96  llvm::SplitString(B, BundleParts, ",");
97  for (const auto &P : BundleParts) {
98  // TODO: Automate the generation of the string case table.
99  auto Valid = llvm::StringSwitch<bool>(P)
100  .Cases("none", "all", "function", "custom", true)
101  .Default(false);
102 
103  if (!Valid) {
104  D.Diag(clang::diag::err_drv_invalid_value)
105  << "-fxray-instrumentation-bundle=" << P;
106  continue;
107  }
108 
109  auto Mask = parseXRayInstrValue(P);
110  if (Mask == XRayInstrKind::None) {
111  InstrumentationBundle.clear();
112  break;
113  }
114 
115  InstrumentationBundle.Mask |= Mask;
116  }
117  }
118 
119  // Validate the always/never attribute files. We also make sure that they
120  // are treated as actual dependencies.
121  for (const auto &Filename :
122  Args.getAllArgValues(options::OPT_fxray_always_instrument)) {
123  if (llvm::sys::fs::exists(Filename)) {
124  AlwaysInstrumentFiles.push_back(Filename);
125  ExtraDeps.push_back(Filename);
126  } else
127  D.Diag(clang::diag::err_drv_no_such_file) << Filename;
128  }
129 
130  for (const auto &Filename :
131  Args.getAllArgValues(options::OPT_fxray_never_instrument)) {
132  if (llvm::sys::fs::exists(Filename)) {
133  NeverInstrumentFiles.push_back(Filename);
134  ExtraDeps.push_back(Filename);
135  } else
136  D.Diag(clang::diag::err_drv_no_such_file) << Filename;
137  }
138 
139  for (const auto &Filename :
140  Args.getAllArgValues(options::OPT_fxray_attr_list)) {
141  if (llvm::sys::fs::exists(Filename)) {
142  AttrListFiles.push_back(Filename);
143  ExtraDeps.push_back(Filename);
144  } else
145  D.Diag(clang::diag::err_drv_no_such_file) << Filename;
146  }
147 
148  // Get the list of modes we want to support.
149  auto SpecifiedModes = Args.getAllArgValues(options::OPT_fxray_modes);
150  if (SpecifiedModes.empty())
151  llvm::copy(XRaySupportedModes, std::back_inserter(Modes));
152  else
153  for (const auto &Arg : SpecifiedModes) {
154  // Parse CSV values for -fxray-modes=...
156  llvm::SplitString(Arg, ModeParts, ",");
157  for (const auto &M : ModeParts)
158  if (M == "none")
159  Modes.clear();
160  else if (M == "all")
161  llvm::copy(XRaySupportedModes, std::back_inserter(Modes));
162  else
163  Modes.push_back(M);
164  }
165 
166  // Then we want to sort and unique the modes we've collected.
167  llvm::sort(Modes.begin(), Modes.end());
168  Modes.erase(std::unique(Modes.begin(), Modes.end()), Modes.end());
169  }
170 }
171 
172 void XRayArgs::addArgs(const ToolChain &TC, const ArgList &Args,
173  ArgStringList &CmdArgs, types::ID InputType) const {
174  if (!XRayInstrument)
175  return;
176 
177  CmdArgs.push_back(XRayInstrumentOption);
178 
179  if (XRayAlwaysEmitCustomEvents)
180  CmdArgs.push_back("-fxray-always-emit-customevents");
181 
182  if (XRayAlwaysEmitTypedEvents)
183  CmdArgs.push_back("-fxray-always-emit-typedevents");
184 
185  CmdArgs.push_back(Args.MakeArgString(Twine(XRayInstructionThresholdOption) +
186  Twine(InstructionThreshold)));
187 
188  for (const auto &Always : AlwaysInstrumentFiles) {
189  SmallString<64> AlwaysInstrumentOpt("-fxray-always-instrument=");
190  AlwaysInstrumentOpt += Always;
191  CmdArgs.push_back(Args.MakeArgString(AlwaysInstrumentOpt));
192  }
193 
194  for (const auto &Never : NeverInstrumentFiles) {
195  SmallString<64> NeverInstrumentOpt("-fxray-never-instrument=");
196  NeverInstrumentOpt += Never;
197  CmdArgs.push_back(Args.MakeArgString(NeverInstrumentOpt));
198  }
199 
200  for (const auto &AttrFile : AttrListFiles) {
201  SmallString<64> AttrListFileOpt("-fxray-attr-list=");
202  AttrListFileOpt += AttrFile;
203  CmdArgs.push_back(Args.MakeArgString(AttrListFileOpt));
204  }
205 
206  for (const auto &Dep : ExtraDeps) {
207  SmallString<64> ExtraDepOpt("-fdepfile-entry=");
208  ExtraDepOpt += Dep;
209  CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt));
210  }
211 
212  for (const auto &Mode : Modes) {
213  SmallString<64> ModeOpt("-fxray-modes=");
214  ModeOpt += Mode;
215  CmdArgs.push_back(Args.MakeArgString(ModeOpt));
216  }
217 }
StringRef P
DiagnosticBuilder Diag(unsigned DiagID) const
Definition: Driver.h:110
for(const auto &A :T->param_types())
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:59
void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const
Definition: XRayArgs.cpp:172
constexpr XRayInstrMask All
Definition: XRayInstr.h:42
StringRef Filename
Definition: Format.cpp:1572
const Driver & getDriver() const
Definition: ToolChain.h:181
constexpr XRayInstrMask None
Definition: XRayInstr.h:38
Dataflow Directional Tag Classes.
const llvm::Triple & getTriple() const
Definition: ToolChain.h:183
XRayArgs(const ToolChain &TC, const llvm::opt::ArgList &Args)
Parses the XRay arguments from an argument list.
Definition: XRayArgs.cpp:33
XRayInstrMask parseXRayInstrValue(StringRef Value)
Definition: XRayInstr.cpp:19
ToolChain - Access to tools for a single platform.
Definition: ToolChain.h:88