/// Get the number of vars of the specified kind.
unsigned getNumVarKind(VarKind kind) const {
return space.getNumVarKind(kind);
- };
+ }
/// Return the index at which the specified kind of vars starts.
unsigned getVarKindOffset(VarKind kind) const {
return space.getVarKindOffset(kind);
- };
+ }
/// Return the index at Which the specified kind of vars ends.
unsigned getVarKindEnd(VarKind kind) const {
return space.getVarKindEnd(kind);
- };
+ }
/// Get the number of elements of the specified kind in the range
/// [varStart, varLimit).
unsigned getVarKindOverlap(VarKind kind, unsigned varStart,
unsigned varLimit) const {
return space.getVarKindOverlap(kind, varStart, varLimit);
- };
+ }
/// Return the VarKind of the var at the specified position.
- VarKind getVarKindAt(unsigned pos) const { return space.getVarKindAt(pos); };
+ VarKind getVarKindAt(unsigned pos) const { return space.getVarKindAt(pos); }
/// The struct CountsSnapshot stores the count of each VarKind, and also of
/// each constraint type. getCounts() returns a CountsSnapshot object
if (ub)
*ub = getInt64Vec(ubMPInt);
if (boundFloorDivisor)
- *boundFloorDivisor = int64_t(boundFloorDivisorMPInt);
+ *boundFloorDivisor = static_cast<int64_t>(boundFloorDivisorMPInt);
return llvm::transformOptional(result, int64FromMPInt);
}
DependenceResult checkMemrefAccessDependence(
const MemRefAccess &srcAccess, const MemRefAccess &dstAccess,
- unsigned loopDepth, FlatAffineValueConstraints *dependenceConstraints,
- SmallVector<DependenceComponent, 2> *dependenceComponents,
+ unsigned loopDepth,
+ FlatAffineValueConstraints *dependenceConstraints = nullptr,
+ SmallVector<DependenceComponent, 2> *dependenceComponents = nullptr,
bool allowRAR = false);
/// Utility function that returns true if the provided DependenceResult
class FlatAffineValueConstraints : public presburger::IntegerPolyhedron {
public:
/// Constructs a constraint system reserving memory for the specified number
- /// of constraints and variables.
+ /// of constraints and variables. `valArgs` are the optional SSA values
+ /// associated with each dimension/symbol. These must either be empty or match
+ /// the number of dimensions and symbols.
FlatAffineValueConstraints(unsigned numReservedInequalities,
unsigned numReservedEqualities,
unsigned numReservedCols, unsigned numDims,
unsigned numSymbols, unsigned numLocals,
- ArrayRef<std::optional<Value>> valArgs = {})
+ ArrayRef<std::optional<Value>> valArgs)
: IntegerPolyhedron(numReservedInequalities, numReservedEqualities,
numReservedCols,
presburger::PresburgerSpace::getSetSpace(
values.append(valArgs.begin(), valArgs.end());
}
- /// Constructs a constraint system with the specified number of
+ /// Constructs a constraint system reserving memory for the specified number
+ /// of constraints and variables. `valArgs` are the optional SSA values
+ /// associated with each dimension/symbol. These must either be empty or match
+ /// the number of dimensions and symbols.
+ FlatAffineValueConstraints(unsigned numReservedInequalities,
+ unsigned numReservedEqualities,
+ unsigned numReservedCols, unsigned numDims,
+ unsigned numSymbols, unsigned numLocals,
+ ArrayRef<Value> valArgs = {})
+ : IntegerPolyhedron(numReservedInequalities, numReservedEqualities,
+ numReservedCols,
+ presburger::PresburgerSpace::getSetSpace(
+ numDims, numSymbols, numLocals)) {
+ assert(numReservedCols >= getNumVars() + 1);
+ assert(valArgs.empty() || valArgs.size() == getNumDimAndSymbolVars());
+ values.reserve(numReservedCols);
+ if (valArgs.empty())
+ values.resize(getNumDimAndSymbolVars(), std::nullopt);
+ else
+ values.append(valArgs.begin(), valArgs.end());
+ }
+
+ /// Constructs a constraint system with the specified number of dimensions
+ /// and symbols. `valArgs` are the optional SSA values associated with each
+ /// dimension/symbol. These must either be empty or match the number of
+ /// dimensions and symbols.
+ FlatAffineValueConstraints(unsigned numDims, unsigned numSymbols,
+ unsigned numLocals,
+ ArrayRef<std::optional<Value>> valArgs)
+ : FlatAffineValueConstraints(/*numReservedInequalities=*/0,
+ /*numReservedEqualities=*/0,
+ /*numReservedCols=*/numDims + numSymbols +
+ numLocals + 1,
+ numDims, numSymbols, numLocals, valArgs) {}
+
+ /// Constructs a constraint system with the specified number of dimensions
+ /// and symbols. `valArgs` are the optional SSA values associated with each
+ /// dimension/symbol. These must either be empty or match the number of
/// dimensions and symbols.
FlatAffineValueConstraints(unsigned numDims = 0, unsigned numSymbols = 0,
unsigned numLocals = 0,
- ArrayRef<std::optional<Value>> valArgs = {})
+ ArrayRef<Value> valArgs = {})
: FlatAffineValueConstraints(/*numReservedInequalities=*/0,
/*numReservedEqualities=*/0,
/*numReservedCols=*/numDims + numSymbols +
values.append(valArgs.begin(), valArgs.end());
}
- /// Create a flat affine constraint system from an AffineValueMap or a list of
- /// these. The constructed system will only include equalities.
- explicit FlatAffineValueConstraints(const AffineValueMap &avm);
- explicit FlatAffineValueConstraints(ArrayRef<const AffineValueMap *> avmRef);
-
/// Creates an affine constraint system from an IntegerSet.
explicit FlatAffineValueConstraints(IntegerSet set, ValueRange operands = {});
return cst->getKind() == Kind::FlatAffineValueConstraints;
}
- /// Clears any existing data and reserves memory for the specified
- /// constraints.
- void reset(unsigned numReservedInequalities, unsigned numReservedEqualities,
- unsigned numReservedCols, unsigned numDims, unsigned numSymbols,
- unsigned numLocals = 0);
- void reset(unsigned numDims = 0, unsigned numSymbols = 0,
- unsigned numLocals = 0);
- void reset(unsigned numReservedInequalities, unsigned numReservedEqualities,
- unsigned numReservedCols, unsigned numDims, unsigned numSymbols,
- unsigned numLocals, ArrayRef<Value> valArgs);
- void reset(unsigned numDims, unsigned numSymbols, unsigned numLocals,
- ArrayRef<Value> valArgs);
-
/// Clones this object.
std::unique_ptr<FlatAffineValueConstraints> clone() const;
MemRefAccess srcAccess(srcOp);
for (auto *dstOp : loadAndStoreOps) {
MemRefAccess dstAccess(dstOp);
- FlatAffineValueConstraints dependenceConstraints;
- DependenceResult result = checkMemrefAccessDependence(
- srcAccess, dstAccess, depth, &dependenceConstraints,
- /*dependenceComponents=*/nullptr);
+ DependenceResult result =
+ checkMemrefAccessDependence(srcAccess, dstAccess, depth);
if (result.value != DependenceResult::NoDependence)
return false;
}
}
extractInductionVars(loopOps, indices);
// Reset while associating Values in 'indices' to the domain.
- domain->reset(numDims, /*numSymbols=*/0, /*numLocals=*/0, indices);
+ *domain = FlatAffineValueConstraints(numDims, /*numSymbols=*/0,
+ /*numLocals=*/0, indices);
for (Operation *op : ops) {
// Add constraints from forOp's bounds.
if (AffineForOp forOp = dyn_cast<AffineForOp>(op)) {
// memory locations.
dstRel.inverse();
dstRel.compose(srcRel);
- *dependenceConstraints = dstRel;
// Add 'src' happens before 'dst' ordering constraints.
- addOrderingConstraints(srcDomain, dstDomain, loopDepth,
- dependenceConstraints);
+ addOrderingConstraints(srcDomain, dstDomain, loopDepth, &dstRel);
// Return 'NoDependence' if the solution space is empty: no dependence.
- if (dependenceConstraints->isEmpty())
+ if (dstRel.isEmpty())
return DependenceResult::NoDependence;
// Compute dependence direction vector and return true.
if (dependenceComponents != nullptr)
- computeDirectionVector(srcDomain, dstDomain, loopDepth,
- dependenceConstraints, dependenceComponents);
+ computeDirectionVector(srcDomain, dstDomain, loopDepth, &dstRel,
+ dependenceComponents);
LLVM_DEBUG(llvm::dbgs() << "Dependence polyhedron:\n");
- LLVM_DEBUG(dependenceConstraints->dump());
+ LLVM_DEBUG(dstRel.dump());
+
+ if (dependenceConstraints)
+ *dependenceConstraints = dstRel;
return DependenceResult::HasDependence;
}
auto *dstOp = loadAndStoreOps[j];
MemRefAccess dstAccess(dstOp);
- FlatAffineValueConstraints dependenceConstraints;
SmallVector<DependenceComponent, 2> depComps;
// TODO: Explore whether it would be profitable to pre-compute and store
// deps instead of repeatedly checking.
DependenceResult result = checkMemrefAccessDependence(
- srcAccess, dstAccess, d, &dependenceConstraints, &depComps);
+ srcAccess, dstAccess, d, /*dependenceConstraints=*/nullptr,
+ &depComps);
if (hasDependence(result))
depCompsVec->push_back(depComps);
}
std::vector<SmallVector<int64_t, 8>> *flattenedExprs,
FlatAffineValueConstraints *localVarCst) {
if (exprs.empty()) {
- localVarCst->reset(numDims, numSymbols);
+ if (localVarCst)
+ *localVarCst = FlatAffineValueConstraints(numDims, numSymbols);
return success();
}
AffineMap map, std::vector<SmallVector<int64_t, 8>> *flattenedExprs,
FlatAffineValueConstraints *localVarCst) {
if (map.getNumResults() == 0) {
- localVarCst->reset(map.getNumDims(), map.getNumSymbols());
+ if (localVarCst)
+ *localVarCst =
+ FlatAffineValueConstraints(map.getNumDims(), map.getNumSymbols());
return success();
}
return ::getFlattenedAffineExprs(map.getResults(), map.getNumDims(),
IntegerSet set, std::vector<SmallVector<int64_t, 8>> *flattenedExprs,
FlatAffineValueConstraints *localVarCst) {
if (set.getNumConstraints() == 0) {
- localVarCst->reset(set.getNumDims(), set.getNumSymbols());
+ if (localVarCst)
+ *localVarCst =
+ FlatAffineValueConstraints(set.getNumDims(), set.getNumSymbols());
return success();
}
return ::getFlattenedAffineExprs(set.getConstraints(), set.getNumDims(),
return res;
}
-void FlatAffineValueConstraints::reset(unsigned numReservedInequalities,
- unsigned numReservedEqualities,
- unsigned newNumReservedCols,
- unsigned newNumDims,
- unsigned newNumSymbols,
- unsigned newNumLocals) {
- assert(newNumReservedCols >= newNumDims + newNumSymbols + newNumLocals + 1 &&
- "minimum 1 column");
- *this = FlatAffineValueConstraints(numReservedInequalities,
- numReservedEqualities, newNumReservedCols,
- newNumDims, newNumSymbols, newNumLocals);
-}
-
-void FlatAffineValueConstraints::reset(unsigned newNumDims,
- unsigned newNumSymbols,
- unsigned newNumLocals) {
- reset(/*numReservedInequalities=*/0, /*numReservedEqualities=*/0,
- /*numReservedCols=*/newNumDims + newNumSymbols + newNumLocals + 1,
- newNumDims, newNumSymbols, newNumLocals);
-}
-
-void FlatAffineValueConstraints::reset(
- unsigned numReservedInequalities, unsigned numReservedEqualities,
- unsigned newNumReservedCols, unsigned newNumDims, unsigned newNumSymbols,
- unsigned newNumLocals, ArrayRef<Value> valArgs) {
- assert(newNumReservedCols >= newNumDims + newNumSymbols + newNumLocals + 1 &&
- "minimum 1 column");
- SmallVector<std::optional<Value>, 8> newVals;
- if (!valArgs.empty())
- newVals.assign(valArgs.begin(), valArgs.end());
-
- *this = FlatAffineValueConstraints(
- numReservedInequalities, numReservedEqualities, newNumReservedCols,
- newNumDims, newNumSymbols, newNumLocals, newVals);
-}
-
-void FlatAffineValueConstraints::reset(unsigned newNumDims,
- unsigned newNumSymbols,
- unsigned newNumLocals,
- ArrayRef<Value> valArgs) {
- reset(0, 0, newNumDims + newNumSymbols + newNumLocals + 1, newNumDims,
- newNumSymbols, newNumLocals, valArgs);
-}
-
unsigned FlatAffineValueConstraints::appendDimVar(ValueRange vals) {
unsigned pos = getNumDimVars();
return insertVar(VarKind::SetDim, pos, vals);
LogicalResult
ComputationSliceState::getSourceAsConstraints(FlatAffineValueConstraints &cst) {
assert(!ivs.empty() && "Cannot have a slice without its IVs");
- cst.reset(/*numDims=*/ivs.size(), /*numSymbols=*/0, /*numLocals=*/0, ivs);
+ cst = FlatAffineValueConstraints(/*numDims=*/ivs.size(), /*numSymbols=*/0,
+ /*numLocals=*/0, ivs);
for (Value iv : ivs) {
AffineForOp loop = getForInductionVarOwner(iv);
assert(loop && "Expected affine for");
SmallVector<Value, 4> values(ivs);
// Append 'ivs' then 'operands' to 'values'.
values.append(lbOperands[0].begin(), lbOperands[0].end());
- cst->reset(numDims, numSymbols, 0, values);
+ *cst = FlatAffineValueConstraints(numDims, numSymbols, 0, values);
// Add loop bound constraints for values which are loop IVs of the destination
// of fusion and equality constraints for symbols which are constants.
return isMaximalFastCheck;
// Create constraints for the src loop nest being sliced.
- FlatAffineValueConstraints srcConstraints;
- srcConstraints.reset(/*numDims=*/ivs.size(), /*numSymbols=*/0,
- /*numLocals=*/0, ivs);
+ FlatAffineValueConstraints srcConstraints(/*numDims=*/ivs.size(),
+ /*numSymbols=*/0,
+ /*numLocals=*/0, ivs);
for (Value iv : ivs) {
AffineForOp loop = getForInductionVarOwner(iv);
assert(loop && "Expected affine for");
// Create constraints for the slice using the dst loop nest information. We
// retrieve existing dst loops from the lbOperands.
- SmallVector<Value, 8> consumerIVs;
+ SmallVector<Value> consumerIVs;
for (Value lbOp : lbOperands[0])
if (getForInductionVarOwner(lbOp))
consumerIVs.push_back(lbOp);
for (int i = consumerIVs.size(), end = ivs.size(); i < end; ++i)
consumerIVs.push_back(Value());
- FlatAffineValueConstraints sliceConstraints;
- sliceConstraints.reset(/*numDims=*/consumerIVs.size(), /*numSymbols=*/0,
- /*numLocals=*/0, consumerIVs);
+ FlatAffineValueConstraints sliceConstraints(/*numDims=*/consumerIVs.size(),
+ /*numSymbols=*/0,
+ /*numLocals=*/0, consumerIVs);
if (failed(sliceConstraints.addDomainFromSliceMaps(lbs, ubs, lbOperands[0])))
return std::nullopt;
// The first 'loopDepth' IVs are symbols for this region.
ivs.resize(loopDepth);
// A 0-d memref has a 0-d region.
- cst.reset(rank, loopDepth, /*numLocals=*/0, ivs);
+ cst = FlatAffineValueConstraints(rank, loopDepth, /*numLocals=*/0, ivs);
return success();
}
// We'll first associate the dims and symbols of the access map to the dims
// and symbols resp. of cst. This will change below once cst is
// fully constructed out.
- cst.reset(numDims, numSymbols, 0, operands);
+ cst = FlatAffineValueConstraints(numDims, numSymbols, 0, operands);
// Add equality constraints.
// Add inequalities for loop lower/upper bounds.
unsigned numCommonLoops =
getNumCommonSurroundingLoops(*srcOpInst, *dstOpInst);
for (unsigned d = 1; d <= numCommonLoops + 1; ++d) {
- FlatAffineValueConstraints dependenceConstraints;
// TODO: Cache dependence analysis results, check cache here.
- DependenceResult result = checkMemrefAccessDependence(
- srcAccess, dstAccess, d, &dependenceConstraints,
- /*dependenceComponents=*/nullptr);
+ DependenceResult result =
+ checkMemrefAccessDependence(srcAccess, dstAccess, d);
if (hasDependence(result)) {
// Store minimum loop depth and break because we want the min 'd' at
// which there is a dependence.
unsigned numOps = loadAndStoreOps.size();
unsigned numLoops = origLoops.size();
- FlatAffineValueConstraints dependenceConstraints;
for (unsigned d = 1; d <= numLoops + 1; ++d) {
for (unsigned i = 0; i < numOps; ++i) {
Operation *srcOp = loadAndStoreOps[i];
MemRefAccess dstAccess(dstOp);
SmallVector<DependenceComponent, 2> depComps;
- dependenceConstraints.reset();
DependenceResult result = checkMemrefAccessDependence(
- srcAccess, dstAccess, d, &dependenceConstraints, &depComps);
+ srcAccess, dstAccess, d, /*dependenceConstraints=*/nullptr,
+ &depComps);
// Skip if there is no dependence in this case.
if (!hasDependence(result))
ivs.resize(numParamLoopIVs);
SmallVector<Value, 4> symbols;
extractForInductionVars(ivs, &symbols);
- regionCst->reset(rank, numParamLoopIVs, 0);
+ *regionCst = FlatAffineValueConstraints(rank, numParamLoopIVs, 0);
regionCst->setValues(rank, rank + numParamLoopIVs, symbols);
// Memref dim sizes provide the bounds.
unsigned nsLoops =
getNumCommonSurroundingLoops(*srcAccess.opInst, *destAccess.opInst);
- FlatAffineValueConstraints dependenceConstraints;
- DependenceResult result = checkMemrefAccessDependence(
- srcAccess, destAccess, nsLoops + 1, &dependenceConstraints,
- /*dependenceComponents=*/nullptr);
+ DependenceResult result =
+ checkMemrefAccessDependence(srcAccess, destAccess, nsLoops + 1);
return hasDependence(result);
}
unsigned numCommonLoops =
getNumCommonSurroundingLoops(*srcOpInst, *dstOpInst);
for (unsigned d = 1; d <= numCommonLoops + 1; ++d) {
- FlatAffineValueConstraints dependenceConstraints;
SmallVector<DependenceComponent, 2> dependenceComponents;
DependenceResult result = checkMemrefAccessDependence(
- srcAccess, dstAccess, d, &dependenceConstraints,
+ srcAccess, dstAccess, d, /*dependenceConstraints=*/nullptr,
&dependenceComponents);
if (result.value == DependenceResult::Failure) {
srcOpInst->emitError("dependence check failed");