From 69bc334be56997aff21a55149c987a5c20741f93 Mon Sep 17 00:00:00 2001 From: Eugene Zhulenev Date: Fri, 14 Jan 2022 11:08:23 -0800 Subject: [PATCH] [mlir] Remove getNumberOfExecutions from RegionBranchOpInterface `getNumRegionInvocations` was originally added for the async reference counting, but turned out to be not useful, and currently is not used anywhere (couldn't find any uses in public github repos). Removing dead code. Reviewed By: Mogball, mehdi_amini Differential Revision: https://reviews.llvm.org/D117347 --- .../mlir/Analysis/NumberOfExecutions.h | 107 -------- .../include/mlir/Dialect/Async/IR/AsyncOps.td | 3 +- mlir/include/mlir/Dialect/SCF/SCFOps.td | 11 - .../mlir/Interfaces/ControlFlowInterfaces.h | 3 - .../mlir/Interfaces/ControlFlowInterfaces.td | 20 -- mlir/lib/Analysis/CMakeLists.txt | 2 - mlir/lib/Analysis/NumberOfExecutions.cpp | 242 ------------------ mlir/lib/Dialect/Async/IR/Async.cpp | 6 - mlir/lib/Dialect/SCF/SCF.cpp | 37 --- mlir/lib/Interfaces/ControlFlowInterfaces.cpp | 3 - .../test-number-of-block-executions.mlir | 192 -------------- .../test-number-of-operation-executions.mlir | 66 ----- mlir/test/lib/Analysis/CMakeLists.txt | 1 - .../lib/Analysis/TestNumberOfExecutions.cpp | 67 ----- mlir/tools/mlir-opt/mlir-opt.cpp | 4 - mlir/unittests/Dialect/CMakeLists.txt | 1 - mlir/unittests/Dialect/SCF/CMakeLists.txt | 10 - mlir/unittests/Dialect/SCF/SCFOps.cpp | 67 ----- 18 files changed, 1 insertion(+), 841 deletions(-) delete mode 100644 mlir/include/mlir/Analysis/NumberOfExecutions.h delete mode 100644 mlir/lib/Analysis/NumberOfExecutions.cpp delete mode 100644 mlir/test/Analysis/test-number-of-block-executions.mlir delete mode 100644 mlir/test/Analysis/test-number-of-operation-executions.mlir delete mode 100644 mlir/test/lib/Analysis/TestNumberOfExecutions.cpp delete mode 100644 mlir/unittests/Dialect/SCF/CMakeLists.txt delete mode 100644 mlir/unittests/Dialect/SCF/SCFOps.cpp diff --git a/mlir/include/mlir/Analysis/NumberOfExecutions.h b/mlir/include/mlir/Analysis/NumberOfExecutions.h deleted file mode 100644 index 538d3900ac9f..000000000000 --- a/mlir/include/mlir/Analysis/NumberOfExecutions.h +++ /dev/null @@ -1,107 +0,0 @@ -//===- NumberOfExecutions.h - Number of executions analysis -----*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// -// -// This file contains an analysis for computing how many times a block within a -// region is executed *each time* that region is entered. The analysis -// iterates over all associated regions that are attached to the given top-level -// operation. -// -// It is possible to query number of executions information on block level. -// -//===----------------------------------------------------------------------===// - -#ifndef MLIR_ANALYSIS_NUMBEROFEXECUTIONS_H -#define MLIR_ANALYSIS_NUMBEROFEXECUTIONS_H - -#include "mlir/Support/LLVM.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/Optional.h" - -namespace mlir { - -class Block; -class BlockNumberOfExecutionsInfo; -class Operation; -class Region; - -/// Represents an analysis for computing how many times a block or an operation -/// within a region is executed *each time* that region is entered. The analysis -/// iterates over all associated regions that are attached to the given -/// top-level operation. -/// -/// This analysis assumes that all operations complete in a finite amount of -/// time (do not abort and do not go into the infinite loop). -class NumberOfExecutions { -public: - /// Creates a new NumberOfExecutions analysis that computes how many times a - /// block within a region is executed for all associated regions. - explicit NumberOfExecutions(Operation *op); - - /// Returns the number of times operations `op` is executed *each time* the - /// control flow enters the region `perEntryOfThisRegion`. Returns empty - /// optional if this is not known statically. - Optional getNumberOfExecutions(Operation *op, - Region *perEntryOfThisRegion) const; - - /// Returns the number of times block `block` is executed *each time* the - /// control flow enters the region `perEntryOfThisRegion`. Returns empty - /// optional if this is not known statically. - Optional getNumberOfExecutions(Block *block, - Region *perEntryOfThisRegion) const; - - /// Dumps the number of block executions *each time* the control flow enters - /// the region `perEntryOfThisRegion` to the given stream. - void printBlockExecutions(raw_ostream &os, - Region *perEntryOfThisRegion) const; - - /// Dumps the number of operation executions *each time* the control flow - /// enters the region `perEntryOfThisRegion` to the given stream. - void printOperationExecutions(raw_ostream &os, - Region *perEntryOfThisRegion) const; - -private: - /// The operation this analysis was constructed from. - Operation *operation; - - /// A mapping from blocks to number of executions information. - DenseMap blockNumbersOfExecution; -}; - -/// Represents number of block executions information. -class BlockNumberOfExecutionsInfo { -public: - BlockNumberOfExecutionsInfo(Block *block, - Optional numberOfRegionInvocations, - Optional numberOfBlockExecutions); - - /// Returns the number of times this block will be executed *each time* the - /// parent operation is executed. - Optional getNumberOfExecutions() const; - - /// Returns the number of times this block will be executed if the parent - /// region is invoked `numberOfRegionInvocations` times. This can be different - /// from the number of region invocations by the parent operation. - Optional - getNumberOfExecutions(int64_t numberOfRegionInvocations) const; - - Block *getBlock() const { return block; } - -private: - Block *block; - - /// Number of `block` parent region invocations *each time* parent operation - /// is executed. - Optional numberOfRegionInvocations; - - /// Number of `block` executions *each time* parent region is invoked. - Optional numberOfBlockExecutions; -}; - -} // namespace mlir - -#endif // MLIR_ANALYSIS_NUMBEROFEXECUTIONS_H diff --git a/mlir/include/mlir/Dialect/Async/IR/AsyncOps.td b/mlir/include/mlir/Dialect/Async/IR/AsyncOps.td index a7fc743864d0..8f132043f3bb 100644 --- a/mlir/include/mlir/Dialect/Async/IR/AsyncOps.td +++ b/mlir/include/mlir/Dialect/Async/IR/AsyncOps.td @@ -29,8 +29,7 @@ class Async_Op traits = []> : def Async_ExecuteOp : Async_Op<"execute", [SingleBlockImplicitTerminator<"YieldOp">, DeclareOpInterfaceMethods, + ["getSuccessorEntryOperands"]>, AttrSizedOperandSegments]> { let summary = "Asynchronous execute operation"; let description = [{ diff --git a/mlir/include/mlir/Dialect/SCF/SCFOps.td b/mlir/include/mlir/Dialect/SCF/SCFOps.td index e060dac6ce21..74834c03cae1 100644 --- a/mlir/include/mlir/Dialect/SCF/SCFOps.td +++ b/mlir/include/mlir/Dialect/SCF/SCFOps.td @@ -309,11 +309,6 @@ def ForOp : SCF_Op<"for", /// induction variable. LoopOp only has one region, so 0 is the only valid /// value for `index`. OperandRange getSuccessorEntryOperands(unsigned index); - - /// Returns the number of invocations of the body block if the loop bounds - /// are constants. Returns `kUnknownNumRegionInvocations` otherwise. - void getNumRegionInvocations(ArrayRef operands, - SmallVectorImpl &countPerRegion); }]; let hasCanonicalizer = 1; @@ -404,12 +399,6 @@ def IfOp : SCF_Op<"if", YieldOp thenYield(); Block* elseBlock(); YieldOp elseYield(); - - /// If the condition is a constant, returns 1 for the executed block and 0 - /// for the other. Otherwise, returns `kUnknownNumRegionInvocations` for - /// both successors. - void getNumRegionInvocations(ArrayRef operands, - SmallVectorImpl &countPerRegion); }]; let hasFolder = 1; let hasCanonicalizer = 1; diff --git a/mlir/include/mlir/Interfaces/ControlFlowInterfaces.h b/mlir/include/mlir/Interfaces/ControlFlowInterfaces.h index dbbe1a30ac5a..8ff76edb3068 100644 --- a/mlir/include/mlir/Interfaces/ControlFlowInterfaces.h +++ b/mlir/include/mlir/Interfaces/ControlFlowInterfaces.h @@ -41,9 +41,6 @@ LogicalResult verifyBranchSuccessorOperands(Operation *op, unsigned succNo, // RegionBranchOpInterface //===----------------------------------------------------------------------===// -// A constant value to represent unknown number of region invocations. -extern const int64_t kUnknownNumRegionInvocations; - namespace detail { /// Verify that types match along control flow edges described the given op. LogicalResult verifyTypesAlongControlFlowEdges(Operation *op); diff --git a/mlir/include/mlir/Interfaces/ControlFlowInterfaces.td b/mlir/include/mlir/Interfaces/ControlFlowInterfaces.td index bb635e77c4a1..0633426cf50a 100644 --- a/mlir/include/mlir/Interfaces/ControlFlowInterfaces.td +++ b/mlir/include/mlir/Interfaces/ControlFlowInterfaces.td @@ -129,26 +129,6 @@ def RegionBranchOpInterface : OpInterface<"RegionBranchOpInterface"> { "void", "getSuccessorRegions", (ins "::mlir::Optional":$index, "::mlir::ArrayRef<::mlir::Attribute>":$operands, "::mlir::SmallVectorImpl<::mlir::RegionSuccessor> &":$regions) - >, - InterfaceMethod<[{ - Populates countPerRegion with the number of times this operation will - invoke the attached regions (assuming the regions yield normally, i.e. - do not abort or invoke an infinite loop). If the number of region - invocations is not known statically it will set the number of - invocations to `kUnknownNumRegionInvocations`. - - `operands` is a set of optional attributes that either correspond to a - constant values for each operand of this operation, or null if that - operand is not a constant. - }], - "void", "getNumRegionInvocations", - (ins "::mlir::ArrayRef<::mlir::Attribute>":$operands, - "::mlir::SmallVectorImpl &":$countPerRegion), [{}], - /*defaultImplementation=*/[{ - unsigned numRegions = this->getOperation()->getNumRegions(); - assert(countPerRegion.empty()); - countPerRegion.resize(numRegions, kUnknownNumRegionInvocations); - }] > ]; diff --git a/mlir/lib/Analysis/CMakeLists.txt b/mlir/lib/Analysis/CMakeLists.txt index 9022ce831ba0..7c9a71237adf 100644 --- a/mlir/lib/Analysis/CMakeLists.txt +++ b/mlir/lib/Analysis/CMakeLists.txt @@ -9,7 +9,6 @@ set(LLVM_OPTIONAL_SOURCES Liveness.cpp LoopAnalysis.cpp NestedMatcher.cpp - NumberOfExecutions.cpp SliceAnalysis.cpp Utils.cpp @@ -23,7 +22,6 @@ add_mlir_library(MLIRAnalysis DataFlowAnalysis.cpp DataLayoutAnalysis.cpp Liveness.cpp - NumberOfExecutions.cpp SliceAnalysis.cpp AliasAnalysis/LocalAliasAnalysis.cpp diff --git a/mlir/lib/Analysis/NumberOfExecutions.cpp b/mlir/lib/Analysis/NumberOfExecutions.cpp deleted file mode 100644 index ad90cee92ee8..000000000000 --- a/mlir/lib/Analysis/NumberOfExecutions.cpp +++ /dev/null @@ -1,242 +0,0 @@ -//===- NumberOfExecutions.cpp - Number of executions 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 -// -//===----------------------------------------------------------------------===// -// -// Implementation of the number of executions analysis. -// -//===----------------------------------------------------------------------===// - -#include "mlir/Analysis/NumberOfExecutions.h" -#include "mlir/IR/Matchers.h" -#include "mlir/IR/RegionKindInterface.h" -#include "mlir/Interfaces/ControlFlowInterfaces.h" - -#include "llvm/ADT/FunctionExtras.h" -#include "llvm/ADT/SmallSet.h" -#include "llvm/Support/raw_ostream.h" - -#define DEBUG_TYPE "number-of-executions-analysis" - -using namespace mlir; - -//===----------------------------------------------------------------------===// -// NumberOfExecutions -//===----------------------------------------------------------------------===// - -/// Computes blocks number of executions information for the given region. -static void computeRegionBlockNumberOfExecutions( - Region ®ion, DenseMap &blockInfo) { - Operation *parentOp = region.getParentOp(); - int regionId = region.getRegionNumber(); - - auto regionKindInterface = dyn_cast(parentOp); - bool isGraphRegion = - regionKindInterface && - regionKindInterface.getRegionKind(regionId) == RegionKind::Graph; - - // CFG analysis does not make sense for Graph regions, set the number of - // executions for all blocks as unknown. - if (isGraphRegion) { - for (Block &block : region) - blockInfo.insert({&block, {&block, None, None}}); - return; - } - - // Number of region invocations for all attached regions. - SmallVector numRegionsInvocations; - - // Query RegionBranchOpInterface interface if it is available. - if (auto regionInterface = dyn_cast(parentOp)) { - SmallVector operands(parentOp->getNumOperands()); - for (const auto &operandIt : llvm::enumerate(parentOp->getOperands())) - matchPattern(operandIt.value(), m_Constant(&operands[operandIt.index()])); - - regionInterface.getNumRegionInvocations(operands, numRegionsInvocations); - } - - // Number of region invocations *each time* parent operation is invoked. - Optional numRegionInvocations; - - if (!numRegionsInvocations.empty() && - numRegionsInvocations[regionId] != kUnknownNumRegionInvocations) { - numRegionInvocations = numRegionsInvocations[regionId]; - } - - // DFS traversal looking for loops in the CFG. - llvm::SmallSet loopStart; - - llvm::unique_function &)> dfs = - [&](Block *block, llvm::SmallSet &visited) { - // Found a loop in the CFG that starts at the `block`. - if (visited.contains(block)) { - loopStart.insert(block); - return; - } - - // Continue DFS traversal. - visited.insert(block); - for (Block *successor : block->getSuccessors()) - dfs(successor, visited); - visited.erase(block); - }; - - llvm::SmallSet visited; - dfs(®ion.front(), visited); - - // Start from the entry block and follow only blocks with single succesor. - Block *block = ®ion.front(); - while (block && !loopStart.contains(block)) { - // Block will be executed exactly once. - blockInfo.insert( - {block, BlockNumberOfExecutionsInfo(block, numRegionInvocations, - /*numberOfBlockExecutions=*/1)}); - - // We reached the exit block or block with multiple successors. - if (block->getNumSuccessors() != 1) - break; - - // Continue traversal. - block = block->getSuccessor(0); - } - - // For all blocks that we did not visit set the executions number to unknown. - for (Block &block : region) - if (blockInfo.count(&block) == 0) - blockInfo.insert({&block, BlockNumberOfExecutionsInfo( - &block, numRegionInvocations, - /*numberOfBlockExecutions=*/None)}); -} - -/// Creates a new NumberOfExecutions analysis that computes how many times a -/// block within a region is executed for all associated regions. -NumberOfExecutions::NumberOfExecutions(Operation *op) : operation(op) { - operation->walk([&](Region *region) { - computeRegionBlockNumberOfExecutions(*region, blockNumbersOfExecution); - }); -} - -Optional -NumberOfExecutions::getNumberOfExecutions(Operation *op, - Region *perEntryOfThisRegion) const { - // Assuming that all operations complete in a finite amount of time (do not - // abort and do not go into the infinite loop), the number of operation - // executions is equal to the number of block executions that contains the - // operation. - return getNumberOfExecutions(op->getBlock(), perEntryOfThisRegion); -} - -Optional -NumberOfExecutions::getNumberOfExecutions(Block *block, - Region *perEntryOfThisRegion) const { - // Return None if the given `block` does not lie inside the - // `perEntryOfThisRegion` region. - if (!perEntryOfThisRegion->findAncestorBlockInRegion(*block)) - return None; - - // Find the block information for the given `block. - auto blockIt = blockNumbersOfExecution.find(block); - if (blockIt == blockNumbersOfExecution.end()) - return None; - const auto &blockInfo = blockIt->getSecond(); - - // Override the number of region invocations with `1` if the - // `perEntryOfThisRegion` region owns the block. - auto getNumberOfExecutions = [&](const BlockNumberOfExecutionsInfo &info) { - if (info.getBlock()->getParent() == perEntryOfThisRegion) - return info.getNumberOfExecutions(/*numberOfRegionInvocations=*/1); - return info.getNumberOfExecutions(); - }; - - // Immediately return None if we do not know the block number of executions. - auto blockExecutions = getNumberOfExecutions(blockInfo); - if (!blockExecutions.hasValue()) - return None; - - // Follow parent operations until we reach the operations that owns the - // `perEntryOfThisRegion`. - int64_t numberOfExecutions = *blockExecutions; - Operation *parentOp = block->getParentOp(); - - while (parentOp != perEntryOfThisRegion->getParentOp()) { - // Find how many times will be executed the block that owns the parent - // operation. - Block *parentBlock = parentOp->getBlock(); - - auto parentBlockIt = blockNumbersOfExecution.find(parentBlock); - if (parentBlockIt == blockNumbersOfExecution.end()) - return None; - const auto &parentBlockInfo = parentBlockIt->getSecond(); - auto parentBlockExecutions = getNumberOfExecutions(parentBlockInfo); - - // We stumbled upon an operation with unknown number of executions. - if (!parentBlockExecutions.hasValue()) - return None; - - // Number of block executions is a product of all parent blocks executions. - numberOfExecutions *= *parentBlockExecutions; - parentOp = parentOp->getParentOp(); - - assert(parentOp != nullptr); - } - - return numberOfExecutions; -} - -void NumberOfExecutions::printBlockExecutions( - raw_ostream &os, Region *perEntryOfThisRegion) const { - unsigned blockId = 0; - - operation->walk([&](Block *block) { - llvm::errs() << "Block: " << blockId++ << "\n"; - llvm::errs() << "Number of executions: "; - if (auto n = getNumberOfExecutions(block, perEntryOfThisRegion)) - llvm::errs() << *n << "\n"; - else - llvm::errs() << "\n"; - }); -} - -void NumberOfExecutions::printOperationExecutions( - raw_ostream &os, Region *perEntryOfThisRegion) const { - operation->walk([&](Block *block) { - block->walk([&](Operation *operation) { - // Skip the operation that was used to build the analysis. - if (operation == this->operation) - return; - - llvm::errs() << "Operation: " << operation->getName() << "\n"; - llvm::errs() << "Number of executions: "; - if (auto n = getNumberOfExecutions(operation, perEntryOfThisRegion)) - llvm::errs() << *n << "\n"; - else - llvm::errs() << "\n"; - }); - }); -} - -//===----------------------------------------------------------------------===// -// BlockNumberOfExecutionsInfo -//===----------------------------------------------------------------------===// - -BlockNumberOfExecutionsInfo::BlockNumberOfExecutionsInfo( - Block *block, Optional numberOfRegionInvocations, - Optional numberOfBlockExecutions) - : block(block), numberOfRegionInvocations(numberOfRegionInvocations), - numberOfBlockExecutions(numberOfBlockExecutions) {} - -Optional BlockNumberOfExecutionsInfo::getNumberOfExecutions() const { - if (numberOfRegionInvocations && numberOfBlockExecutions) - return *numberOfRegionInvocations * *numberOfBlockExecutions; - return None; -} - -Optional BlockNumberOfExecutionsInfo::getNumberOfExecutions( - int64_t numberOfRegionInvocations) const { - if (numberOfBlockExecutions) - return numberOfRegionInvocations * *numberOfBlockExecutions; - return None; -} diff --git a/mlir/lib/Dialect/Async/IR/Async.cpp b/mlir/lib/Dialect/Async/IR/Async.cpp index acae4cdba18d..c33d023c8d12 100644 --- a/mlir/lib/Dialect/Async/IR/Async.cpp +++ b/mlir/lib/Dialect/Async/IR/Async.cpp @@ -60,12 +60,6 @@ YieldOp::getMutableSuccessorOperands(Optional index) { constexpr char kOperandSegmentSizesAttr[] = "operand_segment_sizes"; -void ExecuteOp::getNumRegionInvocations( - ArrayRef, SmallVectorImpl &countPerRegion) { - assert(countPerRegion.empty()); - countPerRegion.push_back(1); -} - OperandRange ExecuteOp::getSuccessorEntryOperands(unsigned index) { assert(index == 0 && "invalid region index"); return operands(); diff --git a/mlir/lib/Dialect/SCF/SCF.cpp b/mlir/lib/Dialect/SCF/SCF.cpp index 8a7509e469bf..7c6d13aad73b 100644 --- a/mlir/lib/Dialect/SCF/SCF.cpp +++ b/mlir/lib/Dialect/SCF/SCF.cpp @@ -463,26 +463,6 @@ void ForOp::getSuccessorRegions(Optional index, regions.push_back(RegionSuccessor(getResults())); } -void ForOp::getNumRegionInvocations(ArrayRef operands, - SmallVectorImpl &countPerRegion) { - assert(countPerRegion.empty()); - countPerRegion.resize(1); - - auto lb = operands[0].dyn_cast_or_null(); - auto ub = operands[1].dyn_cast_or_null(); - auto step = operands[2].dyn_cast_or_null(); - - // Loop bounds are not known statically. - if (!lb || !ub || !step || step.getValue().getSExtValue() == 0) { - countPerRegion[0] = kUnknownNumRegionInvocations; - return; - } - - countPerRegion[0] = - ceilDiv(ub.getValue().getSExtValue() - lb.getValue().getSExtValue(), - step.getValue().getSExtValue()); -} - LoopNest mlir::scf::buildLoopNest( OpBuilder &builder, Location loc, ValueRange lbs, ValueRange ubs, ValueRange steps, ValueRange iterArgs, @@ -1182,23 +1162,6 @@ void IfOp::getSuccessorRegions(Optional index, regions.push_back(RegionSuccessor(condition ? &getThenRegion() : elseRegion)); } -/// If the condition is a constant, returns 1 for the executed block and 0 for -/// the other. Otherwise, returns `kUnknownNumRegionInvocations` for both -/// successors. -void IfOp::getNumRegionInvocations(ArrayRef operands, - SmallVectorImpl &countPerRegion) { - if (auto condAttr = operands.front().dyn_cast_or_null()) { - // If the condition is true, `then` is executed once and `else` zero times, - // and vice-versa. - bool cond = condAttr.getValue().isOneValue(); - countPerRegion.assign(1, cond ? 1 : 0); - countPerRegion.push_back(cond ? 0 : 1); - } else { - // Non-constant condition: unknown invocations for both successors. - countPerRegion.assign(2, kUnknownNumRegionInvocations); - } -} - LogicalResult IfOp::fold(ArrayRef operands, SmallVectorImpl &results) { // if (!c) then A() else B() -> if c then B() else A() diff --git a/mlir/lib/Interfaces/ControlFlowInterfaces.cpp b/mlir/lib/Interfaces/ControlFlowInterfaces.cpp index d2ab30282562..c8319bc1db96 100644 --- a/mlir/lib/Interfaces/ControlFlowInterfaces.cpp +++ b/mlir/lib/Interfaces/ControlFlowInterfaces.cpp @@ -73,9 +73,6 @@ detail::verifyBranchSuccessorOperands(Operation *op, unsigned succNo, // RegionBranchOpInterface //===----------------------------------------------------------------------===// -// A constant value to represent unknown number of region invocations. -const int64_t mlir::kUnknownNumRegionInvocations = -1; - /// Verify that types match along all region control flow edges originating from /// `sourceNo` (region # if source is a region, llvm::None if source is parent /// op). `getInputsTypesForRegion` is a function that returns the types of the diff --git a/mlir/test/Analysis/test-number-of-block-executions.mlir b/mlir/test/Analysis/test-number-of-block-executions.mlir deleted file mode 100644 index 84fd7a7e87b3..000000000000 --- a/mlir/test/Analysis/test-number-of-block-executions.mlir +++ /dev/null @@ -1,192 +0,0 @@ -// RUN: mlir-opt %s \ -// RUN: -test-print-number-of-block-executions \ -// RUN: -split-input-file 2>&1 \ -// RUN: | FileCheck %s --dump-input=always - -// CHECK-LABEL: Number of executions: empty -func @empty() { - // CHECK: Block: 0 - // CHECK-NEXT: Number of executions: 1 - return -} - -// ----- - -// CHECK-LABEL: Number of executions: sequential -func @sequential() { - // CHECK: Block: 0 - // CHECK-NEXT: Number of executions: 1 - br ^bb1 -^bb1: - // CHECK: Block: 1 - // CHECK-NEXT: Number of executions: 1 - br ^bb2 -^bb2: - // CHECK: Block: 2 - // CHECK-NEXT: Number of executions: 1 - return -} - -// ----- - -// CHECK-LABEL: Number of executions: conditional -func @conditional(%cond : i1) { - // CHECK: Block: 0 - // CHECK-NEXT: Number of executions: 1 - br ^bb1 -^bb1: - // CHECK: Block: 1 - // CHECK-NEXT: Number of executions: 1 - cond_br %cond, ^bb2, ^bb3 -^bb2: - // CHECK: Block: 2 - // CHECK-NEXT: Number of executions: - br ^bb4 -^bb3: - // CHECK: Block: 3 - // CHECK-NEXT: Number of executions: - br ^bb4 -^bb4: - // CHECK: Block: 4 - // CHECK-NEXT: Number of executions: - return -} - -// ----- - -// CHECK-LABEL: Number of executions: loop -func @loop(%cond : i1) { - // CHECK: Block: 0 - // CHECK-NEXT: Number of executions: 1 - br ^bb1 -^bb1: - // CHECK: Block: 1 - // CHECK-NEXT: Number of executions: - br ^bb2 -^bb2: - // CHECK: Block: 2 - // CHECK-NEXT: Number of executions: - br ^bb3 -^bb3: - // CHECK: Block: 3 - // CHECK-NEXT: Number of executions: - cond_br %cond, ^bb1, ^bb4 -^bb4: - // CHECK: Block: 4 - // CHECK-NEXT: Number of executions: - return -} - -// ----- - -// CHECK-LABEL: Number of executions: scf_if_dynamic_branch -func @scf_if_dynamic_branch(%cond : i1) { - // CHECK: Block: 0 - // CHECK-NEXT: Number of executions: 1 - scf.if %cond { - // CHECK: Block: 1 - // CHECK-NEXT: Number of executions: - } else { - // CHECK: Block: 2 - // CHECK-NEXT: Number of executions: - } - return -} - -// ----- - -// CHECK-LABEL: Number of executions: async_execute -func @async_execute() { - // CHECK: Block: 0 - // CHECK-NEXT: Number of executions: 1 - async.execute { - // CHECK: Block: 1 - // CHECK-NEXT: Number of executions: 1 - async.yield - } - return -} - -// ----- - -// CHECK-LABEL: Number of executions: async_execute_with_scf_if -func @async_execute_with_scf_if(%cond : i1) { - // CHECK: Block: 0 - // CHECK-NEXT: Number of executions: 1 - async.execute { - // CHECK: Block: 1 - // CHECK-NEXT: Number of executions: 1 - scf.if %cond { - // CHECK: Block: 2 - // CHECK-NEXT: Number of executions: - } else { - // CHECK: Block: 3 - // CHECK-NEXT: Number of executions: - } - async.yield - } - return -} - -// ----- - -// CHECK-LABEL: Number of executions: scf_for_constant_bounds -func @scf_for_constant_bounds() { - // CHECK: Block: 0 - // CHECK-NEXT: Number of executions: 1 - %c0 = arith.constant 0 : index - %c1 = arith.constant 1 : index - %c2 = arith.constant 2 : index - - scf.for %i = %c0 to %c2 step %c1 { - // CHECK: Block: 1 - // CHECK-NEXT: Number of executions: 2 - } - - return -} - -// ----- - -// CHECK-LABEL: Number of executions: propagate_parent_num_executions -func @propagate_parent_num_executions() { - // CHECK: Block: 0 - // CHECK-NEXT: Number of executions: 1 - %c0 = arith.constant 0 : index - %c1 = arith.constant 1 : index - %c2 = arith.constant 2 : index - - scf.for %i = %c0 to %c2 step %c1 { - // CHECK: Block: 1 - // CHECK-NEXT: Number of executions: 2 - async.execute { - // CHECK: Block: 2 - // CHECK-NEXT: Number of executions: 2 - async.yield - } - } - - return -} - -// ----- - -// CHECK-LABEL: Number of executions: clear_num_executions -func @clear_num_executions(%step : index) { - // CHECK: Block: 0 - // CHECK-NEXT: Number of executions: 1 - %c0 = arith.constant 0 : index - %c2 = arith.constant 2 : index - - scf.for %i = %c0 to %c2 step %step { - // CHECK: Block: 1 - // CHECK-NEXT: Number of executions: - async.execute { - // CHECK: Block: 2 - // CHECK-NEXT: Number of executions: - async.yield - } - } - - return -} diff --git a/mlir/test/Analysis/test-number-of-operation-executions.mlir b/mlir/test/Analysis/test-number-of-operation-executions.mlir deleted file mode 100644 index bdbc403b34bd..000000000000 --- a/mlir/test/Analysis/test-number-of-operation-executions.mlir +++ /dev/null @@ -1,66 +0,0 @@ -// RUN: mlir-opt %s \ -// RUN: -test-print-number-of-operation-executions \ -// RUN: -split-input-file 2>&1 \ -// RUN: | FileCheck %s - -// CHECK-LABEL: Number of executions: empty -func @empty() { - // CHECK: Operation: std.return - // CHECK-NEXT: Number of executions: 1 - return -} - -// ----- - -// CHECK-LABEL: Number of executions: propagate_parent_num_executions -func @propagate_parent_num_executions() { - // CHECK: Operation: arith.constant - // CHECK-NEXT: Number of executions: 1 - %c0 = arith.constant 0 : index - // CHECK: Operation: arith.constant - // CHECK-NEXT: Number of executions: 1 - %c1 = arith.constant 1 : index - // CHECK: Operation: arith.constant - // CHECK-NEXT: Number of executions: 1 - %c2 = arith.constant 2 : index - - // CHECK-DAG: Operation: scf.for - // CHECK-NEXT: Number of executions: 1 - scf.for %i = %c0 to %c2 step %c1 { - // CHECK-DAG: Operation: async.execute - // CHECK-NEXT: Number of executions: 2 - async.execute { - // CHECK-DAG: Operation: async.yield - // CHECK-NEXT: Number of executions: 2 - async.yield - } - } - - return -} - -// ----- - -// CHECK-LABEL: Number of executions: clear_num_executions -func @clear_num_executions(%step : index) { - // CHECK: Operation: arith.constant - // CHECK-NEXT: Number of executions: 1 - %c0 = arith.constant 0 : index - // CHECK: Operation: arith.constant - // CHECK-NEXT: Number of executions: 1 - %c2 = arith.constant 2 : index - - // CHECK: Operation: scf.for - // CHECK-NEXT: Number of executions: 1 - scf.for %i = %c0 to %c2 step %step { - // CHECK: Operation: async.execute - // CHECK-NEXT: Number of executions: - async.execute { - // CHECK: Operation: async.yield - // CHECK-NEXT: Number of executions: - async.yield - } - } - - return -} diff --git a/mlir/test/lib/Analysis/CMakeLists.txt b/mlir/test/lib/Analysis/CMakeLists.txt index 00321034429d..fc378b8af84f 100644 --- a/mlir/test/lib/Analysis/CMakeLists.txt +++ b/mlir/test/lib/Analysis/CMakeLists.txt @@ -7,7 +7,6 @@ add_mlir_library(MLIRTestAnalysis TestMemRefBoundCheck.cpp TestMemRefDependenceCheck.cpp TestMemRefStrideCalculation.cpp - TestNumberOfExecutions.cpp TestSlice.cpp diff --git a/mlir/test/lib/Analysis/TestNumberOfExecutions.cpp b/mlir/test/lib/Analysis/TestNumberOfExecutions.cpp deleted file mode 100644 index 5684096bff22..000000000000 --- a/mlir/test/lib/Analysis/TestNumberOfExecutions.cpp +++ /dev/null @@ -1,67 +0,0 @@ -//===- TestNumberOfExecutions.cpp - Test number of executions 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 -// -//===----------------------------------------------------------------------===// -// -// This file contains test passes for constructing and resolving number of -// executions information. -// -//===----------------------------------------------------------------------===// - -#include "mlir/Analysis/NumberOfExecutions.h" -#include "mlir/Pass/Pass.h" - -using namespace mlir; - -namespace { - -struct TestNumberOfBlockExecutionsPass - : public PassWrapper { - StringRef getArgument() const final { - return "test-print-number-of-block-executions"; - } - StringRef getDescription() const final { - return "Print the contents of a constructed number of executions analysis " - "for " - "all blocks."; - } - void runOnFunction() override { - llvm::errs() << "Number of executions: " << getFunction().getName() << "\n"; - getAnalysis().printBlockExecutions( - llvm::errs(), &getFunction().getBody()); - } -}; - -struct TestNumberOfOperationExecutionsPass - : public PassWrapper { - StringRef getArgument() const final { - return "test-print-number-of-operation-executions"; - } - StringRef getDescription() const final { - return "Print the contents of a constructed number of executions analysis " - "for " - "all operations."; - } - void runOnFunction() override { - llvm::errs() << "Number of executions: " << getFunction().getName() << "\n"; - getAnalysis().printOperationExecutions( - llvm::errs(), &getFunction().getBody()); - } -}; - -} // namespace - -namespace mlir { -namespace test { -void registerTestNumberOfBlockExecutionsPass() { - PassRegistration(); -} - -void registerTestNumberOfOperationExecutionsPass() { - PassRegistration(); -} -} // namespace test -} // namespace mlir diff --git a/mlir/tools/mlir-opt/mlir-opt.cpp b/mlir/tools/mlir-opt/mlir-opt.cpp index 120585c806a9..9a54cf257ce2 100644 --- a/mlir/tools/mlir-opt/mlir-opt.cpp +++ b/mlir/tools/mlir-opt/mlir-opt.cpp @@ -102,8 +102,6 @@ void registerTestMathAlgebraicSimplificationPass(); void registerTestMathPolynomialApproximationPass(); void registerTestMemRefDependenceCheck(); void registerTestMemRefStrideCalculation(); -void registerTestNumberOfBlockExecutionsPass(); -void registerTestNumberOfOperationExecutionsPass(); void registerTestOpaqueLoc(); void registerTestPadFusion(); void registerTestPDLByteCodePass(); @@ -196,8 +194,6 @@ void registerTestPasses() { mlir::test::registerTestMathPolynomialApproximationPass(); mlir::test::registerTestMemRefDependenceCheck(); mlir::test::registerTestMemRefStrideCalculation(); - mlir::test::registerTestNumberOfBlockExecutionsPass(); - mlir::test::registerTestNumberOfOperationExecutionsPass(); mlir::test::registerTestOpaqueLoc(); mlir::test::registerTestPadFusion(); mlir::test::registerTestPDLByteCodePass(); diff --git a/mlir/unittests/Dialect/CMakeLists.txt b/mlir/unittests/Dialect/CMakeLists.txt index 91aec5054af2..f37f578572b8 100644 --- a/mlir/unittests/Dialect/CMakeLists.txt +++ b/mlir/unittests/Dialect/CMakeLists.txt @@ -7,7 +7,6 @@ target_link_libraries(MLIRDialectTests MLIRDialect) add_subdirectory(Quant) -add_subdirectory(SCF) add_subdirectory(SparseTensor) add_subdirectory(SPIRV) add_subdirectory(Utils) diff --git a/mlir/unittests/Dialect/SCF/CMakeLists.txt b/mlir/unittests/Dialect/SCF/CMakeLists.txt deleted file mode 100644 index 81e05d353d49..000000000000 --- a/mlir/unittests/Dialect/SCF/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -add_mlir_unittest(MLIRSCFTests - SCFOps.cpp - ) -target_link_libraries(MLIRSCFTests - PRIVATE - MLIRIR - MLIRParser - MLIRSCF - MLIRStandard - ) diff --git a/mlir/unittests/Dialect/SCF/SCFOps.cpp b/mlir/unittests/Dialect/SCF/SCFOps.cpp deleted file mode 100644 index 099bd2764e7d..000000000000 --- a/mlir/unittests/Dialect/SCF/SCFOps.cpp +++ /dev/null @@ -1,67 +0,0 @@ -//===- SCFOps.cpp - SCF Op Unit Tests -------------------------------------===// -// -// 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/Dialect/SCF/SCF.h" -#include "mlir/Dialect/StandardOps/IR/Ops.h" -#include "mlir/Parser.h" -#include "gtest/gtest.h" - -using namespace mlir; - -namespace { -class SCFOpsTest : public testing::Test { -public: - SCFOpsTest() { - context.getOrLoadDialect(); - context.getOrLoadDialect(); - } - -protected: - MLIRContext context; -}; - -TEST_F(SCFOpsTest, IfOpNumRegionInvocations) { - const char *const code = R"mlir( -func @test(%cond : i1) -> () { - scf.if %cond { - scf.yield - } else { - scf.yield - } - return -} -)mlir"; - Builder builder(&context); - - auto module = parseSourceString(code, &context); - ASSERT_TRUE(module); - scf::IfOp op; - module->walk([&](scf::IfOp ifOp) { op = ifOp; }); - ASSERT_TRUE(op); - - SmallVector countPerRegion; - op.getNumRegionInvocations({Attribute()}, countPerRegion); - EXPECT_EQ(countPerRegion.size(), 2u); - EXPECT_EQ(countPerRegion[0], kUnknownNumRegionInvocations); - EXPECT_EQ(countPerRegion[1], kUnknownNumRegionInvocations); - - countPerRegion.clear(); - op.getNumRegionInvocations( - {builder.getIntegerAttr(builder.getI1Type(), true)}, countPerRegion); - EXPECT_EQ(countPerRegion.size(), 2u); - EXPECT_EQ(countPerRegion[0], 1); - EXPECT_EQ(countPerRegion[1], 0); - - countPerRegion.clear(); - op.getNumRegionInvocations( - {builder.getIntegerAttr(builder.getI1Type(), false)}, countPerRegion); - EXPECT_EQ(countPerRegion.size(), 2u); - EXPECT_EQ(countPerRegion[0], 0); - EXPECT_EQ(countPerRegion[1], 1); -} -} // end anonymous namespace