Drop AffineMap::Null and IntegerSet::Null

Addresses b/122486036

This CL addresses some leftover crumbs in AffineMap and IntegerSet by removing
the Null method and cleaning up the constructors.

As the ::Null uses were tracked down, opportunities appeared to untangle some
of the Parsing logic and make it explicit where AffineMap/IntegerSet have
ambiguous syntax. Previously, ambiguous cases were hidden behind the implicit
pointer values of AffineMap* and IntegerSet* that were passed as function
parameters. Depending the values of those pointers one of 3 behaviors could
occur.

This parsing logic convolution is one of the rare cases where I would advocate
for code duplication. The more proper fix would be to make the syntax
unambiguous or to allow some lookahead.

PiperOrigin-RevId: 231058512
This commit is contained in:
Nicolas Vasilache 2019-01-26 10:41:17 -08:00 committed by jpienaar
parent 81c7f2e2f3
commit 0e7a8a9027
12 changed files with 205 additions and 207 deletions

View File

@ -378,7 +378,7 @@ public:
/// identifiers as an affine map of the remaining identifiers (dimensional and /// identifiers as an affine map of the remaining identifiers (dimensional and
/// symbolic). This method is able to detect identifiers as floordiv's /// symbolic). This method is able to detect identifiers as floordiv's
/// and mod's of affine expressions of other identifiers with respect to /// and mod's of affine expressions of other identifiers with respect to
/// (positive) constants. Sets bound map to AffineMap::Null if such a bound /// (positive) constants. Sets bound map to a null AffineMap if such a bound
/// can't be found (or yet unimplemented). /// can't be found (or yet unimplemented).
void getSliceBounds(unsigned num, MLIRContext *context, void getSliceBounds(unsigned num, MLIRContext *context,
SmallVectorImpl<AffineMap> *lbMaps, SmallVectorImpl<AffineMap> *lbMaps,

View File

@ -46,8 +46,10 @@ class AffineMap {
public: public:
using ImplType = detail::AffineMapStorage; using ImplType = detail::AffineMapStorage;
explicit AffineMap(ImplType *map = nullptr) : map(map) {} AffineMap() : map(nullptr) {}
static AffineMap Null() { return AffineMap(nullptr); } explicit AffineMap(ImplType *map) : map(map) {}
AffineMap(const AffineMap &other) : map(other.map) {}
AffineMap &operator=(const AffineMap &other) = default;
static AffineMap get(unsigned dimCount, unsigned symbolCount, static AffineMap get(unsigned dimCount, unsigned symbolCount,
ArrayRef<AffineExpr> results, ArrayRef<AffineExpr> results,
@ -62,9 +64,9 @@ public:
MLIRContext *getContext() const; MLIRContext *getContext() const;
explicit operator bool() { return map; } explicit operator bool() { return map != nullptr; }
bool operator==(const AffineMap &other) const { return other.map == map; } bool operator==(AffineMap other) const { return other.map == map; }
bool operator!=(const AffineMap &other) const { return !(other.map == map); } bool operator!=(AffineMap other) const { return !(other.map == map); }
/// Returns true if the co-domain (or more loosely speaking, range) of this /// Returns true if the co-domain (or more loosely speaking, range) of this
/// map is bounded. Bounded affine maps have a size (extent) for each of /// map is bounded. Bounded affine maps have a size (extent) for each of

View File

@ -52,12 +52,10 @@ class IntegerSet {
public: public:
using ImplType = detail::IntegerSetStorage; using ImplType = detail::IntegerSetStorage;
explicit IntegerSet(ImplType *set = nullptr) : set(set) {} IntegerSet() : set(nullptr) {}
explicit IntegerSet(ImplType *set) : set(set) {}
IntegerSet &operator=(const IntegerSet other) { IntegerSet(const IntegerSet &other) : set(other.set) {}
set = other.set; IntegerSet &operator=(const IntegerSet &other) = default;
return *this;
}
static IntegerSet get(unsigned dimCount, unsigned symbolCount, static IntegerSet get(unsigned dimCount, unsigned symbolCount,
ArrayRef<AffineExpr> constraints, ArrayRef<AffineExpr> constraints,
@ -74,8 +72,6 @@ public:
/// Returns true if this is the canonical integer set. /// Returns true if this is the canonical integer set.
bool isEmptyIntegerSet() const; bool isEmptyIntegerSet() const;
static IntegerSet Null() { return IntegerSet(nullptr); }
explicit operator bool() { return set; } explicit operator bool() { return set; }
bool operator==(IntegerSet other) const { return set == other.set; } bool operator==(IntegerSet other) const { return set == other.set; }

View File

@ -65,7 +65,7 @@ class Function;
// TODO(bondhugula): allow extraIndices to be added at any position. // TODO(bondhugula): allow extraIndices to be added at any position.
bool replaceAllMemRefUsesWith(const Value *oldMemRef, Value *newMemRef, bool replaceAllMemRefUsesWith(const Value *oldMemRef, Value *newMemRef,
ArrayRef<Value *> extraIndices = {}, ArrayRef<Value *> extraIndices = {},
AffineMap indexRemap = AffineMap::Null(), AffineMap indexRemap = AffineMap(),
ArrayRef<Value *> extraOperands = {}, ArrayRef<Value *> extraOperands = {},
const Instruction *domInstFilter = nullptr); const Instruction *domInstFilter = nullptr);

View File

@ -1133,8 +1133,8 @@ void FlatAffineConstraints::getSliceBounds(unsigned num, MLIRContext *context,
numMapDims, numMapSymbols, numMapDims, numMapSymbols,
getAffineConstantExpr(ubConst.getValue() + 1, context), {}); getAffineConstantExpr(ubConst.getValue() + 1, context), {});
} else { } else {
(*lbMaps)[pos] = AffineMap::Null(); (*lbMaps)[pos] = AffineMap();
(*ubMaps)[pos] = AffineMap::Null(); (*ubMaps)[pos] = AffineMap();
} }
} }
LLVM_DEBUG(llvm::dbgs() << "lb map for pos = " << Twine(pos) << ", expr: "); LLVM_DEBUG(llvm::dbgs() << "lb map for pos = " << Twine(pos) << ", expr: ");

View File

@ -410,8 +410,8 @@ bool mlir::getBackwardComputationSliceState(const MemRefAccess &srcAccess,
numDstLoopIVs - dstLoopDepth); numDstLoopIVs - dstLoopDepth);
// Set up lower/upper bound affine maps for the slice. // Set up lower/upper bound affine maps for the slice.
sliceState->lbs.resize(numSrcLoopIVs, AffineMap::Null()); sliceState->lbs.resize(numSrcLoopIVs, AffineMap());
sliceState->ubs.resize(numSrcLoopIVs, AffineMap::Null()); sliceState->ubs.resize(numSrcLoopIVs, AffineMap());
// Get bounds for src IVs in terms of dst IVs, symbols, and constants. // Get bounds for src IVs in terms of dst IVs, symbols, and constants.
dependenceConstraints.getSliceBounds(numSrcLoopIVs, dependenceConstraints.getSliceBounds(numSrcLoopIVs,

View File

@ -612,9 +612,11 @@ bool OperationInst::emitOpError(const Twine &message) const {
ForInst *ForInst::create(Location location, ArrayRef<Value *> lbOperands, ForInst *ForInst::create(Location location, ArrayRef<Value *> lbOperands,
AffineMap lbMap, ArrayRef<Value *> ubOperands, AffineMap lbMap, ArrayRef<Value *> ubOperands,
AffineMap ubMap, int64_t step) { AffineMap ubMap, int64_t step) {
assert(lbOperands.size() == lbMap.getNumInputs() && assert((!lbMap && lbOperands.empty()) ||
lbOperands.size() == lbMap.getNumInputs() &&
"lower bound operand count does not match the affine map"); "lower bound operand count does not match the affine map");
assert(ubOperands.size() == ubMap.getNumInputs() && assert((!ubMap && ubOperands.empty()) ||
ubOperands.size() == ubMap.getNumInputs() &&
"upper bound operand count does not match the affine map"); "upper bound operand count does not match the affine map");
assert(step > 0 && "step has to be a positive integer constant"); assert(step > 0 && "step has to be a positive integer constant");

View File

@ -1202,7 +1202,7 @@ AffineMap AffineMap::get(unsigned dimCount, unsigned symbolCount,
// Check if we already have this affine map. // Check if we already have this affine map.
auto key = std::make_tuple(dimCount, symbolCount, results, rangeSizes); auto key = std::make_tuple(dimCount, symbolCount, results, rangeSizes);
auto existing = impl.affineMaps.insert_as(AffineMap(nullptr), key); auto existing = impl.affineMaps.insert_as(AffineMap(), key);
// If we already have it, return that value. // If we already have it, return that value.
if (!existing.second) if (!existing.second)

View File

@ -200,12 +200,10 @@ public:
ParseResult parseAttributeDict(SmallVectorImpl<NamedAttribute> &attributes); ParseResult parseAttributeDict(SmallVectorImpl<NamedAttribute> &attributes);
// Polyhedral structures. // Polyhedral structures.
void parseAffineStructureInline(AffineMap *map, IntegerSet *set);
void parseAffineStructureReference(AffineMap *map, IntegerSet *set);
AffineMap parseAffineMapInline();
AffineMap parseAffineMapReference(); AffineMap parseAffineMapReference();
IntegerSet parseIntegerSetInline();
IntegerSet parseIntegerSetReference(); IntegerSet parseIntegerSetReference();
ParseResult parseAffineMapOrIntegerSetReference(AffineMap &map,
IntegerSet &set);
DenseElementsAttr parseDenseElementsAttr(VectorOrTensorType type); DenseElementsAttr parseDenseElementsAttr(VectorOrTensorType type);
DenseElementsAttr parseDenseElementsAttr(Type eltType, bool isVector); DenseElementsAttr parseDenseElementsAttr(Type eltType, bool isVector);
VectorOrTensorType parseVectorOrTensorType(); VectorOrTensorType parseVectorOrTensorType();
@ -997,13 +995,13 @@ Attribute Parser::parseAttribute(Type type) {
// Try to parse an affine map or an integer set reference. // Try to parse an affine map or an integer set reference.
AffineMap map; AffineMap map;
IntegerSet set; IntegerSet set;
parseAffineStructureReference(&map, &set); if (parseAffineMapOrIntegerSetReference(map, set))
if (map)
return builder.getAffineMapAttr(map);
if (set)
return builder.getIntegerSetAttr(set);
return (emitError("expected affine map or integer set attribute value"), return (emitError("expected affine map or integer set attribute value"),
nullptr); nullptr);
if (map)
return builder.getAffineMapAttr(map);
assert(set);
return builder.getIntegerSetAttr(set);
} }
case Token::at_identifier: { case Token::at_identifier: {
@ -1474,8 +1472,10 @@ class AffineParser : public Parser {
public: public:
explicit AffineParser(ParserState &state) : Parser(state) {} explicit AffineParser(ParserState &state) : Parser(state) {}
void parseAffineStructureInline(AffineMap *map, IntegerSet *set); AffineMap parseAffineMapInline();
AffineMap parseAffineMapRange(unsigned numDims, unsigned numSymbols); AffineMap parseAffineMapRange(unsigned numDims, unsigned numSymbols);
IntegerSet parseIntegerSetInline();
ParseResult parseAffineMapOrIntegerSetInline(AffineMap &map, IntegerSet &set);
IntegerSet parseIntegerSetConstraints(unsigned numDims, unsigned numSymbols); IntegerSet parseIntegerSetConstraints(unsigned numDims, unsigned numSymbols);
private: private:
@ -1486,6 +1486,8 @@ private:
// Identifier lists for polyhedral structures. // Identifier lists for polyhedral structures.
ParseResult parseDimIdList(unsigned &numDims); ParseResult parseDimIdList(unsigned &numDims);
ParseResult parseSymbolIdList(unsigned &numSymbols); ParseResult parseSymbolIdList(unsigned &numSymbols);
ParseResult parseDimAndOptionalSymbolIdList(unsigned &numDims,
unsigned &numSymbols);
ParseResult parseIdentifierDefinition(AffineExpr idExpr); ParseResult parseIdentifierDefinition(AffineExpr idExpr);
AffineExpr parseAffineExpr(); AffineExpr parseAffineExpr();
@ -1841,6 +1843,20 @@ ParseResult AffineParser::parseIdentifierDefinition(AffineExpr idExpr) {
return ParseSuccess; return ParseSuccess;
} }
/// Parse the list of dimensional identifiers to an affine map.
ParseResult AffineParser::parseDimIdList(unsigned &numDims) {
if (parseToken(Token::l_paren,
"expected '(' at start of dimensional identifiers list")) {
return ParseFailure;
}
auto parseElt = [&]() -> ParseResult {
auto dimension = getAffineDimExpr(numDims++, getContext());
return parseIdentifierDefinition(dimension);
};
return parseCommaSeparatedListUntil(Token::r_paren, parseElt);
}
/// Parse the list of symbolic identifiers to an affine map. /// Parse the list of symbolic identifiers to an affine map.
ParseResult AffineParser::parseSymbolIdList(unsigned &numSymbols) { ParseResult AffineParser::parseSymbolIdList(unsigned &numSymbols) {
consumeToken(Token::l_square); consumeToken(Token::l_square);
@ -1851,23 +1867,21 @@ ParseResult AffineParser::parseSymbolIdList(unsigned &numSymbols) {
return parseCommaSeparatedListUntil(Token::r_square, parseElt); return parseCommaSeparatedListUntil(Token::r_square, parseElt);
} }
/// Parse the list of dimensional identifiers to an affine map. /// Parse the list of symbolic identifiers to an affine map.
ParseResult AffineParser::parseDimIdList(unsigned &numDims) { ParseResult
if (parseToken(Token::l_paren, AffineParser::parseDimAndOptionalSymbolIdList(unsigned &numDims,
"expected '(' at start of dimensional identifiers list")) unsigned &numSymbols) {
return ParseFailure; if (parseDimIdList(numDims)) {
return ParseResult::ParseFailure;
auto parseElt = [&]() -> ParseResult { }
auto dimension = getAffineDimExpr(numDims++, getContext()); if (!getToken().is(Token::l_square)) {
return parseIdentifierDefinition(dimension); numSymbols = 0;
}; return ParseResult::ParseSuccess;
return parseCommaSeparatedListUntil(Token::r_paren, parseElt); }
return parseSymbolIdList(numSymbols);
} }
/// Parses either an affine map or an integer set definition inline. If both /// Parses an affine map definition inline.
/// 'map' and 'set' are non-null, parses either an affine map or an integer set.
/// If 'map' is set to nullptr, parses an integer set. If 'set' is set to
/// nullptr, parses an affine map. 'map'/'set' are set to the parsed structure.
/// ///
/// affine-map-inline ::= dim-and-symbol-id-lists `->` multi-dim-affine-expr /// affine-map-inline ::= dim-and-symbol-id-lists `->` multi-dim-affine-expr
/// (`size` `(` dim-size (`,` dim-size)* `)`)? /// (`size` `(` dim-size (`,` dim-size)* `)`)?
@ -1875,6 +1889,23 @@ ParseResult AffineParser::parseDimIdList(unsigned &numDims) {
/// ///
/// multi-dim-affine-expr ::= `(` affine-expr (`,` affine-expr)* `) /// multi-dim-affine-expr ::= `(` affine-expr (`,` affine-expr)* `)
/// ///
AffineMap AffineParser::parseAffineMapInline() {
unsigned numDims = 0, numSymbols = 0;
// List of dimensional and optional symbol identifiers.
if (parseDimAndOptionalSymbolIdList(numDims, numSymbols)) {
return AffineMap();
}
if (parseToken(Token::arrow, "expected '->' or '['")) {
return AffineMap();
}
// Parse the affine map.
return parseAffineMapRange(numDims, numSymbols);
}
/// Parses an integer set definition inline.
/// ///
/// integer-set-inline /// integer-set-inline
/// ::= dim-and-symbol-id-lists `:` /// ::= dim-and-symbol-id-lists `:`
@ -1883,68 +1914,49 @@ ParseResult AffineParser::parseDimIdList(unsigned &numDims) {
/// | affine-constraint (`,` /// | affine-constraint (`,`
/// affine-constraint)* /// affine-constraint)*
/// ///
void AffineParser::parseAffineStructureInline(AffineMap *map, IntegerSet *set) { IntegerSet AffineParser::parseIntegerSetInline() {
assert((map || set) && "one of map or set expected to be non-null");
unsigned numDims = 0, numSymbols = 0; unsigned numDims = 0, numSymbols = 0;
// List of dimensional identifiers. // List of dimensional and optional symbol identifiers.
if (parseDimIdList(numDims)) { if (parseDimAndOptionalSymbolIdList(numDims, numSymbols)) {
if (map) return IntegerSet();
*map = AffineMap::Null();
if (set)
*set = IntegerSet::Null();
return;
} }
// Symbols are optional. if (parseToken(Token::colon, "expected ':' or '['")) {
if (getToken().is(Token::l_square)) { return IntegerSet();
if (parseSymbolIdList(numSymbols)) {
if (map)
*map = AffineMap::Null();
if (set)
*set = IntegerSet::Null();
return;
} }
return parseIntegerSetConstraints(numDims, numSymbols);
}
/// Parses an ambiguous affine map or integer set definition inline.
ParseResult AffineParser::parseAffineMapOrIntegerSetInline(AffineMap &map,
IntegerSet &set) {
unsigned numDims = 0, numSymbols = 0;
// List of dimensional and optional symbol identifiers.
if (parseDimAndOptionalSymbolIdList(numDims, numSymbols)) {
return ParseResult::ParseFailure;
} }
// This is needed for parsing attributes as we wouldn't know whether we would // This is needed for parsing attributes as we wouldn't know whether we would
// be parsing an integer set attribute or an affine map attribute. // be parsing an integer set attribute or an affine map attribute.
if (map && set && getToken().isNot(Token::arrow) && bool isArrow = getToken().is(Token::arrow);
getToken().isNot(Token::colon)) { bool isColon = getToken().is(Token::colon);
emitError("expected '->' or ':' or '['"); if (!isArrow && !isColon) {
*map = AffineMap::Null(); return ParseFailure;
*set = IntegerSet::Null(); } else if (isArrow) {
return; parseToken(Token::arrow, "expected '->' or '['");
map = parseAffineMapRange(numDims, numSymbols);
return map ? ParseSuccess : ParseFailure;
} else if (parseToken(Token::colon, "expected ':' or '['")) {
return ParseFailure;
} }
if (map && (!set || getToken().is(Token::arrow))) { if ((set = parseIntegerSetConstraints(numDims, numSymbols)))
// Parse an affine map. return ParseSuccess;
if (parseToken(Token::arrow, "expected '->' or '['")) {
*map = AffineMap::Null();
if (set)
*set = IntegerSet::Null();
return;
}
*map = parseAffineMapRange(numDims, numSymbols);
if (set)
*set = IntegerSet::Null();
return;
}
if (set && (!map || getToken().is(Token::colon))) { return ParseFailure;
// Parse an integer set.
if (parseToken(Token::colon, "expected ':' or '['")) {
*set = IntegerSet::Null();
if (map)
*map = AffineMap::Null();
return;
}
*set = parseIntegerSetConstraints(numDims, numSymbols);
if (map)
*map = AffineMap::Null();
return;
}
} }
/// Parse the range and sizes affine map definition inline. /// Parse the range and sizes affine map definition inline.
@ -1970,7 +1982,7 @@ AffineMap AffineParser::parseAffineMapRange(unsigned numDims,
// 1-d affine expressions); the list cannot be empty. Grammar: // 1-d affine expressions); the list cannot be empty. Grammar:
// multi-dim-affine-expr ::= `(` affine-expr (`,` affine-expr)* `) // multi-dim-affine-expr ::= `(` affine-expr (`,` affine-expr)* `)
if (parseCommaSeparatedListUntil(Token::r_paren, parseElt, false)) if (parseCommaSeparatedListUntil(Token::r_paren, parseElt, false))
return AffineMap::Null(); return AffineMap();
// Parse optional range sizes. // Parse optional range sizes.
// range-sizes ::= (`size` `(` dim-size (`,` dim-size)* `)`)? // range-sizes ::= (`size` `(` dim-size (`,` dim-size)* `)`)?
@ -1982,7 +1994,7 @@ AffineMap AffineParser::parseAffineMapRange(unsigned numDims,
// Location of the l_paren token (if it exists) for error reporting later. // Location of the l_paren token (if it exists) for error reporting later.
auto loc = getToken().getLoc(); auto loc = getToken().getLoc();
if (parseToken(Token::l_paren, "expected '(' at start of affine map range")) if (parseToken(Token::l_paren, "expected '(' at start of affine map range"))
return AffineMap::Null(); return AffineMap();
auto parseRangeSize = [&]() -> ParseResult { auto parseRangeSize = [&]() -> ParseResult {
auto loc = getToken().getLoc(); auto loc = getToken().getLoc();
@ -1999,99 +2011,90 @@ AffineMap AffineParser::parseAffineMapRange(unsigned numDims,
}; };
if (parseCommaSeparatedListUntil(Token::r_paren, parseRangeSize, false)) if (parseCommaSeparatedListUntil(Token::r_paren, parseRangeSize, false))
return AffineMap::Null(); return AffineMap();
if (exprs.size() > rangeSizes.size()) if (exprs.size() > rangeSizes.size())
return (emitError(loc, "fewer range sizes than range expressions"), return (emitError(loc, "fewer range sizes than range expressions"),
AffineMap::Null()); AffineMap());
if (exprs.size() < rangeSizes.size()) if (exprs.size() < rangeSizes.size())
return (emitError(loc, "more range sizes than range expressions"), return (emitError(loc, "more range sizes than range expressions"),
AffineMap::Null()); AffineMap());
} }
// Parsed a valid affine map. // Parsed a valid affine map.
return builder.getAffineMap(numDims, numSymbols, exprs, rangeSizes); return builder.getAffineMap(numDims, numSymbols, exprs, rangeSizes);
} }
void Parser::parseAffineStructureInline(AffineMap *map, IntegerSet *set) {
AffineParser(state).parseAffineStructureInline(map, set);
}
AffineMap Parser::parseAffineMapInline() {
AffineMap map;
AffineParser(state).parseAffineStructureInline(&map, nullptr);
return map;
}
/// Parse either an affine map reference or integer set reference.
///
/// affine-structure ::= affine-structure-id | affine-structure-inline
/// affine-structure-id ::= `#` suffix-id
///
/// affine-structure ::= affine-map | integer-set
///
void Parser::parseAffineStructureReference(AffineMap *map, IntegerSet *set) {
assert((map || set) && "both map and set are non-null");
if (getToken().isNot(Token::hash_identifier)) {
// Try to parse inline affine map or integer set.
return parseAffineStructureInline(map, set);
}
// Parse affine map / integer set identifier and verify that it exists.
// Note that an id can't be in both affineMapDefinitions and
// integerSetDefinitions since they use the same sigil '#'.
StringRef affineStructId = getTokenSpelling().drop_front();
if (getState().affineMapDefinitions.count(affineStructId) > 0) {
consumeToken(Token::hash_identifier);
if (map)
*map = getState().affineMapDefinitions[affineStructId];
if (set)
*set = IntegerSet::Null();
return;
}
if (getState().integerSetDefinitions.count(affineStructId) > 0) {
consumeToken(Token::hash_identifier);
if (set)
*set = getState().integerSetDefinitions[affineStructId];
if (map)
*map = AffineMap::Null();
return;
}
// The id isn't among any of the recorded definitions.
// Emit the right message depending on what the caller expected.
if (map && !set)
emitError("undefined affine map id '" + affineStructId + "'");
else if (set && !map)
emitError("undefined integer set id '" + affineStructId + "'");
else if (set && map)
emitError("undefined affine map or integer set id '" + affineStructId +
"'");
if (map)
*map = AffineMap::Null();
if (set)
*set = IntegerSet::Null();
}
/// Parse a reference to an integer set.
/// affine-map ::= affine-map-id | affine-map-inline
/// affine-map-id ::= `#` suffix-id
///
AffineMap Parser::parseAffineMapReference() {
AffineMap map;
parseAffineStructureReference(&map, nullptr);
return map;
}
/// Parse a reference to an integer set. /// Parse a reference to an integer set.
/// integer-set ::= integer-set-id | integer-set-inline /// integer-set ::= integer-set-id | integer-set-inline
/// integer-set-id ::= `#` suffix-id /// integer-set-id ::= `#` suffix-id
/// ///
IntegerSet Parser::parseIntegerSetReference() { IntegerSet Parser::parseIntegerSetReference() {
IntegerSet set; if (getToken().isNot(Token::hash_identifier)) {
parseAffineStructureReference(nullptr, &set); // Try to parse inline integer set.
return set; return AffineParser(state).parseIntegerSetInline();
}
// Parse integer set identifier and verify that it exists.
StringRef id = getTokenSpelling().drop_front();
if (getState().integerSetDefinitions.count(id) > 0) {
consumeToken(Token::hash_identifier);
return getState().integerSetDefinitions[id];
}
// The id isn't among any of the recorded definitions.
emitError("undefined integer set id '" + id + "'");
return IntegerSet();
}
/// Parse a reference to an affine map.
/// affine-map ::= affine-map-id | affine-map-inline
/// affine-map-id ::= `#` suffix-id
///
AffineMap Parser::parseAffineMapReference() {
if (getToken().isNot(Token::hash_identifier)) {
// Try to parse inline affine map.
return AffineParser(state).parseAffineMapInline();
}
// Parse affine map identifier and verify that it exists.
StringRef id = getTokenSpelling().drop_front();
if (getState().affineMapDefinitions.count(id) > 0) {
consumeToken(Token::hash_identifier);
return getState().affineMapDefinitions[id];
}
// The id isn't among any of the recorded definitions.
emitError("undefined affine map id '" + id + "'");
return AffineMap();
}
/// Parse an ambiguous reference to either and affine map or an integer set.
ParseResult Parser::parseAffineMapOrIntegerSetReference(AffineMap &map,
IntegerSet &set) {
if (getToken().isNot(Token::hash_identifier)) {
// Try to parse inline affine map.
return AffineParser(state).parseAffineMapOrIntegerSetInline(map, set);
}
// Parse affine map / integer set identifier and verify that it exists.
// Note that an id can't be in both affineMapDefinitions and
// integerSetDefinitions since they use the same sigil '#'.
StringRef id = getTokenSpelling().drop_front();
if (getState().affineMapDefinitions.count(id) > 0) {
consumeToken(Token::hash_identifier);
map = getState().affineMapDefinitions[id];
return ParseSuccess;
}
if (getState().integerSetDefinitions.count(id) > 0) {
consumeToken(Token::hash_identifier);
set = getState().integerSetDefinitions[id];
return ParseSuccess;
}
// The id isn't among any of the recorded definitions.
emitError("undefined affine map or integer set id '" + id + "'");
return ParseFailure;
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -3402,7 +3405,7 @@ IntegerSet AffineParser::parseIntegerSetConstraints(unsigned numDims,
unsigned numSymbols) { unsigned numSymbols) {
if (parseToken(Token::l_paren, if (parseToken(Token::l_paren,
"expected '(' at start of integer set constraint list")) "expected '(' at start of integer set constraint list"))
return IntegerSet::Null(); return IntegerSet();
SmallVector<AffineExpr, 4> constraints; SmallVector<AffineExpr, 4> constraints;
SmallVector<bool, 4> isEqs; SmallVector<bool, 4> isEqs;
@ -3422,24 +3425,18 @@ IntegerSet AffineParser::parseIntegerSetConstraints(unsigned numDims,
// affine-constraint)* `) // affine-constraint)* `)
auto constraintListLoc = getToken().getLoc(); auto constraintListLoc = getToken().getLoc();
if (parseCommaSeparatedListUntil(Token::r_paren, parseElt, true)) if (parseCommaSeparatedListUntil(Token::r_paren, parseElt, true))
return IntegerSet::Null(); return IntegerSet();
// Check that at least one constraint was parsed. // Check that at least one constraint was parsed.
if (constraints.empty()) { if (constraints.empty()) {
emitError(constraintListLoc, "expected a valid affine constraint"); emitError(constraintListLoc, "expected a valid affine constraint");
return IntegerSet::Null(); return IntegerSet();
} }
// Parsed a valid integer set. // Parsed a valid integer set.
return builder.getIntegerSet(numDims, numSymbols, constraints, isEqs); return builder.getIntegerSet(numDims, numSymbols, constraints, isEqs);
} }
IntegerSet Parser::parseIntegerSetInline() {
IntegerSet set;
AffineParser(state).parseAffineStructureInline(nullptr, &set);
return set;
}
/// If instruction. /// If instruction.
/// ///
/// ml-if-head ::= `if` ml-if-cond trailing-location? `{` inst* `}` /// ml-if-head ::= `if` ml-if-cond trailing-location? `{` inst* `}`
@ -3564,15 +3561,16 @@ ParseResult ModuleParser::parseAffineStructureDef() {
AffineMap map; AffineMap map;
IntegerSet set; IntegerSet set;
parseAffineStructureInline(&map, &set); if (AffineParser(getState()).parseAffineMapOrIntegerSetInline(map, set))
if (!map && !set)
return ParseFailure; return ParseFailure;
if (map) if (map) {
getState().affineMapDefinitions[affineStructureId] = map; getState().affineMapDefinitions[affineStructureId] = map;
else return ParseSuccess;
getState().integerSetDefinitions[affineStructureId] = set; }
assert(set);
getState().integerSetDefinitions[affineStructureId] = set;
return ParseSuccess; return ParseSuccess;
} }

View File

@ -595,7 +595,7 @@ static bool buildSliceTripCountMap(
for (unsigned i = 0; i < numSrcLoopIVs; ++i) { for (unsigned i = 0; i < numSrcLoopIVs; ++i) {
AffineMap lbMap = sliceState->lbs[i]; AffineMap lbMap = sliceState->lbs[i];
AffineMap ubMap = sliceState->ubs[i]; AffineMap ubMap = sliceState->ubs[i];
if (lbMap == AffineMap::Null() || ubMap == AffineMap::Null()) { if (lbMap == AffineMap() || ubMap == AffineMap()) {
// The iteration of src loop IV 'i' was not sliced. Use full loop bounds. // The iteration of src loop IV 'i' was not sliced. Use full loop bounds.
if (srcLoopIVs[i]->hasConstantLowerBound() && if (srcLoopIVs[i]->hasConstantLowerBound() &&
srcLoopIVs[i]->hasConstantUpperBound()) { srcLoopIVs[i]->hasConstantUpperBound()) {
@ -675,16 +675,16 @@ static bool getSliceUnion(const ComputationSliceState &sliceStateA,
for (unsigned i = 0, e = sliceStateA.lbs.size(); i < e; ++i) { for (unsigned i = 0, e = sliceStateA.lbs.size(); i < e; ++i) {
AffineMap lbMapA = sliceStateA.lbs[i]; AffineMap lbMapA = sliceStateA.lbs[i];
AffineMap ubMapA = sliceStateA.ubs[i]; AffineMap ubMapA = sliceStateA.ubs[i];
if (lbMapA == AffineMap::Null()) { if (lbMapA == AffineMap()) {
assert(ubMapA == AffineMap::Null()); assert(ubMapA == AffineMap());
continue; continue;
} }
assert(ubMapA && "expected non-null ub map"); assert(ubMapA && "expected non-null ub map");
AffineMap lbMapB = sliceStateB->lbs[i]; AffineMap lbMapB = sliceStateB->lbs[i];
AffineMap ubMapB = sliceStateB->ubs[i]; AffineMap ubMapB = sliceStateB->ubs[i];
if (lbMapB == AffineMap::Null()) { if (lbMapB == AffineMap()) {
assert(ubMapB == AffineMap::Null()); assert(ubMapB == AffineMap());
// Union 'sliceStateB' does not have a bound for 'i' so copy from A. // Union 'sliceStateB' does not have a bound for 'i' so copy from A.
sliceStateB->lbs[i] = lbMapA; sliceStateB->lbs[i] = lbMapA;
sliceStateB->ubs[i] = ubMapA; sliceStateB->ubs[i] = ubMapA;
@ -799,7 +799,7 @@ static Value *createPrivateMemRef(ForInst *forInst,
} }
auto indexRemap = auto indexRemap =
zeroOffsetCount == rank zeroOffsetCount == rank
? AffineMap::Null() ? AffineMap()
: b.getAffineMap(outerIVs.size() + rank, 0, remapExprs, {}); : b.getAffineMap(outerIVs.size() + rank, 0, remapExprs, {});
// Replace all users of 'oldMemRef' with 'newMemRef'. // Replace all users of 'oldMemRef' with 'newMemRef'.
bool ret = bool ret =
@ -1107,11 +1107,11 @@ static bool isFusionProfitable(OperationInst *srcOpInst,
// Canonicalize slice bound affine maps. // Canonicalize slice bound affine maps.
for (unsigned i = 0; i < numSrcLoopIVs; ++i) { for (unsigned i = 0; i < numSrcLoopIVs; ++i) {
if (sliceState->lbs[i] != AffineMap::Null()) { if (sliceState->lbs[i] != AffineMap()) {
canonicalizeMapAndOperands(&sliceState->lbs[i], canonicalizeMapAndOperands(&sliceState->lbs[i],
&sliceState->lbOperands[i]); &sliceState->lbOperands[i]);
} }
if (sliceState->ubs[i] != AffineMap::Null()) { if (sliceState->ubs[i] != AffineMap()) {
canonicalizeMapAndOperands(&sliceState->ubs[i], canonicalizeMapAndOperands(&sliceState->ubs[i],
&sliceState->ubOperands[i]); &sliceState->ubOperands[i]);
} }

View File

@ -127,7 +127,7 @@ static bool doubleBuffer(Value *oldMemRef, ForInst *forInst) {
// replaceAllMemRefUsesWith will always succeed unless the forInst body has // replaceAllMemRefUsesWith will always succeed unless the forInst body has
// non-deferencing uses of the memref. // non-deferencing uses of the memref.
if (!replaceAllMemRefUsesWith(oldMemRef, newMemRef, ivModTwoOp->getResult(0), if (!replaceAllMemRefUsesWith(oldMemRef, newMemRef, ivModTwoOp->getResult(0),
AffineMap::Null(), {}, AffineMap(), {},
&*forInst->getBody()->begin())) { &*forInst->getBody()->begin())) {
LLVM_DEBUG(llvm::dbgs() LLVM_DEBUG(llvm::dbgs()
<< "memref replacement for double buffering failed\n";); << "memref replacement for double buffering failed\n";);

View File

@ -46,12 +46,12 @@ AffineMap mlir::getUnrolledLoopUpperBound(const ForInst &forInst,
// Single result lower bound map only. // Single result lower bound map only.
if (lbMap.getNumResults() != 1) if (lbMap.getNumResults() != 1)
return AffineMap::Null(); return AffineMap();
// Sometimes, the trip count cannot be expressed as an affine expression. // Sometimes, the trip count cannot be expressed as an affine expression.
auto tripCount = getTripCountExpr(forInst); auto tripCount = getTripCountExpr(forInst);
if (!tripCount) if (!tripCount)
return AffineMap::Null(); return AffineMap();
AffineExpr lb(lbMap.getResult(0)); AffineExpr lb(lbMap.getResult(0));
unsigned step = forInst.getStep(); unsigned step = forInst.getStep();
@ -72,12 +72,12 @@ AffineMap mlir::getCleanupLoopLowerBound(const ForInst &forInst,
// Single result lower bound map only. // Single result lower bound map only.
if (lbMap.getNumResults() != 1) if (lbMap.getNumResults() != 1)
return AffineMap::Null(); return AffineMap();
// Sometimes the trip count cannot be expressed as an affine expression. // Sometimes the trip count cannot be expressed as an affine expression.
AffineExpr tripCount(getTripCountExpr(forInst)); AffineExpr tripCount(getTripCountExpr(forInst));
if (!tripCount) if (!tripCount)
return AffineMap::Null(); return AffineMap();
AffineExpr lb(lbMap.getResult(0)); AffineExpr lb(lbMap.getResult(0));
unsigned step = forInst.getStep(); unsigned step = forInst.getStep();