LLVM  14.0.0git
Option.cpp
Go to the documentation of this file.
1 //===- Option.cpp - Abstract Driver Options -------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/ADT/StringRef.h"
10 #include "llvm/ADT/Twine.h"
11 #include "llvm/Config/llvm-config.h"
12 #include "llvm/Option/Arg.h"
13 #include "llvm/Option/ArgList.h"
14 #include "llvm/Option/Option.h"
15 #include "llvm/Option/OptTable.h"
16 #include "llvm/Support/Compiler.h"
17 #include "llvm/Support/Debug.h"
20 #include <cassert>
21 #include <cstring>
22 
23 using namespace llvm;
24 using namespace llvm::opt;
25 
27  : Info(info), Owner(owner) {
28  // Multi-level aliases are not supported. This just simplifies option
29  // tracking, it is not an inherent limitation.
30  assert((!Info || !getAlias().isValid() || !getAlias().getAlias().isValid()) &&
31  "Multi-level aliases are not supported.");
32 
33  if (Info && getAliasArgs()) {
34  assert(getAlias().isValid() && "Only alias options can have alias args.");
35  assert(getKind() == FlagClass && "Only Flag aliases can have alias args.");
37  "Cannot provide alias args to a flag option.");
38  }
39 }
40 
41 void Option::print(raw_ostream &O) const {
42  O << "<";
43  switch (getKind()) {
44 #define P(N) case N: O << #N; break
45  P(GroupClass);
46  P(InputClass);
47  P(UnknownClass);
48  P(FlagClass);
49  P(JoinedClass);
50  P(ValuesClass);
58 #undef P
59  }
60 
61  if (Info->Prefixes) {
62  O << " Prefixes:[";
63  for (const char *const *Pre = Info->Prefixes; *Pre != nullptr; ++Pre) {
64  O << '"' << *Pre << (*(Pre + 1) == nullptr ? "\"" : "\", ");
65  }
66  O << ']';
67  }
68 
69  O << " Name:\"" << getName() << '"';
70 
71  const Option Group = getGroup();
72  if (Group.isValid()) {
73  O << " Group:";
74  Group.print(O);
75  }
76 
77  const Option Alias = getAlias();
78  if (Alias.isValid()) {
79  O << " Alias:";
80  Alias.print(O);
81  }
82 
83  if (getKind() == MultiArgClass)
84  O << " NumArgs:" << getNumArgs();
85 
86  O << ">\n";
87 }
88 
89 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
91 #endif
92 
93 bool Option::matches(OptSpecifier Opt) const {
94  // Aliases are never considered in matching, look through them.
95  const Option Alias = getAlias();
96  if (Alias.isValid())
97  return Alias.matches(Opt);
98 
99  // Check exact match.
100  if (getID() == Opt.getID())
101  return true;
102 
103  const Option Group = getGroup();
104  if (Group.isValid())
105  return Group.matches(Opt);
106  return false;
107 }
108 
109 Arg *Option::acceptInternal(const ArgList &Args, StringRef Spelling,
110  unsigned &Index) const {
111  size_t ArgSize = Spelling.size();
112  switch (getKind()) {
113  case FlagClass: {
114  if (ArgSize != strlen(Args.getArgString(Index)))
115  return nullptr;
116  return new Arg(*this, Spelling, Index++);
117  }
118  case JoinedClass: {
119  const char *Value = Args.getArgString(Index) + ArgSize;
120  return new Arg(*this, Spelling, Index++, Value);
121  }
122  case CommaJoinedClass: {
123  // Always matches.
124  const char *Str = Args.getArgString(Index) + ArgSize;
125  Arg *A = new Arg(*this, Spelling, Index++);
126 
127  // Parse out the comma separated values.
128  const char *Prev = Str;
129  for (;; ++Str) {
130  char c = *Str;
131 
132  if (!c || c == ',') {
133  if (Prev != Str) {
134  char *Value = new char[Str - Prev + 1];
135  memcpy(Value, Prev, Str - Prev);
136  Value[Str - Prev] = '\0';
137  A->getValues().push_back(Value);
138  }
139 
140  if (!c)
141  break;
142 
143  Prev = Str + 1;
144  }
145  }
146  A->setOwnsValues(true);
147 
148  return A;
149  }
150  case SeparateClass:
151  // Matches iff this is an exact match.
152  // FIXME: Avoid strlen.
153  if (ArgSize != strlen(Args.getArgString(Index)))
154  return nullptr;
155 
156  Index += 2;
157  if (Index > Args.getNumInputArgStrings() ||
158  Args.getArgString(Index - 1) == nullptr)
159  return nullptr;
160 
161  return new Arg(*this, Spelling, Index - 2, Args.getArgString(Index - 1));
162  case MultiArgClass: {
163  // Matches iff this is an exact match.
164  // FIXME: Avoid strlen.
165  if (ArgSize != strlen(Args.getArgString(Index)))
166  return nullptr;
167 
168  Index += 1 + getNumArgs();
169  if (Index > Args.getNumInputArgStrings())
170  return nullptr;
171 
172  Arg *A = new Arg(*this, Spelling, Index - 1 - getNumArgs(),
173  Args.getArgString(Index - getNumArgs()));
174  for (unsigned i = 1; i != getNumArgs(); ++i)
175  A->getValues().push_back(Args.getArgString(Index - getNumArgs() + i));
176  return A;
177  }
178  case JoinedOrSeparateClass: {
179  // If this is not an exact match, it is a joined arg.
180  // FIXME: Avoid strlen.
181  if (ArgSize != strlen(Args.getArgString(Index))) {
182  const char *Value = Args.getArgString(Index) + ArgSize;
183  return new Arg(*this, Spelling, Index++, Value);
184  }
185 
186  // Otherwise it must be separate.
187  Index += 2;
188  if (Index > Args.getNumInputArgStrings() ||
189  Args.getArgString(Index - 1) == nullptr)
190  return nullptr;
191 
192  return new Arg(*this, Spelling, Index - 2, Args.getArgString(Index - 1));
193  }
195  // Always matches.
196  Index += 2;
197  if (Index > Args.getNumInputArgStrings() ||
198  Args.getArgString(Index - 1) == nullptr)
199  return nullptr;
200 
201  return new Arg(*this, Spelling, Index - 2,
202  Args.getArgString(Index - 2) + ArgSize,
203  Args.getArgString(Index - 1));
204  case RemainingArgsClass: {
205  // Matches iff this is an exact match.
206  // FIXME: Avoid strlen.
207  if (ArgSize != strlen(Args.getArgString(Index)))
208  return nullptr;
209  Arg *A = new Arg(*this, Spelling, Index++);
210  while (Index < Args.getNumInputArgStrings() &&
211  Args.getArgString(Index) != nullptr)
212  A->getValues().push_back(Args.getArgString(Index++));
213  return A;
214  }
216  Arg *A = new Arg(*this, Spelling, Index);
217  if (ArgSize != strlen(Args.getArgString(Index))) {
218  // An inexact match means there is a joined arg.
219  A->getValues().push_back(Args.getArgString(Index) + ArgSize);
220  }
221  Index++;
222  while (Index < Args.getNumInputArgStrings() &&
223  Args.getArgString(Index) != nullptr)
224  A->getValues().push_back(Args.getArgString(Index++));
225  return A;
226  }
227 
228  default:
229  llvm_unreachable("Invalid option kind!");
230  }
231 }
232 
234  bool GroupedShortOption, unsigned &Index) const {
235  std::unique_ptr<Arg> A(GroupedShortOption && getKind() == FlagClass
236  ? new Arg(*this, CurArg, Index)
237  : acceptInternal(Args, CurArg, Index));
238  if (!A)
239  return nullptr;
240 
241  const Option &UnaliasedOption = getUnaliasedOption();
242  if (getID() == UnaliasedOption.getID())
243  return A.release();
244 
245  // "A" is an alias for a different flag. For most clients it's more convenient
246  // if this function returns unaliased Args, so create an unaliased arg for
247  // returning.
248 
249  // This creates a completely new Arg object for the unaliased Arg because
250  // the alias and the unaliased arg can have different Kinds and different
251  // Values (due to AliasArgs<>).
252 
253  // Get the spelling from the unaliased option.
254  StringRef UnaliasedSpelling = Args.MakeArgString(
255  Twine(UnaliasedOption.getPrefix()) + Twine(UnaliasedOption.getName()));
256 
257  // It's a bit weird that aliased and unaliased arg share one index, but
258  // the index is mostly use as a memory optimization in render().
259  // Due to this, ArgList::getArgString(A->getIndex()) will return the spelling
260  // of the aliased arg always, while A->getSpelling() returns either the
261  // unaliased or the aliased arg, depending on which Arg object it's called on.
262  Arg *UnaliasedA = new Arg(UnaliasedOption, UnaliasedSpelling, A->getIndex());
263  Arg *RawA = A.get();
264  UnaliasedA->setAlias(std::move(A));
265 
266  if (getKind() != FlagClass) {
267  // Values are usually owned by the ArgList. The exception are
268  // CommaJoined flags, where the Arg owns the values. For aliased flags,
269  // make the unaliased Arg the owner of the values.
270  // FIXME: There aren't many uses of CommaJoined -- try removing
271  // CommaJoined in favor of just calling StringRef::split(',') instead.
272  UnaliasedA->getValues() = RawA->getValues();
273  UnaliasedA->setOwnsValues(RawA->getOwnsValues());
274  RawA->setOwnsValues(false);
275  return UnaliasedA;
276  }
277 
278  // FlagClass aliases can have AliasArgs<>; add those to the unaliased arg.
279  if (const char *Val = getAliasArgs()) {
280  while (*Val != '\0') {
281  UnaliasedA->getValues().push_back(Val);
282 
283  // Move past the '\0' to the next argument.
284  Val += strlen(Val) + 1;
285  }
286  }
287  if (UnaliasedOption.getKind() == JoinedClass && !getAliasArgs())
288  // A Flag alias for a Joined option must provide an argument.
289  UnaliasedA->getValues().push_back("");
290  return UnaliasedA;
291 }
llvm::opt::Option::dump
void dump() const
Definition: Option.cpp:90
i
i
Definition: README.txt:29
llvm::opt::OptTable
Provide access to the Option info table.
Definition: OptTable.h:40
Option.h
llvm::opt::Option::Option
Option(const OptTable::Info *Info, const OptTable *Owner)
Definition: Option.cpp:26
LLVM_DUMP_METHOD
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:491
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::opt::Option::MultiArgClass
@ MultiArgClass
Definition: Option.h:64
llvm::opt::Arg
A concrete instance of a particular driver option.
Definition: Arg.h:34
llvm::opt::Option::CommaJoinedClass
@ CommaJoinedClass
Definition: Option.h:63
StringRef.h
llvm::opt::ArgList
ArgList - Ordered collection of driver arguments.
Definition: ArgList.h:116
ErrorHandling.h
llvm::opt::Option::getUnaliasedOption
const Option getUnaliasedOption() const
getUnaliasedOption - Return the final option this option aliases (itself, if the option has no alias)...
Definition: Option.h:188
llvm::opt::Option::Info
const OptTable::Info * Info
Definition: Option.h:77
llvm::opt::Option::InputClass
@ InputClass
Definition: Option.h:55
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:206
llvm::opt::Arg::setAlias
void setAlias(std::unique_ptr< Arg > Alias)
Definition: Arg.h:101
llvm::opt::Option::getAliasArgs
const char * getAliasArgs() const
Get the alias arguments as a \0 separated list.
Definition: Option.h:117
llvm::opt::Arg::getValues
SmallVectorImpl< const char * > & getValues()
Definition: Arg.h:117
llvm::opt::Arg::setOwnsValues
void setOwnsValues(bool Value) const
Definition: Arg.h:104
llvm::ARM_PROC::A
@ A
Definition: ARMBaseInfo.h:34
Twine.h
llvm::opt::Option::RemainingArgsJoinedClass
@ RemainingArgsJoinedClass
Definition: Option.h:62
llvm::opt::Option::getID
unsigned getID() const
Definition: Option.h:87
llvm::opt::Option::matches
bool matches(OptSpecifier ID) const
matches - Predicate for whether this option is part of the given option (which may be a group).
Definition: Option.cpp:93
llvm::opt::Arg::getOwnsValues
bool getOwnsValues() const
Definition: Arg.h:103
llvm::opt
Definition: Arg.h:26
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::opt::Option::SeparateClass
@ SeparateClass
Definition: Option.h:60
llvm::opt::Option::JoinedAndSeparateClass
@ JoinedAndSeparateClass
Definition: Option.h:66
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
c
the resulting code requires compare and branches when and if the revised code is with conditional branches instead of More there is a byte word extend before each where there should be only and the condition codes are not remembered when the same two values are compared twice More LSR enhancements i8 and i32 load store addressing modes are identical int int c
Definition: README.txt:418
llvm::opt::Option::print
void print(raw_ostream &O) const
Definition: Option.cpp:41
llvm::opt::OptSpecifier
OptSpecifier - Wrapper class for abstracting references to option IDs.
Definition: OptSpecifier.h:18
llvm::opt::Option::UnknownClass
@ UnknownClass
Definition: Option.h:56
llvm::opt::Option::getKind
OptionClass getKind() const
Definition: Option.h:92
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:192
Index
uint32_t Index
Definition: ELFObjHandler.cpp:84
OptTable.h
llvm::opt::Option::getName
StringRef getName() const
Get the name of this option without any prefix.
Definition: Option.h:98
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::opt::Option::getPrefix
StringRef getPrefix() const
Get the default prefix for this option.
Definition: Option.h:126
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::opt::Option::isValid
bool isValid() const
Definition: Option.h:83
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::opt::Option::ValuesClass
@ ValuesClass
Definition: Option.h:59
llvm::opt::Option::getNumArgs
unsigned getNumArgs() const
Definition: Option.h:150
llvm::opt::Option::GroupClass
@ GroupClass
Definition: Option.h:54
info
lazy value info
Definition: LazyValueInfo.cpp:59
Arg.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::opt::Option::RemainingArgsClass
@ RemainingArgsClass
Definition: Option.h:61
Compiler.h
llvm::opt::OptTable::Info::Prefixes
const char *const * Prefixes
A null terminated array of prefix strings to apply to name while matching.
Definition: OptTable.h:46
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
ArgList.h
llvm::opt::Option
Option - Abstract representation for a single form of driver argument.
Definition: Option.h:51
llvm::opt::Option::JoinedOrSeparateClass
@ JoinedOrSeparateClass
Definition: Option.h:65
llvm::opt::Option::FlagClass
@ FlagClass
Definition: Option.h:57
llvm::opt::Option::getGroup
const Option getGroup() const
Definition: Option.h:103
P
#define P(N)
llvm::opt::OptTable::Info
Entry for a single option instance in the option data table.
Definition: OptTable.h:43
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
llvm::opt::Option::getAlias
const Option getAlias() const
Definition: Option.h:109
raw_ostream.h
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
llvm::opt::Option::JoinedClass
@ JoinedClass
Definition: Option.h:58
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
Debug.h
llvm::opt::OptSpecifier::getID
unsigned getID() const
Definition: OptSpecifier.h:29
llvm::opt::Option::accept
Arg * accept(const ArgList &Args, StringRef CurArg, bool GroupedShortOption, unsigned &Index) const
accept - Potentially accept the current argument, returning a new Arg instance, or 0 if the option do...
Definition: Option.cpp:233