int64_t CounterMappingContext::evaluate(const Counter &C, std::error_code *EC) const { switch (C.getKind()) { case Counter::Zero: return 0; case Counter::CounterValueReference: if (C.getCounterID() >= CounterValues.size()) { if (EC) *EC = std::make_error_code(std::errc::argument_out_of_domain); break; } return CounterValues[C.getCounterID()]; case Counter::Expression: { if (C.getExpressionID() >= Expressions.size()) { if (EC) *EC = std::make_error_code(std::errc::argument_out_of_domain); break; } const auto &E = Expressions[C.getExpressionID()]; auto LHS = evaluate(E.LHS, EC); if (EC && *EC) return 0; auto RHS = evaluate(E.RHS, EC); if (EC && *EC) return 0; return E.Kind == CounterExpression::Subtract ? LHS - RHS : LHS + RHS; } } return 0; }
void CounterMappingContext::dump(const Counter &C, llvm::raw_ostream &OS) const { switch (C.getKind()) { case Counter::Zero: OS << '0'; return; case Counter::CounterValueReference: OS << '#' << C.getCounterID(); break; case Counter::Expression: { if (C.getExpressionID() >= Expressions.size()) return; const auto &E = Expressions[C.getExpressionID()]; OS << '('; dump(E.LHS, OS); OS << (E.Kind == CounterExpression::Subtract ? " - " : " + "); dump(E.RHS, OS); OS << ')'; break; } } if (CounterValues.empty()) return; ErrorOr<int64_t> Value = evaluate(C); if (!Value) return; OS << '[' << *Value << ']'; }
void PrintTo(const Counter &C, ::std::ostream *os) { if (C.isZero()) *os << "Zero"; else if (C.isExpression()) *os << "Expression " << C.getExpressionID(); else *os << "Counter " << C.getCounterID(); }
ErrorOr<int64_t> CounterMappingContext::evaluate(const Counter &C) const { switch (C.getKind()) { case Counter::Zero: return 0; case Counter::CounterValueReference: if (C.getCounterID() >= CounterValues.size()) return std::make_error_code(std::errc::argument_out_of_domain); return CounterValues[C.getCounterID()]; case Counter::Expression: { if (C.getExpressionID() >= Expressions.size()) return std::make_error_code(std::errc::argument_out_of_domain); const auto &E = Expressions[C.getExpressionID()]; ErrorOr<int64_t> LHS = evaluate(E.LHS); if (!LHS) return LHS; ErrorOr<int64_t> RHS = evaluate(E.RHS); if (!RHS) return RHS; return E.Kind == CounterExpression::Subtract ? *LHS - *RHS : *LHS + *RHS; } } llvm_unreachable("Unhandled CounterKind"); }
void CounterExpressionBuilder::extractTerms(Counter C, int Sign) { switch (C.getKind()) { case Counter::Zero: break; case Counter::CounterValueReference: Terms[C.getCounterID()] += Sign; break; case Counter::Expression: const auto &E = Expressions[C.getExpressionID()]; extractTerms(E.LHS, Sign); extractTerms(E.RHS, E.Kind == CounterExpression::Subtract ? -Sign : Sign); break; } }
void CounterExpressionBuilder::extractTerms( Counter C, int Sign, SmallVectorImpl<std::pair<unsigned, int>> &Terms) { switch (C.getKind()) { case Counter::Zero: break; case Counter::CounterValueReference: Terms.push_back(std::make_pair(C.getCounterID(), Sign)); break; case Counter::Expression: const auto &E = Expressions[C.getExpressionID()]; extractTerms(E.LHS, Sign, Terms); extractTerms(E.RHS, E.Kind == CounterExpression::Subtract ? -Sign : Sign, Terms); break; } }
void CounterExpressionBuilder::extractTerms(Counter C, int Factor, SmallVectorImpl<Term> &Terms) { switch (C.getKind()) { case Counter::Zero: break; case Counter::CounterValueReference: Terms.emplace_back(C.getCounterID(), Factor); break; case Counter::Expression: const auto &E = Expressions[C.getExpressionID()]; extractTerms(E.LHS, Factor, Terms); extractTerms( E.RHS, E.Kind == CounterExpression::Subtract ? -Factor : Factor, Terms); break; } }