brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.3 KiB · fb5649e Raw
119 lines · cpp
1//===- ConstantPropagationAnalysis.cpp - Constant propagation analysis ----===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "mlir/Analysis/DataFlow/ConstantPropagationAnalysis.h"10#include "mlir/Analysis/DataFlow/SparseAnalysis.h"11#include "mlir/IR/BuiltinAttributes.h"12#include "mlir/IR/OpDefinition.h"13#include "mlir/IR/Operation.h"14#include "mlir/IR/Value.h"15#include "mlir/Support/LLVM.h"16#include "llvm/ADT/STLExtras.h"17#include "llvm/Support/Casting.h"18#include "llvm/Support/Debug.h"19#include "llvm/Support/DebugLog.h"20#include <cassert>21 22#define DEBUG_TYPE "constant-propagation"23 24using namespace mlir;25using namespace mlir::dataflow;26 27//===----------------------------------------------------------------------===//28// ConstantValue29//===----------------------------------------------------------------------===//30 31void ConstantValue::print(raw_ostream &os) const {32  if (isUninitialized()) {33    os << "<UNINITIALIZED>";34    return;35  }36  if (getConstantValue() == nullptr) {37    os << "<UNKNOWN>";38    return;39  }40  return getConstantValue().print(os);41}42 43//===----------------------------------------------------------------------===//44// SparseConstantPropagation45//===----------------------------------------------------------------------===//46 47LogicalResult SparseConstantPropagation::visitOperation(48    Operation *op, ArrayRef<const Lattice<ConstantValue> *> operands,49    ArrayRef<Lattice<ConstantValue> *> results) {50  LDBG() << "SCP: Visiting operation: " << *op;51 52  // Don't try to simulate the results of a region operation as we can't53  // guarantee that folding will be out-of-place. We don't allow in-place54  // folds as the desire here is for simulated execution, and not general55  // folding.56  if (op->getNumRegions()) {57    setAllToEntryStates(results);58    return success();59  }60 61  SmallVector<Attribute, 8> constantOperands;62  constantOperands.reserve(op->getNumOperands());63  for (auto *operandLattice : operands) {64    if (operandLattice->getValue().isUninitialized())65      return success();66    constantOperands.push_back(operandLattice->getValue().getConstantValue());67  }68 69  // Save the original operands and attributes just in case the operation70  // folds in-place. The constant passed in may not correspond to the real71  // runtime value, so in-place updates are not allowed.72  SmallVector<Value, 8> originalOperands(op->getOperands());73  DictionaryAttr originalAttrs = op->getAttrDictionary();74 75  // Simulate the result of folding this operation to a constant. If folding76  // fails or was an in-place fold, mark the results as overdefined.77  SmallVector<OpFoldResult, 8> foldResults;78  foldResults.reserve(op->getNumResults());79  if (failed(op->fold(constantOperands, foldResults))) {80    setAllToEntryStates(results);81    return success();82  }83 84  // If the folding was in-place, mark the results as overdefined and reset85  // the operation. We don't allow in-place folds as the desire here is for86  // simulated execution, and not general folding.87  if (foldResults.empty()) {88    op->setOperands(originalOperands);89    op->setAttrs(originalAttrs);90    setAllToEntryStates(results);91    return success();92  }93 94  // Merge the fold results into the lattice for this operation.95  assert(foldResults.size() == op->getNumResults() && "invalid result size");96  for (const auto it : llvm::zip(results, foldResults)) {97    Lattice<ConstantValue> *lattice = std::get<0>(it);98 99    // Merge in the result of the fold, either a constant or a value.100    OpFoldResult foldResult = std::get<1>(it);101    if (Attribute attr = llvm::dyn_cast_if_present<Attribute>(foldResult)) {102      LDBG() << "Folded to constant: " << attr;103      propagateIfChanged(lattice,104                         lattice->join(ConstantValue(attr, op->getDialect())));105    } else {106      LDBG() << "Folded to value: " << cast<Value>(foldResult);107      AbstractSparseForwardDataFlowAnalysis::join(108          lattice, *getLatticeElement(cast<Value>(foldResult)));109    }110  }111  return success();112}113 114void SparseConstantPropagation::setToEntryState(115    Lattice<ConstantValue> *lattice) {116  propagateIfChanged(lattice,117                     lattice->join(ConstantValue::getUnknownConstant()));118}119