AffineMap/AffineExpr: delete copy constructor/assignment, refactor

affine expr parsing.

- also make error messages uniform

PiperOrigin-RevId: 203822686
This commit is contained in:
Uday Bondhugula 2018-07-09 13:47:52 -07:00 committed by jpienaar
parent fc46bcf51d
commit 178fd24813
4 changed files with 43 additions and 44 deletions

View File

@ -71,6 +71,9 @@ class AffineExpr {
explicit AffineExpr(Kind kind) : kind(kind) {} explicit AffineExpr(Kind kind) : kind(kind) {}
private: private:
AffineExpr(const AffineExpr&) = delete;
void operator=(const AffineExpr&) = delete;
/// Classification of the subclass /// Classification of the subclass
const Kind kind; const Kind kind;
}; };

View File

@ -56,16 +56,19 @@ public:
} }
private: private:
AffineMap(unsigned numDims, unsigned numSymbols, unsigned numResults, AffineMap(unsigned numDims, unsigned numSymbols, unsigned numResults,
AffineExpr *const *results); AffineExpr *const *results);
const unsigned numDims; AffineMap(const AffineMap&) = delete;
const unsigned numSymbols; void operator=(const AffineMap&) = delete;
const unsigned numResults;
/// The affine expressions for this (multi-dimensional) map. const unsigned numDims;
/// TODO: use trailing objects for this. const unsigned numSymbols;
AffineExpr *const *const results; const unsigned numResults;
/// The affine expressions for this (multi-dimensional) map.
/// TODO: use trailing objects for this.
AffineExpr *const *const results;
}; };
} // end namespace mlir } // end namespace mlir

View File

