#include "mlir/Analysis/DataFlow/ConstantPropagationAnalysis.h"
#include "mlir/IR/OpDefinition.h"
#include "llvm/Support/Debug.h"
#define DEBUG_TYPE "constant-propagation"
using namespace mlir;
using namespace mlir::dataflow;
void ConstantValue::print(raw_ostream &os) const {
if (constant)
return constant.print(os);
os << "<NO VALUE>";
}
void SparseConstantPropagation::visitOperation(
Operation *op, ArrayRef<const Lattice<ConstantValue> *> operands,
ArrayRef<Lattice<ConstantValue> *> results) {
LLVM_DEBUG(llvm::dbgs() << "SCP: Visiting operation: " << *op << "\n");
if (op->getNumRegions())
return;
SmallVector<Attribute, 8> constantOperands;
constantOperands.reserve(op->getNumOperands());
for (auto *operandLattice : operands)
constantOperands.push_back(operandLattice->getValue().getConstantValue());
SmallVector<Value, 8> originalOperands(op->getOperands());
DictionaryAttr originalAttrs = op->getAttrDictionary();
SmallVector<OpFoldResult, 8> foldResults;
foldResults.reserve(op->getNumResults());
if (failed(op->fold(constantOperands, foldResults))) {
markAllPessimisticFixpoint(results);
return;
}
if (foldResults.empty()) {
op->setOperands(originalOperands);
op->setAttrs(originalAttrs);
markAllPessimisticFixpoint(results);
return;
}
assert(foldResults.size() == op->getNumResults() && "invalid result size");
for (const auto it : llvm::zip(results, foldResults)) {
Lattice<ConstantValue> *lattice = std::get<0>(it);
OpFoldResult foldResult = std::get<1>(it);
if (Attribute attr = foldResult.dyn_cast<Attribute>()) {
LLVM_DEBUG(llvm::dbgs() << "Folded to constant: " << attr << "\n");
propagateIfChanged(lattice,
lattice->join(ConstantValue(attr, op->getDialect())));
} else {
LLVM_DEBUG(llvm::dbgs()
<< "Folded to value: " << foldResult.get<Value>() << "\n");
AbstractSparseDataFlowAnalysis::join(
lattice, *getLatticeElement(foldResult.get<Value>()));
}
}
}