21enum PropertyType { INT, STRING, POINTER,
UNKNOWN };
27class FilterEvaluator {
29 DenseMap<StringRef, int64_t> &IntPropertyValues;
30 DenseMap<StringRef, StringRef> &StringPropertyValues;
31 DenseMap<StringRef, Value *> &PointerPropertyValues;
32 DenseMap<StringRef, PropertyType> &DynamicProperties;
36 FilterEvaluator(StringRef Expr,
37 DenseMap<StringRef, int64_t> &IntPropertyValues,
38 DenseMap<StringRef, StringRef> &StringPropertyValues,
39 DenseMap<StringRef, Value *> &PointerPropertyValues,
40 DenseMap<StringRef, PropertyType> &DynamicProperties)
41 : Expr(Expr), IntPropertyValues(IntPropertyValues),
42 StringPropertyValues(StringPropertyValues),
43 PointerPropertyValues(PointerPropertyValues),
44 DynamicProperties(DynamicProperties) {}
50 Expected<bool>
Result = parseOrExpr();
54 if (Pos < Expr.size() && Result)
56 "unexpected characters at position " + std::to_string(Pos) +
": '" +
57 Expr.substr(Pos, std::min<size_t>(10, Expr.size() - Pos)) +
"'");
64 while (Pos < Expr.size() && std::isspace(Expr[Pos]))
68 Expected<bool> parseOrExpr() {
69 Expected<bool>
Result = parseAndExpr();
72 if (Pos + 1 < Expr.size() && Expr[Pos] ==
'|' && Expr[Pos + 1] ==
'|') {
74 Expected<bool> NextResult = parseAndExpr();
85 Expected<bool> parseAndExpr() {
86 Expected<bool>
Result = parsePrimary();
89 if (Pos + 1 < Expr.size() && Expr[Pos] ==
'&' && Expr[Pos + 1] ==
'&') {
91 Expected<bool> NextResult = parsePrimary();
102 Expected<bool> parsePrimary() {
106 if (Pos < Expr.size() && Expr[Pos] ==
'(') {
108 Expected<bool>
Result = parseOrExpr();
111 if (Result && (Pos >= Expr.size() || Expr[Pos] !=
')'))
113 std::to_string(Pos));
121 return parseComparison();
125 Expected<StringRef> parseStringLiteral() {
127 if (Pos >= Expr.size() || Expr[Pos] !=
'"')
129 std::to_string(Pos));
134 while (Pos < Expr.size() && Expr[Pos] !=
'"')
137 if (Pos >= Expr.size())
139 std::to_string(Start - 1));
141 StringRef
Result = Expr.slice(Start, Pos);
147 Expected<bool> parseComparison() {
152 while (Pos < Expr.size() && (std::isalnum(Expr[Pos]) || Expr[Pos] ==
'_'))
155 StringRef PropName = Expr.slice(Start, Pos);
156 if (PropName.
empty())
158 std::to_string(Pos));
163 if (Pos < Expr.size() && Expr[Pos] ==
'.') {
169 while (Pos < Expr.size() && std::isalpha(Expr[Pos]))
172 StringRef MethodName = Expr.slice(Start, Pos);
175 if (MethodName ==
"startswith") {
177 if (Pos >= Expr.size() || Expr[Pos] !=
'(')
179 "expected '(' after 'startswith' at position " +
180 std::to_string(Pos));
185 auto Prefix = parseStringLiteral();
187 return Prefix.takeError();
192 if (Pos >= Expr.size() || Expr[Pos] !=
')')
194 "expected ')' to close 'startswith' call at position " +
195 std::to_string(Pos));
200 auto StrIt = StringPropertyValues.find(PropName);
201 if (StrIt != StringPropertyValues.end())
202 return StrIt->second.starts_with(*Prefix);
205 if (DynamicProperties.lookup_or(PropName, UNKNOWN) == STRING)
209 "startswith is only valid on string properties not '" + PropName +
214 "' on property '" + PropName +
"'");
218 auto IntIt = IntPropertyValues.find(PropName);
219 if (IntIt != IntPropertyValues.end()) {
220 int64_t
LHS = IntIt->second;
224 if (Pos < Expr.size()) {
225 if (Expr[Pos] ==
'=' && Pos + 1 < Expr.size() && Expr[Pos + 1] ==
'=') {
228 }
else if (Expr[Pos] ==
'!' && Pos + 1 < Expr.size() &&
229 Expr[Pos + 1] ==
'=') {
232 }
else if (Expr[Pos] ==
'<' && Pos + 1 < Expr.size() &&
233 Expr[Pos + 1] ==
'=') {
236 }
else if (Expr[Pos] ==
'>' && Pos + 1 < Expr.size() &&
237 Expr[Pos + 1] ==
'=') {
240 }
else if (Expr[Pos] ==
'<') {
243 }
else if (Expr[Pos] ==
'>') {
248 ">, <=, >=) at position " +
249 std::to_string(Pos));
253 "expected comparison operator after property '" + PropName +
"'");
260 bool Negative =
false;
261 if (Pos < Expr.size() && Expr[Pos] ==
'-') {
266 size_t DigitStart = Pos;
267 while (Pos < Expr.size() && std::isdigit(Expr[Pos]))
270 if (Pos == DigitStart)
272 std::to_string(Pos));
274 StringRef ValueStr = Expr.slice(Start, Pos);
301 auto StrIt = StringPropertyValues.find(PropName);
302 if (StrIt != StringPropertyValues.end()) {
303 StringRef
LHS = StrIt->second;
306 enum OpKind {
EQ,
NE }
Op;
307 if (Pos < Expr.size()) {
308 if (Expr[Pos] ==
'=' && Pos + 1 < Expr.size() && Expr[Pos + 1] ==
'=') {
311 }
else if (Expr[Pos] ==
'!' && Pos + 1 < Expr.size() &&
312 Expr[Pos + 1] ==
'=') {
317 "' only supports == and != operators");
321 "expected comparison operator after string property '" + PropName +
328 auto RHS = parseStringLiteral();
330 return RHS.takeError();
343 auto PtrIt = PointerPropertyValues.find(PropName);
344 if (PtrIt != PointerPropertyValues.end()) {
348 enum OpKind {
EQ,
NE }
Op;
349 if (Pos < Expr.size()) {
350 if (Expr[Pos] ==
'=' && Pos + 1 < Expr.size() && Expr[Pos + 1] ==
'=') {
353 }
else if (Expr[Pos] ==
'!' && Pos + 1 < Expr.size() &&
354 Expr[Pos + 1] ==
'=') {
359 "' only supports == and != operators");
363 "expected comparison operator after pointer property '" + PropName +
371 while (Pos < Expr.size() && std::isalpha(Expr[Pos]))
374 StringRef
RHS = Expr.slice(Start, Pos);
377 "right-hand side, got '" +
383 IsNull =
C->isNullValue();
400 if (DynamicProperties.count(PropName))
428 Value *ArgValue = Arg.GetterCB(V, *Arg.Ty, IConf, IIRB);
438 IntPropertyValues[Arg.Name] = CI->getSExtValue();
442 if (GV->isConstant() && GV->hasInitializer())
444 if (CDA->isCString())
445 StringPropertyValues[Arg.Name] = CDA->getAsCString();
448 PointerPropertyValues[Arg.Name] = ArgValue;
452 DynamicProperties[Arg.Name] =
453 Arg.Ty->isIntegerTy()
457 : (Arg.Ty->isPointerTy() ? POINTER : UNKNOWN));
461 FilterEvaluator
Evaluator(IO.
Filter, IntPropertyValues, StringPropertyValues,
462 PointerPropertyValues, DynamicProperties);
468 Twine(
"malformed filter expression for instrumentation opportunity '") +
static bool evaluate(const MCSpecifierExpr &Expr, MCValue &Res, const MCAssembler *Asm)
This file defines the DenseMap class.
static Cursor skipWhitespace(Cursor C)
Skip the leading whitespace characters and return the updated cursor.
Diagnostic information for IR instrumentation reporting.
This class evaluates LLVM IR, producing the Constant representing each SSA instruction.
Tagged union holding either a T or a Error.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr bool empty() const
Check if the string is empty.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
bool isPointerTy() const
True if this is an instance of PointerType.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI bool evaluateFilter(Value &V, bool &Changed, InstrumentationOpportunity &IO, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
Evaluate the filter expression against the current instrumentation opportunity.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
DWARFExpression::Operation Op
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
The class that contains the configuration for the instrumentor.
Base class for instrumentation opportunities.
virtual StringRef getName() const =0
Get the name of the instrumentation opportunity.
SmallVector< IRTArg > IRTArgs
The list of possible arguments for the instrumentation runtime function.
StringRef Filter
A filter expression to be matched against runtime property values.
An IR builder augmented with extra information for the instrumentor pass.