From 18fbc3e170edbf4770acc3d6654be7c0423e71fd Mon Sep 17 00:00:00 2001 From: Uday Bondhugula Date: Sun, 30 Dec 2018 21:22:00 -0800 Subject: [PATCH] Drop unusued HyperRectangularSet.h/.cpp, given the new design being worked on. - drop these ununsed/incomplete sketches given the new design @albertcohen is working on, and given that FlatAffineConstraints is now stable and fast enough for all the analyses/transforms that depend on it. PiperOrigin-RevId: 227322739 --- .../mlir/Analysis/HyperRectangularSet.h | 321 ------------------ mlir/lib/Analysis/HyperRectangularSet.cpp | 199 ----------- 2 files changed, 520 deletions(-) delete mode 100644 mlir/include/mlir/Analysis/HyperRectangularSet.h delete mode 100644 mlir/lib/Analysis/HyperRectangularSet.cpp diff --git a/mlir/include/mlir/Analysis/HyperRectangularSet.h b/mlir/include/mlir/Analysis/HyperRectangularSet.h deleted file mode 100644 index 52c242c06074..000000000000 --- a/mlir/include/mlir/Analysis/HyperRectangularSet.h +++ /dev/null @@ -1,321 +0,0 @@ -//===- HyperRectangularSet.h - MLIR HyperRectangle Class --------*- C++ -*-===// -// -// Copyright 2019 The MLIR Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ============================================================================= -// -// A symbolic hyper-rectangular set of integer points for analysis. -// -//===----------------------------------------------------------------------===// - -#ifndef MLIR_ANALYSIS_HYPER_RECTANGULAR_SET_H -#define MLIR_ANALYSIS_HYPER_RECTANGULAR_SET_H - -#include - -#include "mlir/Analysis/AffineStructures.h" -#include "mlir/IR/AffineExpr.h" -#include "mlir/IR/IntegerSet.h" -#include "llvm/ADT/ilist.h" -#include "llvm/ADT/ilist_node.h" - -namespace mlir { - -class AffineApplyOp; -class AffineBound; -class AffineCondition; -class AffineMap; -class IntegerSet; -class MLIRContext; -class MutableIntegerSet; -class FlatAffineConstraints; -class HyperRectangleList; -class Value; - -/// A list of affine bounds. -// Not using a MutableAffineMap here since numSymbols is the same as the -// containing HyperRectangularSet's numSymbols, and its numDims is 0. -using AffineBoundExprList = SmallVector; - -/// A HyperRectangularSet is a symbolic set of integer points contained in a -/// hyper-rectangular space. It supports set manipulation operations -/// and other queries to aid analysis of multi-dimensional integer sets that can -/// be represented as integer points inside a symbolic hyper-rectangle, i.e., -/// an interval is associated with each dimension, and the lower and upper -/// bounds of each interval are symbolic affine expressions. The bounds on -/// a 'dimension' can't depend on other 'dimensions'. The fields of this set are -/// always maintained in an irredundant form (no redundant bounds), and the -/// bounds are simplified under its context field. -// -// Example: dims: (d0, d1), symbols: (M, N) -// 0 <= d0 <= 511 -// max(128,M) <= d1 <= min(N-1,256) -// -// Symbols here aren't necessarily associated with Function's symbols; they -// could also correspond to outer loop IVs for example or anything abstract. The -// binding to SSA values for dimensions/symbols is optional, and these are in an -// abstract integer domain. As an example, to describe data accessed in a tile -// surrounded by loop i0, i1, the following set symbolic in i0, i1 is a -// hyper-rectangular set: -// -// 128*i <= d0 <= min(128*i0 + 127, N-1) -// 128*i <= d1 <= min(128*i1 + 127, N-1) -// -// The context field specifies constraints on the symbols, and the set is always -// kept in a form simplified under 'context', i.e., information implied by -// context is used to simplify bounds. For eg., if the context includes (N >= -// 0), a bound such as d0 >= max(0, N) will never arise. This would be -// simplified to d0 >= N at construction time or when the context is updated. -// As another example, if N%128 = 0, M <= N-1 floordiv 128 is specified, we will -// never have a bound such as d0 <= min(128*M + 127, N-1); this would be -// simplified to d0 <= 128*M + 127 (since 128*M + 127 is always <= N-1 under -// such circumstances). In the context of code generation, such simplification -// leads to code that explicitly scans "full" tiles / no boundary case and with -// lower control overhead. -// -class HyperRectangularSet - : public llvm::ilist_node_with_parent { -public: - /// Construct a hyper-rectangular set from FlatAffineConstraints if possible; - /// returns nullptr if it cannot. - static std::unique_ptr - getFromFlatAffineConstraints(const FlatAffineConstraints &cst); - - HyperRectangularSet(unsigned numDims, unsigned numSymbols, - ArrayRef> lbs, - ArrayRef> ubs, MLIRContext *context, - IntegerSet symbolContext = IntegerSet()); - - unsigned getNumDims() const { return numDims; } - unsigned getNumSymbols() const { return numSymbols; } - - ArrayRef getLowerBounds() const { return lowerBounds; } - ArrayRef getUpperBounds() const { return upperBounds; } - - AffineBoundExprList &getLowerBound(unsigned idx) { return lowerBounds[idx]; } - AffineBoundExprList &getUpperBound(unsigned idx) { return upperBounds[idx]; } - - const AffineBoundExprList &getLowerBound(unsigned idx) const { - return lowerBounds[idx]; - } - const AffineBoundExprList &getUpperBound(unsigned idx) const { - return upperBounds[idx]; - } - - /// Intersects 'rhs' with this set. - void intersect(const HyperRectangularSet &rhs); - - /// Performs a union of 'rhs' with this set. - void unionize(const HyperRectangularSet &rhs); - - /// Project out num dimensions starting from 'idx'. This is equivalent to - /// taking an image of this set on the remaining dimensions. - void projectOut(unsigned idx, unsigned num); - - /// Returns true if the set has no integer points in it. - bool empty() const; - - /// Add a lower bound expression to dimension position 'idx'. - void addLowerBoundExpr(unsigned idx, AffineExpr expr); - - /// Add an upper bound expression to dimension position 'idx'. - void addUpperBoundExpr(unsigned idx, AffineExpr expr); - - /// Clear this set's context, i.e., make it the universal set. - void clearContext() { context.clear(); } - - void print(raw_ostream &os) const; - void dump() const; - -private: - /// Simplify this set under the symbolic context 'context'. - void simplifyUnderContext() {} - - /// The lower bound along any dimension is a max of several pure - /// symbolic/constant affine expressions. A bound cannot be mutated from - /// outside the class, it has to be to be updated through - /// addLowerBoundExpr/addUpperBoundExpr. - std::vector lowerBounds; - // Each upper bound is a min of several pure symbolic/constant affine - // expressions. - std::vector upperBounds; - - Optional> dims = None; - Optional> symbols = None; - - /// Number of real dimensions. - unsigned numDims; - - /// Number of symbols (unknown but constant) - unsigned numSymbols; - - // Constraints on the symbols. The representation of the set is kept - // simplified under this context. - MutableIntegerSet context; -}; - -//===--------------------------------------------------------------------===// -// Out of place operations. -//===--------------------------------------------------------------------===// - -static std::unique_ptr -intersection(const HyperRectangularSet &lhs, const HyperRectangularSet &rhs); - -static std::unique_ptr -intersection(const HyperRectangleList &lhs, const HyperRectangleList &rhs); - -/// Performs a union of 'lhs' and 'rhs'. -static std::unique_ptr -unionize(const HyperRectangularSet &lhs, const HyperRectangularSet &rhs); -static std::unique_ptr -unionize(const HyperRectangleList &lhs, const HyperRectangleList &rhs); - -/// Subtract 'rhs' from this lhs and return the result. -static std::unique_ptr -difference(const HyperRectangularSet &lhs, const HyperRectangularSet &rhs); -static std::unique_ptr -difference(const HyperRectangleList &lhs, const HyperRectangleList &rhs); - -/// Project out num dimensions starting from 'idx'. This is equivalent to -/// taking an image of this set on the remaining dimensions. -static std::unique_ptr -projectOut(const HyperRectangularSet &set, unsigned idx, unsigned num); - -} // namespace mlir - -namespace llvm { - -template <> struct ilist_traits<::mlir::HyperRectangularSet> { - using HyperRectangularSet = ::mlir::HyperRectangularSet; - using set_iterator = simple_ilist::iterator; - - static void deleteNode(HyperRectangularSet *set) { delete set; } - - void addNodeToList(HyperRectangularSet *set); - void removeNodeFromList(HyperRectangularSet *set); - void transferNodesFromList(ilist_traits &otherList, - set_iterator first, set_iterator last); - -private: - mlir::HyperRectangleList *getContainingBlock(); -}; - -} // namespace llvm - -namespace mlir { - -/// A list of hyper-rectangular sets lying in the same space of dimensional -/// and symbolic identifiers. The individual set elements are always kept -/// disjoint (re-evaluate choice) and minimal, i.e., the union of any subset of -/// the contained hyperrectangles can't be coalesced into a single -/// hyper-rectangle. -class HyperRectangleList { -public: - /// Construct a constraint system reserving memory for the specified number of - /// constraints and identifiers. - explicit HyperRectangleList(const FlatAffineConstraints &cst); - - HyperRectangleList(unsigned numDims, unsigned numSymbols, - ArrayRef> sets); - - unsigned getNumDims() const { return numDims; } - unsigned getNumSymbols() const { return numSymbols; } - - // In-place operations. - - /// Intersects a hyper rectangular set list 'rhs' with this set. - void intersect(const HyperRectangleList &rhs); - - /// Intersects 'rhs' with this set. - void intersect(const HyperRectangularSet &rhs); - - /// Performs a union of 'rhs' with this set. - void unionize(const HyperRectangleList &rhs); - - /// Performs a union of 'rhs' with this set. - void unionize(const HyperRectangularSet &rhs); - - /// Project out num dimensions starting from 'idx'. This is equivalent to - /// taking an image of this set on the remaining dimensions. - void projectOut(unsigned idx, unsigned num); - - /// Returns true if all the sets are empty. - bool empty() const; - - //===--------------------------------------------------------------------===// - // Hyper-rectangular set list management. - //===--------------------------------------------------------------------===// - - /// These are for the list of hyper-rectangular set elements. - using HyperRectangleListTy = ::llvm::iplist; - HyperRectangleListTy &getRectangles() { return hyperRectangles; } - - // Iteration over the instructions in the block. - using const_iterator = HyperRectangleListTy::const_iterator; - - const_iterator begin() const { return hyperRectangles.begin(); } - const_iterator end() const { return hyperRectangles.end(); } - - bool listEmpty() const { return hyperRectangles.empty(); } - - void addSet(std::unique_ptr set) { - set->clearContext(); - hyperRectangles.push_back(set.release()); - } - -private: - // Mutable versions of the iterators are private. - using iterator = HyperRectangleListTy::iterator; - iterator begin() { return hyperRectangles.begin(); } - iterator end() { return hyperRectangles.end(); } - - /// Simplify under the symbolic context 'context'. - void simplifyUnderContext() {} - - /// Number of identifiers corresponding to real dimensions. - unsigned numDims; - - /// Number of identifiers corresponding to symbols (unknown but constant) - unsigned numSymbols; - - /// The list of hyper-rectangular sets contained. - HyperRectangleListTy hyperRectangles; - - // Constraints on the symbols. The representation of the set is kept - // simplified under this context. - MutableIntegerSet context; -}; - -// Out of place operations. - -// Return a bounding box of this list of hyper-rectangles. This is notionally -// equivanelt to a rectangular/convex hull. -std::unique_ptr boundingBox(); - -/// Intersects and returns the result. -static std::unique_ptr -intersection(const HyperRectangleList &lhs, const HyperRectangleList &rhs); - -/// Performs a union and returns the result. -static std::unique_ptr -unionize(const HyperRectangleList &lhs, const HyperRectangleList &rhs); - -/// Subtracts 'rhs' from this lhs and return the result. -static std::unique_ptr -difference(const HyperRectangleList &lhs, const HyperRectangleList &rhs); - -} // end namespace mlir. - -#endif // MLIR_ANALYSIS_HYPER_RECTANGULAR_SET_H diff --git a/mlir/lib/Analysis/HyperRectangularSet.cpp b/mlir/lib/Analysis/HyperRectangularSet.cpp deleted file mode 100644 index 90272c4f9056..000000000000 --- a/mlir/lib/Analysis/HyperRectangularSet.cpp +++ /dev/null @@ -1,199 +0,0 @@ -//===- HyperRectangularSet.cpp - MLIR HyperRectangularSet Class -----------===// -// -// Copyright 2019 The MLIR Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ============================================================================= -// -// Structures for affine/polyhedral analysis of MLIR functions. -// -//===----------------------------------------------------------------------===// - -#include "mlir/Analysis/HyperRectangularSet.h" -#include "mlir/IR/AffineExpr.h" -#include "mlir/IR/IntegerSet.h" -#include "llvm/Support/raw_ostream.h" -#include -using namespace mlir; - -// TODO(bondhugula): clean this code up. -// Get the constant bound that is either the min or max (depending on 'cmp'). -static Optional -getReducedConstBound(const HyperRectangularSet &set, unsigned *idx, - std::function const &cmp) { - Optional val = None; - - for (unsigned i = 0, n = set.getNumDims(); i < n; i++) { - auto &ubs = set.getLowerBound(i); - unsigned j = 0; - AffineBoundExprList::const_iterator it, e; - for (it = ubs.begin(), e = ubs.end(); it != e; it++, j++) { - if (auto cExpr = it->dyn_cast()) { - if (val == None) { - val = cExpr.getValue(); - *idx = j; - } else if (cmp(cExpr.getValue(), val.getValue())) { - val = cExpr.getValue(); - *idx = j; - } - } - } - } - return val; -} - -// Merge the two lists of AffineExpr's into a single one, avoiding -// duplicates. lb specifies whether the bound lists are for a lower bound or an -// upper bound. -// TODO(bondhugula): clean this code up. -static void mergeBounds(const HyperRectangularSet &set, - AffineBoundExprList &lhsList, - const AffineBoundExprList &rhsList, bool lb) { - // The list of bounds is going to be small. Just a linear search - // should be enough to create a list without duplicates. - for (auto expr : rhsList) { - AffineBoundExprList::const_iterator it; - for (it = lhsList.begin(); it != lhsList.end(); it++) { - if (expr == *it) - break; - } - if (it == lhsList.end()) { - // There can only be one constant affine expr in this bound list. - if (auto cExpr = expr.dyn_cast()) { - unsigned idx; - if (lb) { - auto cb = getReducedConstBound( - set, &idx, - [](int64_t newVal, int64_t oldVal) { return newVal < oldVal; }); - if (!cb.hasValue()) { - lhsList.push_back(expr); - continue; - } - if (cExpr.getValue() < cb) - lhsList[idx] = expr; - // A constant value >= the existing bound constant. - continue; - } - // Upper bound case. - auto cb = - getReducedConstBound(set, &idx, [](int64_t newVal, int64_t oldVal) { - return newVal > oldVal; - }); - if (!cb.hasValue()) { - lhsList.push_back(expr); - continue; - } - if (cExpr.getValue() > cb) - lhsList[idx] = expr; - continue; - } - // Not a constant expression; push it. - // TODO(bondhugula): check if this was implied by an existing symbolic - // expression or by the context. - lhsList.push_back(expr); - } - } -} - -HyperRectangularSet::HyperRectangularSet(unsigned numDims, unsigned numSymbols, - ArrayRef> lbs, - ArrayRef> ubs, - MLIRContext *context, - IntegerSet symbolContext) - : context(symbolContext ? MutableIntegerSet(symbolContext, context) - : MutableIntegerSet(numDims, numSymbols, context)) { - unsigned d = 0; - for (auto boundList : lbs) { - AffineBoundExprList lb; - for (auto expr : boundList) { - assert(expr.isSymbolicOrConstant() && - "bound expression should be symbolic or constant"); - lb.push_back(expr); - } - mergeBounds(*this, lowerBounds[d++], lb, true); - } - - d = 0; - for (auto boundList : ubs) { - AffineBoundExprList ub; - for (auto expr : boundList) { - assert(expr.isSymbolicOrConstant() && - "bound expression should be symbolic or constant"); - ub.push_back(expr); - } - mergeBounds(*this, upperBounds[d++], ub, false); - } - - simplifyUnderContext(); -} - -void HyperRectangularSet::projectOut(unsigned idx, unsigned num) { - // Erase the bounds along the projected out dimensions. - lowerBounds.erase(lowerBounds.begin() + idx, lowerBounds.begin() + idx + num); - upperBounds.erase(upperBounds.begin() + idx, upperBounds.begin() + idx + num); - numDims -= num; -} - -void HyperRectangularSet::intersect(const HyperRectangularSet &rhs) { - assert(rhs.getNumSymbols() == getNumSymbols() && - rhs.getNumDims() == getNumDims() && "operand space does not match"); - - // Intersection is just a concatenation of distinct bounds. - for (unsigned i = 0, n = getNumDims(); i < n; i++) { - mergeBounds(*this, getLowerBound(i), rhs.getLowerBound(i), true); - mergeBounds(*this, getUpperBound(i), rhs.getUpperBound(i), false); - } -} - -void HyperRectangularSet::print(raw_ostream &os) const { - os << "Hyper rectangular set: " << numDims << "dimensions, " << numSymbols - << "symbols\n"; - os << "Lower bounds\n"; - unsigned d = 0; - for (auto &lb : lowerBounds) { - os << "Dim " << d++ << "\n"; - for (auto expr : lb) { - expr.print(os); - } - } - d = 0; - os << "Upper bounds\n"; - for (auto &lb : upperBounds) { - os << "Dim " << d++ << "\n"; - for (auto expr : lb) { - expr.print(os); - } - } -} - -void HyperRectangleList::projectOut(unsigned idx, unsigned num) { - for (auto &elt : hyperRectangles) { - elt.projectOut(idx, num); - } - // TODO: after a project out, some of the sets may be identical. Remove those. -} - -bool HyperRectangleList::empty() const { - for (auto &set : hyperRectangles) { - if (!set.empty()) - return false; - } - return true; -} - -bool HyperRectangularSet::empty() const { - assert(0 && "unimplemented"); - return false; -} - -void HyperRectangularSet::dump() const { print(llvm::errs()); }