Skip to content

Commit

Permalink
[FileCheck, 4/4] NFC: Stop using ExpressionValue
Browse files Browse the repository at this point in the history
Use APInt directly instead.

Depends On D150880

Reviewed By: arichardson

Differential Revision: https://reviews.llvm.org/D154430
  • Loading branch information
RoboTux committed Aug 7, 2023
1 parent e894c3d commit e15e969
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 149 deletions.
89 changes: 34 additions & 55 deletions llvm/lib/FileCheck/FileCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,7 @@ Expected<std::string> ExpressionFormat::getWildcardRegex() const {
}

Expected<std::string>
ExpressionFormat::getMatchingString(ExpressionValue IntegerValue) const {
APInt IntValue = IntegerValue.getAPIntValue();
ExpressionFormat::getMatchingString(APInt IntValue) const {
if (Value != Kind::Signed && IntValue.isNegative())
return make_error<OverflowError>();

Expand Down Expand Up @@ -135,7 +134,7 @@ static APInt toSigned(APInt AbsVal, bool Negative) {
return Result;
}

Expected<ExpressionValue>
Expected<APInt>
ExpressionFormat::valueFromStringRepr(StringRef StrVal,
const SourceMgr &SM) const {
bool ValueIsSigned = Value == Kind::Signed;
Expand All @@ -155,76 +154,59 @@ ExpressionFormat::valueFromStringRepr(StringRef StrVal,
if (ParseFailure)
return ErrorDiagnostic::get(SM, StrVal,
"unable to represent numeric value");
return ExpressionValue(toSigned(ResultValue, Negative));
return toSigned(ResultValue, Negative);
}

Expected<ExpressionValue> llvm::exprAdd(const ExpressionValue &LeftOperand,
const ExpressionValue &RightOperand,
bool &Overflow) {
APInt Result = LeftOperand.getAPIntValue().sadd_ov(
RightOperand.getAPIntValue(), Overflow);
return ExpressionValue(Result);
Expected<APInt> llvm::exprAdd(const APInt &LeftOperand,
const APInt &RightOperand, bool &Overflow) {
return LeftOperand.sadd_ov(RightOperand, Overflow);
}

Expected<ExpressionValue> llvm::exprSub(const ExpressionValue &LeftOperand,
const ExpressionValue &RightOperand,
bool &Overflow) {
APInt Result = LeftOperand.getAPIntValue().ssub_ov(
RightOperand.getAPIntValue(), Overflow);
return ExpressionValue(Result);
Expected<APInt> llvm::exprSub(const APInt &LeftOperand,
const APInt &RightOperand, bool &Overflow) {
return LeftOperand.ssub_ov(RightOperand, Overflow);
}

Expected<ExpressionValue> llvm::exprMul(const ExpressionValue &LeftOperand,
const ExpressionValue &RightOperand,
bool &Overflow) {
APInt Result = LeftOperand.getAPIntValue().smul_ov(
RightOperand.getAPIntValue(), Overflow);
return ExpressionValue(Result);
Expected<APInt> llvm::exprMul(const APInt &LeftOperand,
const APInt &RightOperand, bool &Overflow) {
return LeftOperand.smul_ov(RightOperand, Overflow);
}

Expected<ExpressionValue> llvm::exprDiv(const ExpressionValue &LeftOperand,
const ExpressionValue &RightOperand,
bool &Overflow) {
Expected<APInt> llvm::exprDiv(const APInt &LeftOperand,
const APInt &RightOperand, bool &Overflow) {
// Check for division by zero.
if (RightOperand.getAPIntValue().isZero())
if (RightOperand.isZero())
return make_error<OverflowError>();

APInt Result = LeftOperand.getAPIntValue().sdiv_ov(
RightOperand.getAPIntValue(), Overflow);
return ExpressionValue(Result);
return LeftOperand.sdiv_ov(RightOperand, Overflow);
}

Expected<ExpressionValue> llvm::exprMax(const ExpressionValue &LeftOperand,
const ExpressionValue &RightOperand,
bool &Overflow) {
Expected<APInt> llvm::exprMax(const APInt &LeftOperand,
const APInt &RightOperand, bool &Overflow) {
Overflow = false;
return LeftOperand.getAPIntValue().slt(RightOperand.getAPIntValue())
? RightOperand
: LeftOperand;
return LeftOperand.slt(RightOperand) ? RightOperand : LeftOperand;
}

Expected<ExpressionValue> llvm::exprMin(const ExpressionValue &LeftOperand,
const ExpressionValue &RightOperand,
bool &Overflow) {
Expected<APInt> llvm::exprMin(const APInt &LeftOperand,
const APInt &RightOperand, bool &Overflow) {
Overflow = false;
if (cantFail(exprMax(LeftOperand, RightOperand, Overflow)).getAPIntValue() ==
LeftOperand.getAPIntValue())
if (cantFail(exprMax(LeftOperand, RightOperand, Overflow)) == LeftOperand)
return RightOperand;

return LeftOperand;
}

Expected<ExpressionValue> NumericVariableUse::eval() const {
std::optional<ExpressionValue> Value = Variable->getValue();
Expected<APInt> NumericVariableUse::eval() const {
std::optional<APInt> Value = Variable->getValue();
if (Value)
return *Value;

return make_error<UndefVarError>(getExpressionStr());
}

Expected<ExpressionValue> BinaryOperation::eval() const {
Expected<ExpressionValue> MaybeLeftOp = LeftOperand->eval();
Expected<ExpressionValue> MaybeRightOp = RightOperand->eval();
Expected<APInt> BinaryOperation::eval() const {
Expected<APInt> MaybeLeftOp = LeftOperand->eval();
Expected<APInt> MaybeRightOp = RightOperand->eval();

// Bubble up any error (e.g. undefined variables) in the recursive
// evaluation.
Expand All @@ -237,8 +219,8 @@ Expected<ExpressionValue> BinaryOperation::eval() const {
return std::move(Err);
}

APInt LeftOp = MaybeLeftOp->getAPIntValue();
APInt RightOp = MaybeRightOp->getAPIntValue();
APInt LeftOp = *MaybeLeftOp;
APInt RightOp = *MaybeRightOp;
bool Overflow;
// Ensure both operands have the same bitwidth.
unsigned LeftBitWidth = LeftOp.getBitWidth();
Expand All @@ -247,8 +229,7 @@ Expected<ExpressionValue> BinaryOperation::eval() const {
LeftOp = LeftOp.sext(NewBitWidth);
RightOp = RightOp.sext(NewBitWidth);
do {
Expected<ExpressionValue> MaybeResult =
EvalBinop(ExpressionValue(LeftOp), ExpressionValue(RightOp), Overflow);
Expected<APInt> MaybeResult = EvalBinop(LeftOp, RightOp, Overflow);
if (!MaybeResult)
return MaybeResult.takeError();

Expand Down Expand Up @@ -291,8 +272,7 @@ BinaryOperation::getImplicitFormat(const SourceMgr &SM) const {
Expected<std::string> NumericSubstitution::getResult() const {
assert(ExpressionPointer->getAST() != nullptr &&
"Substituting empty expression");
Expected<ExpressionValue> EvaluatedValue =
ExpressionPointer->getAST()->eval();
Expected<APInt> EvaluatedValue = ExpressionPointer->getAST()->eval();
if (!EvaluatedValue)
return EvaluatedValue.takeError();
ExpressionFormat Format = ExpressionPointer->getFormat();
Expand Down Expand Up @@ -1117,7 +1097,7 @@ Pattern::MatchResult Pattern::match(StringRef Buffer,
TmpStr = RegExStr;
if (LineNumber)
Context->LineVariable->setValue(
ExpressionValue(APInt(sizeof(*LineNumber) * 8, *LineNumber)));
APInt(sizeof(*LineNumber) * 8, *LineNumber));

size_t InsertOffset = 0;
// Substitute all string variables and expressions whose values are only
Expand Down Expand Up @@ -1196,8 +1176,7 @@ Pattern::MatchResult Pattern::match(StringRef Buffer,

StringRef MatchedValue = MatchInfo[CaptureParenGroup];
ExpressionFormat Format = DefinedNumericVariable->getImplicitFormat();
Expected<ExpressionValue> Value =
Format.valueFromStringRepr(MatchedValue, SM);
Expected<APInt> Value = Format.valueFromStringRepr(MatchedValue, SM);
if (!Value)
return MatchResult(TheMatch, Value.takeError());
DefinedNumericVariable->setValue(*Value, MatchedValue);
Expand Down Expand Up @@ -2583,7 +2562,7 @@ Error FileCheckPatternContext::defineCmdlineVariables(
// to, since the expression of a command-line variable definition should
// only use variables defined earlier on the command-line. If not, this
// is an error and we report it.
Expected<ExpressionValue> Value = Expression->getAST()->eval();
Expected<APInt> Value = Expression->getAST()->eval();
if (!Value) {
Errs = joinErrors(std::move(Errs), Value.takeError());
continue;
Expand Down
57 changes: 18 additions & 39 deletions llvm/lib/FileCheck/FileCheckImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ namespace llvm {
// Numeric substitution handling code.
//===----------------------------------------------------------------------===//

class ExpressionValue;

/// Type representing the format an expression value should be textualized into
/// for matching. Used to represent both explicit format specifiers as well as
/// implicit format from using numeric variables.
Expand Down Expand Up @@ -95,14 +93,14 @@ struct ExpressionFormat {
/// \returns the string representation of \p Value in the format represented
/// by this instance, or an error if conversion to this format failed or the
/// format is NoFormat.
Expected<std::string> getMatchingString(ExpressionValue Value) const;
Expected<std::string> getMatchingString(APInt Value) const;

/// \returns the value corresponding to string representation \p StrVal
/// according to the matching format represented by this instance or an error
/// with diagnostic against \p SM if \p StrVal does not correspond to a valid
/// and representable value.
Expected<ExpressionValue> valueFromStringRepr(StringRef StrVal,
const SourceMgr &SM) const;
Expected<APInt> valueFromStringRepr(StringRef StrVal,
const SourceMgr &SM) const;
};

/// Class to represent an overflow error that might result when manipulating a
Expand All @@ -118,31 +116,14 @@ class OverflowError : public ErrorInfo<OverflowError> {
void log(raw_ostream &OS) const override { OS << "overflow error"; }
};

/// Class representing a numeric value.
class ExpressionValue {
private:
APInt Value;

public:
ExpressionValue(APInt Val) : Value(Val) {}

APInt getAPIntValue() const { return Value; }
};

/// Performs operation and \returns its result or an error in case of failure,
/// such as if an overflow occurs.
Expected<ExpressionValue> exprAdd(const ExpressionValue &Lhs,
const ExpressionValue &Rhs, bool &Overflow);
Expected<ExpressionValue> exprSub(const ExpressionValue &Lhs,
const ExpressionValue &Rhs, bool &Overflow);
Expected<ExpressionValue> exprMul(const ExpressionValue &Lhs,
const ExpressionValue &Rhs, bool &Overflow);
Expected<ExpressionValue> exprDiv(const ExpressionValue &Lhs,
const ExpressionValue &Rhs, bool &Overflow);
Expected<ExpressionValue> exprMax(const ExpressionValue &Lhs,
const ExpressionValue &Rhs, bool &Overflow);
Expected<ExpressionValue> exprMin(const ExpressionValue &Lhs,
const ExpressionValue &Rhs, bool &Overflow);
Expected<APInt> exprAdd(const APInt &Lhs, const APInt &Rhs, bool &Overflow);
Expected<APInt> exprSub(const APInt &Lhs, const APInt &Rhs, bool &Overflow);
Expected<APInt> exprMul(const APInt &Lhs, const APInt &Rhs, bool &Overflow);
Expected<APInt> exprDiv(const APInt &Lhs, const APInt &Rhs, bool &Overflow);
Expected<APInt> exprMax(const APInt &Lhs, const APInt &Rhs, bool &Overflow);
Expected<APInt> exprMin(const APInt &Lhs, const APInt &Rhs, bool &Overflow);

/// Base class representing the AST of a given expression.
class ExpressionAST {
Expand All @@ -158,7 +139,7 @@ class ExpressionAST {

/// Evaluates and \returns the value of the expression represented by this
/// AST or an error if evaluation fails.
virtual Expected<ExpressionValue> eval() const = 0;
virtual Expected<APInt> eval() const = 0;

/// \returns either the implicit format of this AST, a diagnostic against
/// \p SM if implicit formats of the AST's components conflict, or NoFormat
Expand All @@ -174,14 +155,14 @@ class ExpressionAST {
class ExpressionLiteral : public ExpressionAST {
private:
/// Actual value of the literal.
ExpressionValue Value;
APInt Value;

public:
explicit ExpressionLiteral(StringRef ExpressionStr, APInt Val)
: ExpressionAST(ExpressionStr), Value(Val) {}

/// \returns the literal's value.
Expected<ExpressionValue> eval() const override { return Value; }
Expected<APInt> eval() const override { return Value; }
};

/// Class to represent an undefined variable error, which quotes that
Expand Down Expand Up @@ -240,7 +221,7 @@ class NumericVariable {
ExpressionFormat ImplicitFormat;

/// Value of numeric variable, if defined, or std::nullopt otherwise.
std::optional<ExpressionValue> Value;
std::optional<APInt> Value;

/// The input buffer's string from which Value was parsed, or std::nullopt.
/// See comments on getStringValue for a discussion of the std::nullopt case.
Expand All @@ -267,7 +248,7 @@ class NumericVariable {
ExpressionFormat getImplicitFormat() const { return ImplicitFormat; }

/// \returns this variable's value.
std::optional<ExpressionValue> getValue() const { return Value; }
std::optional<APInt> getValue() const { return Value; }

/// \returns the input buffer's string from which this variable's value was
/// parsed, or std::nullopt if the value is not yet defined or was not parsed
Expand All @@ -279,7 +260,7 @@ class NumericVariable {
/// Sets value of this numeric variable to \p NewValue, and sets the input
/// buffer string from which it was parsed to \p NewStrValue. See comments on
/// getStringValue for a discussion of when the latter can be std::nullopt.
void setValue(ExpressionValue NewValue,
void setValue(APInt NewValue,
std::optional<StringRef> NewStrValue = std::nullopt) {
Value = NewValue;
StrValue = NewStrValue;
Expand Down Expand Up @@ -308,7 +289,7 @@ class NumericVariableUse : public ExpressionAST {
NumericVariableUse(StringRef Name, NumericVariable *Variable)
: ExpressionAST(Name), Variable(Variable) {}
/// \returns the value of the variable referenced by this instance.
Expected<ExpressionValue> eval() const override;
Expected<APInt> eval() const override;

/// \returns implicit format of this numeric variable.
Expected<ExpressionFormat>
Expand All @@ -318,9 +299,7 @@ class NumericVariableUse : public ExpressionAST {
};

/// Type of functions evaluating a given binary operation.
using binop_eval_t = Expected<ExpressionValue> (*)(const ExpressionValue &,
const ExpressionValue &,
bool &);
using binop_eval_t = Expected<APInt> (*)(const APInt &, const APInt &, bool &);

/// Class representing a single binary operation in the AST of an expression.
class BinaryOperation : public ExpressionAST {
Expand All @@ -347,7 +326,7 @@ class BinaryOperation : public ExpressionAST {
/// using EvalBinop on the result of recursively evaluating the operands.
/// \returns the expression value or an error if an undefined numeric
/// variable is used in one of the operands.
Expected<ExpressionValue> eval() const override;
Expected<APInt> eval() const override;

/// \returns the implicit format of this AST, if any, a diagnostic against
/// \p SM if the implicit formats of the AST's components conflict, or no
Expand Down

0 comments on commit e15e969

Please sign in to comment.