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;
33 StringMap<int32_t> &FlagNameVals;
37 FilterEvaluator(StringRef Expr,
38 DenseMap<StringRef, int64_t> &IntPropertyValues,
39 DenseMap<StringRef, StringRef> &StringPropertyValues,
40 DenseMap<StringRef, Value *> &PointerPropertyValues,
41 DenseMap<StringRef, PropertyType> &DynamicProperties,
42 StringMap<int32_t> &FlagNameVals)
43 : Expr(Expr), IntPropertyValues(IntPropertyValues),
44 StringPropertyValues(StringPropertyValues),
45 PointerPropertyValues(PointerPropertyValues),
46 DynamicProperties(DynamicProperties), FlagNameVals(FlagNameVals) {}
52 Expected<bool>
Result = parseOrExpr();
56 if (Pos < Expr.size() && Result)
58 "unexpected characters at position " + std::to_string(Pos) +
": '" +
59 Expr.substr(Pos, std::min<size_t>(10, Expr.size() - Pos)) +
"'");
66 while (Pos < Expr.size() && std::isspace(Expr[Pos]))
70 Expected<bool> parseOrExpr() {
71 Expected<bool>
Result = parseAndExpr();
74 if (Pos + 1 < Expr.size() && Expr[Pos] ==
'|' && Expr[Pos + 1] ==
'|') {
76 Expected<bool> NextResult = parseAndExpr();
87 Expected<bool> parseAndExpr() {
88 Expected<bool>
Result = parsePrimary();
91 if (Pos + 1 < Expr.size() && Expr[Pos] ==
'&' && Expr[Pos + 1] ==
'&') {
93 Expected<bool> NextResult = parsePrimary();
104 Expected<bool> parsePrimary() {
108 if (Pos < Expr.size() && Expr[Pos] ==
'(') {
110 Expected<bool>
Result = parseOrExpr();
113 if (Result && (Pos >= Expr.size() || Expr[Pos] !=
')'))
115 std::to_string(Pos));
123 return parseComparison();
127 Expected<StringRef> parseStringLiteral() {
129 if (Pos >= Expr.size() || Expr[Pos] !=
'"')
131 std::to_string(Pos));
136 while (Pos < Expr.size() && Expr[Pos] !=
'"')
139 if (Pos >= Expr.size())
141 std::to_string(Start - 1));
143 StringRef
Result = Expr.slice(Start, Pos);
149 Expected<bool> parseComparison() {
154 if (Pos < Expr.size() && Expr[Pos] ==
'!') {
161 while (Pos < Expr.size() && (std::isalnum(Expr[Pos]) || Expr[Pos] ==
'_'))
164 StringRef PropName = Expr.slice(Start, Pos);
165 if (PropName.
empty())
167 std::to_string(Pos));
172 if (Pos < Expr.size() && Expr[Pos] ==
'.') {
178 while (Pos < Expr.size() && std::isalpha(Expr[Pos]))
181 StringRef FieldName = Expr.slice(Start, Pos);
185 if (PropName ==
"flags") {
186 auto FlagValIt = IntPropertyValues.find(
"flags");
187 if (FlagValIt != IntPropertyValues.end()) {
188 auto FlagNameIt = FlagNameVals.find(FieldName);
189 if (FlagNameIt == FlagNameVals.end())
191 return ((
static_cast<int32_t
>(FlagValIt->second) &
192 FlagNameIt->second) == FlagNameIt->second) ^
198 if (FieldName ==
"startswith") {
200 if (Pos >= Expr.size() || Expr[Pos] !=
'(')
202 "expected '(' after 'startswith' at position " +
203 std::to_string(Pos));
208 auto Prefix = parseStringLiteral();
210 return Prefix.takeError();
215 if (Pos >= Expr.size() || Expr[Pos] !=
')')
217 "expected ')' to close 'startswith' call at position " +
218 std::to_string(Pos));
223 auto StrIt = StringPropertyValues.find(PropName);
224 if (StrIt != StringPropertyValues.end())
225 return StrIt->second.starts_with(*Prefix) ^
LogicalNot;
228 if (DynamicProperties.lookup_or(PropName, UNKNOWN) == STRING)
232 "startswith is only valid on string properties not '" + PropName +
237 "' on property '" + PropName +
"'");
238 }
else if (LogicalNot) {
240 std::to_string(Start));
244 auto IntIt = IntPropertyValues.find(PropName);
245 if (IntIt != IntPropertyValues.end()) {
246 int64_t
LHS = IntIt->second;
250 if (Pos < Expr.size()) {
251 if (Expr[Pos] ==
'=' && Pos + 1 < Expr.size() && Expr[Pos + 1] ==
'=') {
254 }
else if (Expr[Pos] ==
'!' && Pos + 1 < Expr.size() &&
255 Expr[Pos + 1] ==
'=') {
258 }
else if (Expr[Pos] ==
'<' && Pos + 1 < Expr.size() &&
259 Expr[Pos + 1] ==
'=') {
262 }
else if (Expr[Pos] ==
'>' && Pos + 1 < Expr.size() &&
263 Expr[Pos + 1] ==
'=') {
266 }
else if (Expr[Pos] ==
'<') {
269 }
else if (Expr[Pos] ==
'>') {
274 ">, <=, >=) at position " +
275 std::to_string(Pos));
279 "expected comparison operator after property '" + PropName +
"'");
286 bool Negative =
false;
287 if (Pos < Expr.size() && Expr[Pos] ==
'-') {
292 size_t DigitStart = Pos;
295 if (Pos + 1 < Expr.size() && Expr[Pos] ==
'0' && Expr[Pos + 1] ==
'b') {
297 while (Pos < Expr.size() && (Expr[Pos] ==
'0' || Expr[Pos] ==
'1'))
301 while (Pos < Expr.size() && std::isdigit(Expr[Pos]))
305 if (Pos == DigitStart)
307 std::to_string(Pos));
309 StringRef ValueStr = Expr.slice(Start, Pos);
336 auto StrIt = StringPropertyValues.find(PropName);
337 if (StrIt != StringPropertyValues.end()) {
338 StringRef
LHS = StrIt->second;
341 enum OpKind {
EQ,
NE }
Op;
342 if (Pos < Expr.size()) {
343 if (Expr[Pos] ==
'=' && Pos + 1 < Expr.size() && Expr[Pos + 1] ==
'=') {
346 }
else if (Expr[Pos] ==
'!' && Pos + 1 < Expr.size() &&
347 Expr[Pos + 1] ==
'=') {
352 "' only supports == and != operators");
356 "expected comparison operator after string property '" + PropName +
363 auto RHS = parseStringLiteral();
365 return RHS.takeError();
378 auto PtrIt = PointerPropertyValues.find(PropName);
379 if (PtrIt != PointerPropertyValues.end()) {
383 enum OpKind {
EQ,
NE }
Op;
384 if (Pos < Expr.size()) {
385 if (Expr[Pos] ==
'=' && Pos + 1 < Expr.size() && Expr[Pos + 1] ==
'=') {
388 }
else if (Expr[Pos] ==
'!' && Pos + 1 < Expr.size() &&
389 Expr[Pos + 1] ==
'=') {
394 "' only supports == and != operators");
398 "expected comparison operator after pointer property '" + PropName +
406 while (Pos < Expr.size() && std::isalpha(Expr[Pos]))
409 StringRef
RHS = Expr.slice(Start, Pos);
412 "right-hand side, got '" +
418 IsNull =
C->isNullValue();
435 if (DynamicProperties.count(PropName))
463 Value *ArgValue = Arg.GetterCB(V, *Arg.Ty, IConf, IIRB);
473 IntPropertyValues[Arg.Name] = CI->getSExtValue();
477 if (GV->isConstant() && GV->hasInitializer())
479 if (CDA->isCString())
480 StringPropertyValues[Arg.Name] = CDA->getAsCString();
483 PointerPropertyValues[Arg.Name] = ArgValue;
487 DynamicProperties[Arg.Name] =
488 Arg.Ty->isIntegerTy()
492 : (Arg.Ty->isPointerTy() ? POINTER : UNKNOWN));
496 FilterEvaluator
Evaluator(IO.
Filter, IntPropertyValues, StringPropertyValues,
497 PointerPropertyValues, DynamicProperties,
504 Twine(
"malformed filter expression for instrumentation opportunity '") +
static bool evaluate(const MCSpecifierExpr &Expr, MCValue &Res, const MCAssembler *Asm)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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.
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.
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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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.
StringMap< int32_t > FlagNames
Flag names and their integer bitmask values.
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.