CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
123 lines
4.6 KiB
C++
123 lines
4.6 KiB
C++
//===- ConstantPropagationAnalysis.cpp - Constant propagation analysis ----===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "mlir/Analysis/DataFlow/ConstantPropagationAnalysis.h"
|
|
#include "mlir/Analysis/DataFlow/SparseAnalysis.h"
|
|
#include "mlir/IR/BuiltinAttributes.h"
|
|
#include "mlir/IR/OpDefinition.h"
|
|
#include "mlir/IR/Operation.h"
|
|
#include "mlir/IR/Value.h"
|
|
#include "mlir/Support/LLVM.h"
|
|
#include "llvm/ADT/STLExtras.h"
|
|
#include "llvm/Support/Casting.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "llvm/Support/DebugLog.h"
|
|
#include <cassert>
|
|
|
|
#define DEBUG_TYPE "constant-propagation"
|
|
|
|
using namespace mlir;
|
|
using namespace mlir::dataflow;
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// ConstantValue
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ConstantValue::print(raw_ostream &os) const {
|
|
if (isUninitialized()) {
|
|
os << "<UNINITIALIZED>";
|
|
return;
|
|
}
|
|
if (getConstantValue() == nullptr) {
|
|
os << "<UNKNOWN>";
|
|
return;
|
|
}
|
|
return getConstantValue().print(os);
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// SparseConstantPropagation
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
LogicalResult SparseConstantPropagation::visitOperation(
|
|
Operation *op, ArrayRef<const Lattice<ConstantValue> *> operands,
|
|
ArrayRef<Lattice<ConstantValue> *> results) {
|
|
LDBG() << "SCP: Visiting operation: " << *op;
|
|
|
|
// Don't try to simulate the results of a region operation as we can't
|
|
// guarantee that folding will be out-of-place. We don't allow in-place
|
|
// folds as the desire here is for simulated execution, and not general
|
|
// folding.
|
|
if (op->getNumRegions()) {
|
|
setAllToEntryStates(results);
|
|
return success();
|
|
}
|
|
|
|
SmallVector<Attribute, 8> constantOperands;
|
|
constantOperands.reserve(op->getNumOperands());
|
|
for (auto *operandLattice : operands) {
|
|
if (operandLattice->getValue().isUninitialized())
|
|
return success();
|
|
constantOperands.push_back(operandLattice->getValue().getConstantValue());
|
|
}
|
|
|
|
// Save the original operands and attributes just in case the operation
|
|
// folds in-place. The constant passed in may not correspond to the real
|
|
// runtime value, so in-place updates are not allowed.
|
|
SmallVector<Value, 8> originalOperands(op->getOperands());
|
|
DictionaryAttr originalAttrs = op->getAttrDictionary();
|
|
|
|
// Simulate the result of folding this operation to a constant. If folding
|
|
// fails or was an in-place fold, mark the results as overdefined.
|
|
SmallVector<OpFoldResult, 8> foldResults;
|
|
foldResults.reserve(op->getNumResults());
|
|
if (failed(op->fold(constantOperands, foldResults))) {
|
|
setAllToEntryStates(results);
|
|
return success();
|
|
}
|
|
|
|
// If the folding was in-place, mark the results as overdefined and reset
|
|
// the operation. We don't allow in-place folds as the desire here is for
|
|
// simulated execution, and not general folding.
|
|
if (foldResults.empty()) {
|
|
op->setOperands(originalOperands);
|
|
op->setAttrs(originalAttrs);
|
|
setAllToEntryStates(results);
|
|
return success();
|
|
}
|
|
|
|
// Merge the fold results into the lattice for this operation.
|
|
assert(foldResults.size() == op->getNumResults() && "invalid result size");
|
|
for (const auto it : llvm::zip(results, foldResults)) {
|
|
Lattice<ConstantValue> *lattice = std::get<0>(it);
|
|
|
|
// Merge in the result of the fold, either a constant or a value.
|
|
OpFoldResult foldResult = std::get<1>(it);
|
|
if (Attribute attr = llvm::dyn_cast_if_present<Attribute>(foldResult)) {
|
|
LDBG() << "Folded to constant: " << attr;
|
|
propagateIfChanged(lattice,
|
|
lattice->join(ConstantValue(attr, op->getDialect())));
|
|
} else {
|
|
Value foldValue = cast<Value>(foldResult);
|
|
LDBG() << "Folded to value: " << foldValue;
|
|
// The folded value may not be an operand of `op`, so we need to use
|
|
// `getLatticeElementFor` (and not `getLatticeElement`) so that
|
|
// this operation is revisited if that value's lattice widens later.
|
|
AbstractSparseForwardDataFlowAnalysis::join(
|
|
lattice, *getLatticeElementFor(getProgramPointAfter(op), foldValue));
|
|
}
|
|
}
|
|
return success();
|
|
}
|
|
|
|
void SparseConstantPropagation::setToEntryState(
|
|
Lattice<ConstantValue> *lattice) {
|
|
propagateIfChanged(lattice,
|
|
lattice->join(ConstantValue::getUnknownConstant()));
|
|
}
|