forked from OSchip/llvm-project
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:
parent
81c7f2e2f3
commit
0e7a8a9027
|
@ -378,7 +378,7 @@ public:
|
|||
/// identifiers as an affine map of the remaining identifiers (dimensional and
|
||||
/// symbolic). This method is able to detect identifiers as floordiv's
|
||||
/// 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).
|
||||
void getSliceBounds(unsigned num, MLIRContext *context,
|
||||
SmallVectorImpl<AffineMap> *lbMaps,
|
||||
|
|
|
@ -46,8 +46,10 @@ class AffineMap {
|
|||
public:
|
||||
using ImplType = detail::AffineMapStorage;
|
||||
|
||||
explicit AffineMap(ImplType *map = nullptr) : map(map) {}
|
||||
static AffineMap Null() { return AffineMap(nullptr); }
|
||||
AffineMap() : map(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,
|
||||
ArrayRef<AffineExpr> results,
|
||||
|
@ -62,9 +64,9 @@ public:
|
|||
|
||||
MLIRContext *getContext() const;
|
||||
|
||||
explicit operator bool() { return map; }
|
||||
bool operator==(const AffineMap &other) const { return other.map == map; }
|
||||
bool operator!=(const AffineMap &other) const { return !(other.map == map); }
|
||||
explicit operator bool() { return map != nullptr; }
|
||||
bool operator==(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
|
||||
/// map is bounded. Bounded affine maps have a size (extent) for each of
|
||||
|
|
|
@ -52,12 +52,10 @@ class IntegerSet {
|
|||
public:
|
||||
using ImplType = detail::IntegerSetStorage;
|
||||
|
||||
explicit IntegerSet(ImplType *set = nullptr) : set(set) {}
|
||||
|
||||
IntegerSet &operator=(const IntegerSet other) {
|
||||
set = other.set;
|
||||
return *this;
|
||||
}
|
||||
IntegerSet() : set(nullptr) {}
|
||||
explicit IntegerSet(ImplType *set) : set(set) {}
|
||||
IntegerSet(const IntegerSet &other) : set(other.set) {}
|
||||
IntegerSet &operator=(const IntegerSet &other) = default;
|
||||
|
||||
static IntegerSet get(unsigned dimCount, unsigned symbolCount,
|
||||
ArrayRef<AffineExpr> constraints,
|
||||
|
@ -74,8 +72,6 @@ public:
|
|||
/// Returns true if this is the canonical integer set.
|
||||
bool isEmptyIntegerSet() const;
|
||||
|
||||
static IntegerSet Null() { return IntegerSet(nullptr); }
|
||||
|
||||
explicit operator bool() { return set; }
|
||||
bool operator==(IntegerSet other) const { return set == other.set; }
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ class Function;
|
|||
// TODO(bondhugula): allow extraIndices to be added at any position.
|
||||
bool replaceAllMemRefUsesWith(const Value *oldMemRef, Value *newMemRef,
|
||||
ArrayRef<Value *> extraIndices = {},
|
||||
AffineMap indexRemap = AffineMap::Null(),
|
||||
AffineMap indexRemap = AffineMap(),
|
||||
ArrayRef<Value *> extraOperands = {},
|
||||
const Instruction *domInstFilter = nullptr);
|
||||
|
||||
|
|
|
@ -1133,8 +1133,8 @@ void FlatAffineConstraints::getSliceBounds(unsigned num, MLIRContext *context,
|
|||
numMapDims, numMapSymbols,
|
||||
getAffineConstantExpr(ubConst.getValue() + 1, context), {});
|
||||
} else {
|
||||
(*lbMaps)[pos] = AffineMap::Null();
|
||||
(*ubMaps)[pos] = AffineMap::Null();
|
||||
(*lbMaps)[pos] = AffineMap();
|
||||
(*ubMaps)[pos] = AffineMap();
|
||||
}
|
||||
}
|
||||
LLVM_DEBUG(llvm::dbgs() << "lb map for pos = " << Twine(pos) << ", expr: ");
|
||||
|
|
|
@ -410,8 +410,8 @@ bool mlir::getBackwardComputationSliceState(const MemRefAccess &srcAccess,
|
|||
numDstLoopIVs - dstLoopDepth);
|
||||
|
||||
// Set up lower/upper bound affine maps for the slice.
|
||||
sliceState->lbs.resize(numSrcLoopIVs, AffineMap::Null());
|
||||
sliceState->ubs.resize(numSrcLoopIVs, AffineMap::Null());
|
||||
sliceState->lbs.resize(numSrcLoopIVs, AffineMap());
|
||||
sliceState->ubs.resize(numSrcLoopIVs, AffineMap());
|
||||
|
||||
// Get bounds for src IVs in terms of dst IVs, symbols, and constants.
|
||||
dependenceConstraints.getSliceBounds(numSrcLoopIVs,
|
||||
|
|
|
@ -612,10 +612,12 @@ bool OperationInst::emitOpError(const Twine &message) const {
|
|||
ForInst *ForInst::create(Location location, ArrayRef<Value *> lbOperands,
|
||||
AffineMap lbMap, ArrayRef<Value *> ubOperands,
|
||||
AffineMap ubMap, int64_t step) {
|
||||
assert(lbOperands.size() == lbMap.getNumInputs() &&
|
||||
"lower bound operand count does not match the affine map");
|
||||
assert(ubOperands.size() == ubMap.getNumInputs() &&
|
||||
"upper bound operand count does not match the affine map");
|
||||
assert((!lbMap && lbOperands.empty()) ||
|
||||
lbOperands.size() == lbMap.getNumInputs() &&
|
||||
"lower bound operand count does not match the affine map");
|
||||
assert((!ubMap && ubOperands.empty()) ||
|
||||
ubOperands.size() == ubMap.getNumInputs() &&
|
||||
"upper bound operand count does not match the affine map");
|
||||
assert(step > 0 && "step has to be a positive integer constant");
|
||||
|
||||
unsigned numOperands = lbOperands.size() + ubOperands.size();
|
||||
|
|
|
@ -1202,7 +1202,7 @@ AffineMap AffineMap::get(unsigned dimCount, unsigned symbolCount,
|
|||
|
||||
// Check if we already have this affine map.
|
||||
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 (!existing.second)
|
||||
|
|
|
@ -200,12 +200,10 @@ public:
|
|||
ParseResult parseAttributeDict(SmallVectorImpl<NamedAttribute> &attributes);
|
||||
|
||||
// Polyhedral structures.
|
||||
void parseAffineStructureInline(AffineMap *map, IntegerSet *set);
|
||||
void parseAffineStructureReference(AffineMap *map, IntegerSet *set);
|
||||
AffineMap parseAffineMapInline();
|
||||
AffineMap parseAffineMapReference();
|
||||
IntegerSet parseIntegerSetInline();
|
||||
IntegerSet parseIntegerSetReference();
|
||||
ParseResult parseAffineMapOrIntegerSetReference(AffineMap &map,
|
||||
IntegerSet &set);
|
||||
DenseElementsAttr parseDenseElementsAttr(VectorOrTensorType type);
|
||||
DenseElementsAttr parseDenseElementsAttr(Type eltType, bool isVector);
|
||||
VectorOrTensorType parseVectorOrTensorType();
|
||||
|
@ -997,13 +995,13 @@ Attribute Parser::parseAttribute(Type type) {
|
|||
// Try to parse an affine map or an integer set reference.
|
||||
AffineMap map;
|
||||
IntegerSet set;
|
||||
parseAffineStructureReference(&map, &set);
|
||||
if (parseAffineMapOrIntegerSetReference(map, set))
|
||||
return (emitError("expected affine map or integer set attribute value"),
|
||||
nullptr);
|
||||
if (map)
|
||||
return builder.getAffineMapAttr(map);
|
||||
if (set)
|
||||
return builder.getIntegerSetAttr(set);
|
||||
return (emitError("expected affine map or integer set attribute value"),
|
||||
nullptr);
|
||||
assert(set);
|
||||
return builder.getIntegerSetAttr(set);
|
||||
}
|
||||
|
||||
case Token::at_identifier: {
|
||||
|
@ -1474,8 +1472,10 @@ class AffineParser : public Parser {
|
|||
public:
|
||||
explicit AffineParser(ParserState &state) : Parser(state) {}
|
||||
|
||||
void parseAffineStructureInline(AffineMap *map, IntegerSet *set);
|
||||
AffineMap parseAffineMapInline();
|
||||
AffineMap parseAffineMapRange(unsigned numDims, unsigned numSymbols);
|
||||
IntegerSet parseIntegerSetInline();
|
||||
ParseResult parseAffineMapOrIntegerSetInline(AffineMap &map, IntegerSet &set);
|
||||
IntegerSet parseIntegerSetConstraints(unsigned numDims, unsigned numSymbols);
|
||||
|
||||
private:
|
||||
|
@ -1486,6 +1486,8 @@ private:
|
|||
// Identifier lists for polyhedral structures.
|
||||
ParseResult parseDimIdList(unsigned &numDims);
|
||||
ParseResult parseSymbolIdList(unsigned &numSymbols);
|
||||
ParseResult parseDimAndOptionalSymbolIdList(unsigned &numDims,
|
||||
unsigned &numSymbols);
|
||||
ParseResult parseIdentifierDefinition(AffineExpr idExpr);
|
||||
|
||||
AffineExpr parseAffineExpr();
|
||||
|
@ -1841,6 +1843,20 @@ ParseResult AffineParser::parseIdentifierDefinition(AffineExpr idExpr) {
|
|||
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.
|
||||
ParseResult AffineParser::parseSymbolIdList(unsigned &numSymbols) {
|
||||
consumeToken(Token::l_square);
|
||||
|
@ -1851,23 +1867,21 @@ ParseResult AffineParser::parseSymbolIdList(unsigned &numSymbols) {
|
|||
return parseCommaSeparatedListUntil(Token::r_square, parseElt);
|
||||
}
|
||||
|
||||
/// 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.
|
||||
ParseResult
|
||||
AffineParser::parseDimAndOptionalSymbolIdList(unsigned &numDims,
|
||||
unsigned &numSymbols) {
|
||||
if (parseDimIdList(numDims)) {
|
||||
return ParseResult::ParseFailure;
|
||||
}
|
||||
if (!getToken().is(Token::l_square)) {
|
||||
numSymbols = 0;
|
||||
return ParseResult::ParseSuccess;
|
||||
}
|
||||
return parseSymbolIdList(numSymbols);
|
||||
}
|
||||
|
||||
/// Parses either an affine map or an integer set definition inline. If both
|
||||
/// '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.
|
||||
/// Parses an affine map definition inline.
|
||||
///
|
||||
/// affine-map-inline ::= dim-and-symbol-id-lists `->` multi-dim-affine-expr
|
||||
/// (`size` `(` dim-size (`,` dim-size)* `)`)?
|
||||
|
@ -1875,6 +1889,23 @@ ParseResult AffineParser::parseDimIdList(unsigned &numDims) {
|
|||
///
|
||||
/// 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
|
||||
/// ::= dim-and-symbol-id-lists `:`
|
||||
|
@ -1883,68 +1914,49 @@ ParseResult AffineParser::parseDimIdList(unsigned &numDims) {
|
|||
/// | affine-constraint (`,`
|
||||
/// affine-constraint)*
|
||||
///
|
||||
void AffineParser::parseAffineStructureInline(AffineMap *map, IntegerSet *set) {
|
||||
assert((map || set) && "one of map or set expected to be non-null");
|
||||
|
||||
IntegerSet AffineParser::parseIntegerSetInline() {
|
||||
unsigned numDims = 0, numSymbols = 0;
|
||||
|
||||
// List of dimensional identifiers.
|
||||
if (parseDimIdList(numDims)) {
|
||||
if (map)
|
||||
*map = AffineMap::Null();
|
||||
if (set)
|
||||
*set = IntegerSet::Null();
|
||||
return;
|
||||
// List of dimensional and optional symbol identifiers.
|
||||
if (parseDimAndOptionalSymbolIdList(numDims, numSymbols)) {
|
||||
return IntegerSet();
|
||||
}
|
||||
|
||||
// Symbols are optional.
|
||||
if (getToken().is(Token::l_square)) {
|
||||
if (parseSymbolIdList(numSymbols)) {
|
||||
if (map)
|
||||
*map = AffineMap::Null();
|
||||
if (set)
|
||||
*set = IntegerSet::Null();
|
||||
return;
|
||||
}
|
||||
if (parseToken(Token::colon, "expected ':' or '['")) {
|
||||
return IntegerSet();
|
||||
}
|
||||
|
||||
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
|
||||
// be parsing an integer set attribute or an affine map attribute.
|
||||
if (map && set && getToken().isNot(Token::arrow) &&
|
||||
getToken().isNot(Token::colon)) {
|
||||
emitError("expected '->' or ':' or '['");
|
||||
*map = AffineMap::Null();
|
||||
*set = IntegerSet::Null();
|
||||
return;
|
||||
bool isArrow = getToken().is(Token::arrow);
|
||||
bool isColon = getToken().is(Token::colon);
|
||||
if (!isArrow && !isColon) {
|
||||
return ParseFailure;
|
||||
} else if (isArrow) {
|
||||
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))) {
|
||||
// Parse an affine map.
|
||||
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 = parseIntegerSetConstraints(numDims, numSymbols)))
|
||||
return ParseSuccess;
|
||||
|
||||
if (set && (!map || getToken().is(Token::colon))) {
|
||||
// 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;
|
||||
}
|
||||
return ParseFailure;
|
||||
}
|
||||
|
||||
/// 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:
|
||||
// multi-dim-affine-expr ::= `(` affine-expr (`,` affine-expr)* `)
|
||||
if (parseCommaSeparatedListUntil(Token::r_paren, parseElt, false))
|
||||
return AffineMap::Null();
|
||||
return AffineMap();
|
||||
|
||||
// Parse optional range sizes.
|
||||
// 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.
|
||||
auto loc = getToken().getLoc();
|
||||
if (parseToken(Token::l_paren, "expected '(' at start of affine map range"))
|
||||
return AffineMap::Null();
|
||||
return AffineMap();
|
||||
|
||||
auto parseRangeSize = [&]() -> ParseResult {
|
||||
auto loc = getToken().getLoc();
|
||||
|
@ -1999,99 +2011,90 @@ AffineMap AffineParser::parseAffineMapRange(unsigned numDims,
|
|||
};
|
||||
|
||||
if (parseCommaSeparatedListUntil(Token::r_paren, parseRangeSize, false))
|
||||
return AffineMap::Null();
|
||||
return AffineMap();
|
||||
if (exprs.size() > rangeSizes.size())
|
||||
return (emitError(loc, "fewer range sizes than range expressions"),
|
||||
AffineMap::Null());
|
||||
AffineMap());
|
||||
if (exprs.size() < rangeSizes.size())
|
||||
return (emitError(loc, "more range sizes than range expressions"),
|
||||
AffineMap::Null());
|
||||
AffineMap());
|
||||
}
|
||||
|
||||
// Parsed a valid affine map.
|
||||
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.
|
||||
/// integer-set ::= integer-set-id | integer-set-inline
|
||||
/// integer-set-id ::= `#` suffix-id
|
||||
///
|
||||
IntegerSet Parser::parseIntegerSetReference() {
|
||||
IntegerSet set;
|
||||
parseAffineStructureReference(nullptr, &set);
|
||||
return set;
|
||||
if (getToken().isNot(Token::hash_identifier)) {
|
||||
// Try to parse inline integer 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) {
|
||||
if (parseToken(Token::l_paren,
|
||||
"expected '(' at start of integer set constraint list"))
|
||||
return IntegerSet::Null();
|
||||
return IntegerSet();
|
||||
|
||||
SmallVector<AffineExpr, 4> constraints;
|
||||
SmallVector<bool, 4> isEqs;
|
||||
|
@ -3422,24 +3425,18 @@ IntegerSet AffineParser::parseIntegerSetConstraints(unsigned numDims,
|
|||
// affine-constraint)* `)
|
||||
auto constraintListLoc = getToken().getLoc();
|
||||
if (parseCommaSeparatedListUntil(Token::r_paren, parseElt, true))
|
||||
return IntegerSet::Null();
|
||||
return IntegerSet();
|
||||
|
||||
// Check that at least one constraint was parsed.
|
||||
if (constraints.empty()) {
|
||||
emitError(constraintListLoc, "expected a valid affine constraint");
|
||||
return IntegerSet::Null();
|
||||
return IntegerSet();
|
||||
}
|
||||
|
||||
// Parsed a valid integer set.
|
||||
return builder.getIntegerSet(numDims, numSymbols, constraints, isEqs);
|
||||
}
|
||||
|
||||
IntegerSet Parser::parseIntegerSetInline() {
|
||||
IntegerSet set;
|
||||
AffineParser(state).parseAffineStructureInline(nullptr, &set);
|
||||
return set;
|
||||
}
|
||||
|
||||
/// If instruction.
|
||||
///
|
||||
/// ml-if-head ::= `if` ml-if-cond trailing-location? `{` inst* `}`
|
||||
|
@ -3564,15 +3561,16 @@ ParseResult ModuleParser::parseAffineStructureDef() {
|
|||
|
||||
AffineMap map;
|
||||
IntegerSet set;
|
||||
parseAffineStructureInline(&map, &set);
|
||||
if (!map && !set)
|
||||
if (AffineParser(getState()).parseAffineMapOrIntegerSetInline(map, set))
|
||||
return ParseFailure;
|
||||
|
||||
if (map)
|
||||
if (map) {
|
||||
getState().affineMapDefinitions[affineStructureId] = map;
|
||||
else
|
||||
getState().integerSetDefinitions[affineStructureId] = set;
|
||||
return ParseSuccess;
|
||||
}
|
||||
|
||||
assert(set);
|
||||
getState().integerSetDefinitions[affineStructureId] = set;
|
||||
return ParseSuccess;
|
||||
}
|
||||
|
||||
|
|
|
@ -595,7 +595,7 @@ static bool buildSliceTripCountMap(
|
|||
for (unsigned i = 0; i < numSrcLoopIVs; ++i) {
|
||||
AffineMap lbMap = sliceState->lbs[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.
|
||||
if (srcLoopIVs[i]->hasConstantLowerBound() &&
|
||||
srcLoopIVs[i]->hasConstantUpperBound()) {
|
||||
|
@ -675,16 +675,16 @@ static bool getSliceUnion(const ComputationSliceState &sliceStateA,
|
|||
for (unsigned i = 0, e = sliceStateA.lbs.size(); i < e; ++i) {
|
||||
AffineMap lbMapA = sliceStateA.lbs[i];
|
||||
AffineMap ubMapA = sliceStateA.ubs[i];
|
||||
if (lbMapA == AffineMap::Null()) {
|
||||
assert(ubMapA == AffineMap::Null());
|
||||
if (lbMapA == AffineMap()) {
|
||||
assert(ubMapA == AffineMap());
|
||||
continue;
|
||||
}
|
||||
assert(ubMapA && "expected non-null ub map");
|
||||
|
||||
AffineMap lbMapB = sliceStateB->lbs[i];
|
||||
AffineMap ubMapB = sliceStateB->ubs[i];
|
||||
if (lbMapB == AffineMap::Null()) {
|
||||
assert(ubMapB == AffineMap::Null());
|
||||
if (lbMapB == AffineMap()) {
|
||||
assert(ubMapB == AffineMap());
|
||||
// Union 'sliceStateB' does not have a bound for 'i' so copy from A.
|
||||
sliceStateB->lbs[i] = lbMapA;
|
||||
sliceStateB->ubs[i] = ubMapA;
|
||||
|
@ -799,7 +799,7 @@ static Value *createPrivateMemRef(ForInst *forInst,
|
|||
}
|
||||
auto indexRemap =
|
||||
zeroOffsetCount == rank
|
||||
? AffineMap::Null()
|
||||
? AffineMap()
|
||||
: b.getAffineMap(outerIVs.size() + rank, 0, remapExprs, {});
|
||||
// Replace all users of 'oldMemRef' with 'newMemRef'.
|
||||
bool ret =
|
||||
|
@ -1107,11 +1107,11 @@ static bool isFusionProfitable(OperationInst *srcOpInst,
|
|||
|
||||
// Canonicalize slice bound affine maps.
|
||||
for (unsigned i = 0; i < numSrcLoopIVs; ++i) {
|
||||
if (sliceState->lbs[i] != AffineMap::Null()) {
|
||||
if (sliceState->lbs[i] != AffineMap()) {
|
||||
canonicalizeMapAndOperands(&sliceState->lbs[i],
|
||||
&sliceState->lbOperands[i]);
|
||||
}
|
||||
if (sliceState->ubs[i] != AffineMap::Null()) {
|
||||
if (sliceState->ubs[i] != AffineMap()) {
|
||||
canonicalizeMapAndOperands(&sliceState->ubs[i],
|
||||
&sliceState->ubOperands[i]);
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ static bool doubleBuffer(Value *oldMemRef, ForInst *forInst) {
|
|||
// replaceAllMemRefUsesWith will always succeed unless the forInst body has
|
||||
// non-deferencing uses of the memref.
|
||||
if (!replaceAllMemRefUsesWith(oldMemRef, newMemRef, ivModTwoOp->getResult(0),
|
||||
AffineMap::Null(), {},
|
||||
AffineMap(), {},
|
||||
&*forInst->getBody()->begin())) {
|
||||
LLVM_DEBUG(llvm::dbgs()
|
||||
<< "memref replacement for double buffering failed\n";);
|
||||
|
|
|
@ -46,12 +46,12 @@ AffineMap mlir::getUnrolledLoopUpperBound(const ForInst &forInst,
|
|||
|
||||
// Single result lower bound map only.
|
||||
if (lbMap.getNumResults() != 1)
|
||||
return AffineMap::Null();
|
||||
return AffineMap();
|
||||
|
||||
// Sometimes, the trip count cannot be expressed as an affine expression.
|
||||
auto tripCount = getTripCountExpr(forInst);
|
||||
if (!tripCount)
|
||||
return AffineMap::Null();
|
||||
return AffineMap();
|
||||
|
||||
AffineExpr lb(lbMap.getResult(0));
|
||||
unsigned step = forInst.getStep();
|
||||
|
@ -72,12 +72,12 @@ AffineMap mlir::getCleanupLoopLowerBound(const ForInst &forInst,
|
|||
|
||||
// Single result lower bound map only.
|
||||
if (lbMap.getNumResults() != 1)
|
||||
return AffineMap::Null();
|
||||
return AffineMap();
|
||||
|
||||
// Sometimes the trip count cannot be expressed as an affine expression.
|
||||
AffineExpr tripCount(getTripCountExpr(forInst));
|
||||
if (!tripCount)
|
||||
return AffineMap::Null();
|
||||
return AffineMap();
|
||||
|
||||
AffineExpr lb(lbMap.getResult(0));
|
||||
unsigned step = forInst.getStep();
|
||||
|
|
Loading…
Reference in New Issue