21enum PropertyType { INT, STRING, POINTER,
UNKNOWN };
27class FilterEvaluator {
29 DenseMap<StringRef, APInt> &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, DenseMap<StringRef, APInt> &IntPropertyValues,
38 DenseMap<StringRef, StringRef> &StringPropertyValues,
39 DenseMap<StringRef, Value *> &PointerPropertyValues,
40 DenseMap<StringRef, PropertyType> &DynamicProperties,
41 StringMap<int32_t> &FlagNameVals)
42 : Expr(Expr), IntPropertyValues(IntPropertyValues),
43 StringPropertyValues(StringPropertyValues),
44 PointerPropertyValues(PointerPropertyValues),
45 DynamicProperties(DynamicProperties), FlagNameVals(FlagNameVals) {}
51 Expected<bool>
Result = parseOrExpr();
55 if (Pos < Expr.size() && Result)
57 "unexpected characters at position " + std::to_string(Pos) +
": '" +
58 Expr.substr(Pos, std::min<size_t>(10, Expr.size() - Pos)) +
"'");
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 if (Pos < Expr.size() && Expr[Pos] ==
'!') {
160 while (Pos < Expr.size() && (std::isalnum(Expr[Pos]) || Expr[Pos] ==
'_'))
163 StringRef PropName = Expr.slice(Start, Pos);
164 if (PropName.
empty())
166 std::to_string(Pos));
171 if (Pos < Expr.size() && Expr[Pos] ==
'.') {
177 while (Pos < Expr.size() && std::isalpha(Expr[Pos]))
180 StringRef FieldName = Expr.slice(Start, Pos);
184 if (PropName ==
"flags") {
185 auto FlagValIt = IntPropertyValues.find(
"flags");
186 if (FlagValIt != IntPropertyValues.end()) {
187 auto FlagNameIt = FlagNameVals.find(FieldName);
188 if (FlagNameIt == FlagNameVals.end())
190 return ((
static_cast<int32_t
>(FlagValIt->second.getZExtValue()) &
191 FlagNameIt->second) == FlagNameIt->second) ^
197 if (FieldName ==
"startswith") {
199 if (Pos >= Expr.size() || Expr[Pos] !=
'(')
201 "expected '(' after 'startswith' at position " +
202 std::to_string(Pos));
207 auto Prefix = parseStringLiteral();
209 return Prefix.takeError();
214 if (Pos >= Expr.size() || Expr[Pos] !=
')')
216 "expected ')' to close 'startswith' call at position " +
217 std::to_string(Pos));
222 auto StrIt = StringPropertyValues.find(PropName);
223 if (StrIt != StringPropertyValues.end())
224 return StrIt->second.starts_with(*Prefix) ^
LogicalNot;
227 if (DynamicProperties.lookup_or(PropName, UNKNOWN) == STRING)
231 "startswith is only valid on string properties not '" + PropName +
236 "' on property '" + PropName +
"'");
237 }
else if (LogicalNot) {
239 std::to_string(Start));
243 auto IntIt = IntPropertyValues.find(PropName);
244 if (IntIt != IntPropertyValues.end()) {
245 auto LHS = IntIt->second;
249 if (Pos < Expr.size()) {
250 if (Expr[Pos] ==
'=' && Pos + 1 < Expr.size() && Expr[Pos + 1] ==
'=') {
253 }
else if (Expr[Pos] ==
'!' && Pos + 1 < Expr.size() &&
254 Expr[Pos + 1] ==
'=') {
257 }
else if (Expr[Pos] ==
'<' && Pos + 1 < Expr.size() &&
258 Expr[Pos + 1] ==
'=') {
261 }
else if (Expr[Pos] ==
'>' && Pos + 1 < Expr.size() &&
262 Expr[Pos + 1] ==
'=') {
265 }
else if (Expr[Pos] ==
'<') {
268 }
else if (Expr[Pos] ==
'>') {
273 ">, <=, >=) at position " +
274 std::to_string(Pos));
278 "expected comparison operator after property '" + PropName +
"'");
285 bool Negative =
false;
286 if (Pos < Expr.size() && Expr[Pos] ==
'-') {
291 size_t DigitStart = Pos;
292 uint8_t DigitRadix = 10;
295 if (Pos + 1 < Expr.size() && Expr[Pos] ==
'0' && Expr[Pos + 1] ==
'b') {
296 DigitStart = (Pos += 2);
298 while (Pos < Expr.size() && (Expr[Pos] ==
'0' || Expr[Pos] ==
'1'))
302 while (Pos < Expr.size() && std::isdigit(Expr[Pos]))
306 if (Pos == DigitStart)
308 std::to_string(Pos));
310 StringRef ValueStr = Expr.slice(DigitStart, Pos);
311 APInt
RHS(
LHS.getBitWidth(), ValueStr, DigitRadix);
335 auto StrIt = StringPropertyValues.find(PropName);
336 if (StrIt != StringPropertyValues.end()) {
337 StringRef
LHS = StrIt->second;
340 enum OpKind {
EQ,
NE }
Op;
341 if (Pos < Expr.size()) {
342 if (Expr[Pos] ==
'=' && Pos + 1 < Expr.size() && Expr[Pos + 1] ==
'=') {
345 }
else if (Expr[Pos] ==
'!' && Pos + 1 < Expr.size() &&
346 Expr[Pos + 1] ==
'=') {
351 "' only supports == and != operators");
355 "expected comparison operator after string property '" + PropName +
362 auto RHS = parseStringLiteral();
364 return RHS.takeError();
377 auto PtrIt = PointerPropertyValues.find(PropName);
378 if (PtrIt != PointerPropertyValues.end()) {
382 enum OpKind {
EQ,
NE }
Op;
383 if (Pos < Expr.size()) {
384 if (Expr[Pos] ==
'=' && Pos + 1 < Expr.size() && Expr[Pos + 1] ==
'=') {
387 }
else if (Expr[Pos] ==
'!' && Pos + 1 < Expr.size() &&
388 Expr[Pos + 1] ==
'=') {
393 "' only supports == and != operators");
397 "expected comparison operator after pointer property '" + PropName +
405 while (Pos < Expr.size() && std::isalpha(Expr[Pos]))
408 StringRef
RHS = Expr.slice(Start, Pos);
411 "right-hand side, got '" +
417 IsNull =
C->isNullValue();
434 if (DynamicProperties.count(PropName))
462 Value *ArgValue = Arg.GetterCB(V, *Arg.Ty, IConf, IIRB);
472 IntPropertyValues[Arg.Name] = CI->getValue();
476 if (GV->isConstant() && GV->hasInitializer())
478 if (CDA->isCString())
479 StringPropertyValues[Arg.Name] = CDA->getAsCString();
482 PointerPropertyValues[Arg.Name] = ArgValue;
486 DynamicProperties[Arg.Name] =
487 Arg.Ty->isIntegerTy()
491 : (Arg.Ty->isPointerTy() ? POINTER : UNKNOWN));
495 FilterEvaluator
Evaluator(IO.
Filter, IntPropertyValues, StringPropertyValues,
496 PointerPropertyValues, DynamicProperties,
503 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.
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.