@ -883,9 +883,9 @@ AffineExpr *Parser::parseIntegerExpr(const AffineMapParserState &state) {
} }
/// Parses an expression that can be a valid operand of an affine expression. /// Parses an expression that can be a valid operand of an affine expression.
/// lhs: if non-null, an affine expression that is the lhs of a binary operator, /// lhs: if non-null, lhs is an affine expression that is the lhs of a binary
/// the rhs of which is being parsed. This is used to determine whether an error /// operator, the rhs of which is being parsed. This is used to determine
/// should be emitted for a missing right operand. /// whether an error should be emitted for a missing right operand.
// Eg: for an expression without parentheses (like i + j + k + l), each // Eg: for an expression without parentheses (like i + j + k + l), each
// of the four identifiers is an operand. For i + j*k + l, j*k is not an // of the four identifiers is an operand. For i + j*k + l, j*k is not an
// operand expression, it's an op expression and will be parsed via // operand expression, it's an op expression and will be parsed via
@ -902,9 +902,19 @@ AffineExpr *Parser::parseAffineOperandExpr(AffineExpr *lhs,
return parseParentheticalExpr(state); return parseParentheticalExpr(state);
case Token::minus: case Token::minus:
return parseNegateExpression(lhs, state); return parseNegateExpression(lhs, state);
case Token::kw_ceildiv:
case Token::kw_floordiv:
case Token::kw_mod:
case Token::plus:
case Token::star:
if (lhs)
emitError("missing right operand of binary operator");
else
emitError("missing left operand of binary operator");
return nullptr;
default: default:
if (lhs) if (lhs)
emitError("missing right operand of binary op"); emitError("missing right operand of binary operator");
else else
emitError("expected affine expression"); emitError("expected affine expression");
return nullptr; return nullptr;
@ -919,8 +929,9 @@ AffineExpr *Parser::parseAffineOperandExpr(AffineExpr *lhs,
/// ///
/// {add, sub} have lower precedence than {mul, div, and mod}. /// {add, sub} have lower precedence than {mul, div, and mod}.
/// ///
/// Add, sub'are themselves at the same precedence level, mul, div, and mod are /// Add, sub'are themselves at the same precedence level. Mul, floordiv,
/// at the same higher precedence level. /// ceildiv, and mod are at the same higher precedence level. Negation has
/// higher precedence than any binary op.
/// ///
/// llhs: the affine expression appearing on the left of the one being parsed. /// llhs: the affine expression appearing on the left of the one being parsed.
/// This function will return ((llhs llhsOp lhs) op rhs) if llhs is non null, /// This function will return ((llhs llhsOp lhs) op rhs) if llhs is non null,
@ -934,8 +945,8 @@ AffineExpr *Parser::parseAffineOperandExpr(AffineExpr *lhs,
AffineExpr * AffineExpr *
Parser::parseAffineLowPrecOpExpr(AffineExpr *llhs, AffineLowPrecOp llhsOp, Parser::parseAffineLowPrecOpExpr(AffineExpr *llhs, AffineLowPrecOp llhsOp,
const AffineMapParserState &state) { const AffineMapParserState &state) {
AffineExpr *lhs = parseAffineOperandExpr(llhs, state); AffineExpr *lhs;
if (!lhs) if (!(lhs = parseAffineOperandExpr(llhs, state)))
return nullptr; return nullptr;
// Found an LHS. Deal with the ops. // Found an LHS. Deal with the ops.
@ -990,25 +1001,7 @@ Parser::parseAffineLowPrecOpExpr(AffineExpr *llhs, AffineLowPrecOp llhsOp,
/// operand for floordiv, ceildiv, and mod has to be a positive integer. /// operand for floordiv, ceildiv, and mod has to be a positive integer.
/// Use 'state' to check if valid identifiers appear in the expressoins. /// Use 'state' to check if valid identifiers appear in the expressoins.
AffineExpr *Parser::parseAffineExpr(const AffineMapParserState &state) { AffineExpr *Parser::parseAffineExpr(const AffineMapParserState &state) {
switch (curToken.getKind()) { return parseAffineLowPrecOpExpr(nullptr, AffineLowPrecOp::LNoOp, state);
case Token::l_paren:
case Token::bare_identifier:
case Token::minus:
case Token::integer:
return parseAffineLowPrecOpExpr(nullptr, AffineLowPrecOp::LNoOp, state);
case Token::kw_ceildiv:
case Token::kw_floordiv:
case Token::kw_mod:
case Token::plus:
case Token::star:
emitError("left operand of binary op missing");
return nullptr;
default:
emitError("expected affine expression");
return nullptr;
}
} }
/// Parse a dim or symbol from the lists appearing before the actual expressions /// Parse a dim or symbol from the lists appearing before the actual expressions

View File

@ -48,19 +48,19 @@
#hello_world = (i, j) [s0, s1] -> () ; expected-error {{expected list element}} #hello_world = (i, j) [s0, s1] -> () ; expected-error {{expected list element}}
; ----- ; -----
#hello_world = (i, j) [s0, s1] -> (+i, j) ; expected-error {{left operand of binary op missing}} #hello_world = (i, j) [s0, s1] -> (+i, j) ; expected-error {{missing left operand of binary op}}
; ----- ; -----
#hello_world = (i, j) [s0, s1] -> (i, *j) ; expected-error {{left operand of binary op missing}} #hello_world = (i, j) [s0, s1] -> (i, *j) ; expected-error {{missing left operand of binary op}}
; ----- ; -----
#hello_world = (i, j) [s0, s1] -> (floordiv i 2, j) ; expected-error {{left operand of binary op missing}} #hello_world = (i, j) [s0, s1] -> (floordiv i 2, j) ; expected-error {{missing left operand of binary op}}
; ----- ; -----
#hello_world = (i, j) [s0, s1] -> (ceildiv i 2, j) ; expected-error {{left operand of binary op missing}} #hello_world = (i, j) [s0, s1] -> (ceildiv i 2, j) ; expected-error {{missing left operand of binary op}}
; ----- ; -----
#hello_world = (i, j) [s0, s1] -> (mod i 2, j) ; expected-error {{left operand of binary op missing}} #hello_world = (i, j) [s0, s1] -> (mod i 2, j) ; expected-error {{missing left operand of binary op}}
; ----- ; -----
#hello_world = (i, j) [s0, s1] -> (-(), j) #hello_world = (i, j) [s0, s1] -> (-(), j)
@ -68,16 +68,16 @@
; expected-error@-2 {{missing operand of negation}} ; expected-error@-2 {{missing operand of negation}}
; ----- ; -----
#hello_world = (i, j) [s0, s1] -> (i, *j+5) ; expected-error {{left operand of binary op missing}} #hello_world = (i, j) [s0, s1] -> (i, *j+5) ; expected-error {{missing left operand of binary op}}
; ----- ; -----
#hello_world = (i, j) [s0, s1] -> (i, floordiv j+5) ; expected-error {{left operand of binary op missing}} #hello_world = (i, j) [s0, s1] -> (i, floordiv j+5) ; expected-error {{missing left operand of binary op}}
; ----- ; -----
#hello_world = (i, j) [s0, s1] -> (i, ceildiv j+5) ; expected-error {{left operand of binary op missing}} #hello_world = (i, j) [s0, s1] -> (i, ceildiv j+5) ; expected-error {{missing left operand of binary op}}
; ----- ; -----
#hello_world = (i, j) [s0, s1] -> (i, mod j+5) ; expected-error {{left operand of binary op missing}} #hello_world = (i, j) [s0, s1] -> (i, mod j+5) ; expected-error {{missing left operand of binary op}}
; ----- ; -----
#hello_world = (i, j) [s0, s1] -> (i*j, j) ; expected-error {{non-affine expression: at least one of the multiply operands has to be either a constant or symbolic}} #hello_world = (i, j) [s0, s1] -> (i*j, j) ; expected-error {{non-affine expression: at least one of the multiply operands has to be either a constant or symbolic}}