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)).str() +
65 while (Pos < Expr.size() && std::isspace(Expr[Pos]))
69 Expected<bool> parseOrExpr() {
70 Expected<bool>
Result = parseAndExpr();
73 if (Pos + 1 < Expr.size() && Expr[Pos] ==
'|' && Expr[Pos + 1] ==
'|') {
75 Expected<bool> NextResult = parseAndExpr();
86 Expected<bool> parseAndExpr() {
87 Expected<bool>
Result = parsePrimary();
90 if (Pos + 1 < Expr.size() && Expr[Pos] ==
'&' && Expr[Pos + 1] ==
'&') {
92 Expected<bool> NextResult = parsePrimary();
103 Expected<bool> parsePrimary() {
107 if (Pos < Expr.size() && Expr[Pos] ==
'(') {
109 Expected<bool>
Result = parseOrExpr();
112 if (Result && (Pos >= Expr.size() || Expr[Pos] !=
')'))
114 std::to_string(Pos));
122 return parseComparison();
126 Expected<StringRef> parseStringLiteral() {
128 if (Pos >= Expr.size() || Expr[Pos] !=
'"')
130 std::to_string(Pos));
135 while (Pos < Expr.size() && Expr[Pos] !=
'"')
138 if (Pos >= Expr.size())
140 std::to_string(Start - 1));
142 StringRef
Result = Expr.slice(Start, Pos);
148 Expected<bool> parseComparison() {
153 while (Pos < Expr.size() && (std::isalnum(Expr[Pos]) || Expr[Pos] ==
'_'))
156 StringRef PropName = Expr.slice(Start, Pos);
157 if (PropName.
empty())
159 std::to_string(Pos));
164 if (Pos < Expr.size() && Expr[Pos] ==
'.') {
170 while (Pos < Expr.size() && std::isalpha(Expr[Pos]))
173 StringRef MethodName = Expr.slice(Start, Pos);
176 if (MethodName ==
"startswith") {
178 if (Pos >= Expr.size() || Expr[Pos] !=
'(')
180 "expected '(' after 'startswith' at position " +
181 std::to_string(Pos));
186 auto Prefix = parseStringLiteral();
188 return Prefix.takeError();
193 if (Pos >= Expr.size() || Expr[Pos] !=
')')
195 "expected ')' to close 'startswith' call at position " +
196 std::to_string(Pos));
201 auto StrIt = StringPropertyValues.find(PropName);
202 if (StrIt != StringPropertyValues.end())
203 return StrIt->second.starts_with(*Prefix);
206 if (DynamicProperties.lookup_or(PropName, UNKNOWN) == STRING)
210 "startswith is only valid on string properties not '" + PropName +
215 "' on property '" + PropName.
str() +
"'");
219 auto IntIt = IntPropertyValues.find(PropName);
220 if (IntIt != IntPropertyValues.end()) {
221 int64_t
LHS = IntIt->second;
225 if (Pos < Expr.size()) {
226 if (Expr[Pos] ==
'=' && Pos + 1 < Expr.size() && Expr[Pos + 1] ==
'=') {
229 }
else if (Expr[Pos] ==
'!' && Pos + 1 < Expr.size() &&
230 Expr[Pos + 1] ==
'=') {
233 }
else if (Expr[Pos] ==
'<' && Pos + 1 < Expr.size() &&
234 Expr[Pos + 1] ==
'=') {
237 }
else if (Expr[Pos] ==
'>' && Pos + 1 < Expr.size() &&
238 Expr[Pos + 1] ==
'=') {
241 }
else if (Expr[Pos] ==
'<') {
244 }
else if (Expr[Pos] ==
'>') {
249 ">, <=, >=) at position " +
250 std::to_string(Pos));
254 "expected comparison operator after property '" + PropName.
str() +
262 bool Negative =
false;
263 if (Pos < Expr.size() && Expr[Pos] ==
'-') {
268 size_t DigitStart = Pos;
269 while (Pos < Expr.size() && std::isdigit(Expr[Pos]))
272 if (Pos == DigitStart)
274 std::to_string(Pos));
276 StringRef ValueStr = Expr.slice(Start, Pos);
304 auto StrIt = StringPropertyValues.find(PropName);
305 if (StrIt != StringPropertyValues.end()) {
306 StringRef
LHS = StrIt->second;
309 enum OpKind {
EQ,
NE }
Op;
310 if (Pos < Expr.size()) {
311 if (Expr[Pos] ==
'=' && Pos + 1 < Expr.size() && Expr[Pos + 1] ==
'=') {
314 }
else if (Expr[Pos] ==
'!' && Pos + 1 < Expr.size() &&
315 Expr[Pos + 1] ==
'=') {
320 "' only supports == and != operators");
324 "expected comparison operator after string property '" +
325 PropName.
str() +
"'");
331 auto RHS = parseStringLiteral();
333 return RHS.takeError();
346 auto PtrIt = PointerPropertyValues.find(PropName);
347 if (PtrIt != PointerPropertyValues.end()) {
351 enum OpKind {
EQ,
NE }
Op;
352 if (Pos < Expr.size()) {
353 if (Expr[Pos] ==
'=' && Pos + 1 < Expr.size() && Expr[Pos + 1] ==
'=') {
356 }
else if (Expr[Pos] ==
'!' && Pos + 1 < Expr.size() &&
357 Expr[Pos + 1] ==
'=') {
362 "' only supports == and != operators");
366 "expected comparison operator after pointer property '" +
367 PropName.
str() +
"'");
374 while (Pos < Expr.size() && std::isalpha(Expr[Pos]))
377 StringRef
RHS = Expr.slice(Start, Pos);
380 "right-hand side, got '" +
386 IsNull =
C->isNullValue();
403 if (DynamicProperties.count(PropName))
408 PropName.
str() +
"'");
431 Value *ArgValue = Arg.GetterCB(V, *Arg.Ty, IConf, IIRB);
437 IntPropertyValues[Arg.Name] = CI->getSExtValue();
441 if (GV->isConstant() && GV->hasInitializer())
443 if (CDA->isCString())
444 StringPropertyValues[Arg.Name] = CDA->getAsCString();
447 PointerPropertyValues[Arg.Name] = ArgValue;
451 DynamicProperties[Arg.Name] =
452 Arg.Ty->isIntegerTy()
456 : (Arg.Ty->isPointerTy() ? POINTER : UNKNOWN));
460 FilterEvaluator
Evaluator(IO.
Filter, IntPropertyValues, StringPropertyValues,
461 PointerPropertyValues, DynamicProperties);
467 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.
std::string str() const
Get the contents as an std::string.
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, 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.