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
|
/// 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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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: ");
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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");
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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";);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue