This commit simplifies the design of the `RegionBranchOpInterface`. The property of being a successor input is now independent of the region branch point. There is a new API for querying successor inputs: `RegionBranchOpInterface::getSuccessorInputs(RegionSuccessor)`. Note that this function does **not** take a `RegionBranchPoint` as parameter. The `RegionSuccessor` API is now also simpler: it no longer stores successor inputs. A region successor is simply `Region *`, wrapped around a convenience API. Note: This commit is mostly mechanical. Analyses / transformations that build on top of the `RegionBranchOpInterface` (e.g., `visitNonControlFlowArguments` API) can likely be simplified in follow-up commits. Note for LLVM integration: Split `RegionBranchOpInterface::getSuccessorRegion` implementations into two functions: `getSuccessorRegion` and `getSuccessorInputs. (There are many examples in this commit.) RFC: https://discourse.llvm.org/t/rfc-simplify-regionbranchopinterface-separate-successor-inputs-from-region-successor/89420/7
85 lines
2.8 KiB
C++
85 lines
2.8 KiB
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
|
|
//
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
#include "clang/CIR/Interfaces/CIRLoopOpInterface.h"
|
|
|
|
#include "clang/CIR/Dialect/IR/CIRDialect.h"
|
|
#include "clang/CIR/Interfaces/CIRLoopOpInterface.cpp.inc"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
|
|
namespace cir {
|
|
|
|
void LoopOpInterface::getLoopOpSuccessorRegions(
|
|
LoopOpInterface op, mlir::RegionBranchPoint point,
|
|
llvm::SmallVectorImpl<mlir::RegionSuccessor> ®ions) {
|
|
assert(point.isParent() || point.getTerminatorPredecessorOrNull());
|
|
|
|
// Branching to first region: go to condition or body (do-while).
|
|
if (point.isParent()) {
|
|
regions.emplace_back(&op.getEntry());
|
|
return;
|
|
}
|
|
|
|
mlir::Region *parentRegion =
|
|
point.getTerminatorPredecessorOrNull()->getParentRegion();
|
|
|
|
// Branching from condition: go to body or exit.
|
|
if (&op.getCond() == parentRegion) {
|
|
regions.emplace_back(mlir::RegionSuccessor::parent());
|
|
regions.emplace_back(&op.getBody());
|
|
return;
|
|
}
|
|
|
|
// Branching from body: go to step (for) or condition.
|
|
if (&op.getBody() == parentRegion) {
|
|
// FIXME(cir): Should we consider break/continue statements here?
|
|
mlir::Region *afterBody =
|
|
(op.maybeGetStep() ? op.maybeGetStep() : &op.getCond());
|
|
regions.emplace_back(afterBody);
|
|
return;
|
|
}
|
|
|
|
// Branching from step: go to condition.
|
|
if (op.maybeGetStep() == parentRegion) {
|
|
regions.emplace_back(&op.getCond());
|
|
return;
|
|
}
|
|
|
|
llvm_unreachable("unexpected branch origin");
|
|
}
|
|
|
|
mlir::ValueRange
|
|
LoopOpInterface::getLoopOpSuccessorInputs(LoopOpInterface op,
|
|
mlir::RegionSuccessor successor) {
|
|
if (successor.isParent())
|
|
return op->getResults();
|
|
if (successor == &op.getEntry())
|
|
return op.getEntry().getArguments();
|
|
if (successor == &op.getBody())
|
|
return op.getBody().getArguments();
|
|
mlir::Region *afterBody =
|
|
(op.maybeGetStep() ? op.maybeGetStep() : &op.getCond());
|
|
if (successor == afterBody)
|
|
return afterBody->getArguments();
|
|
if (successor == &op.getCond())
|
|
return op.getCond().getArguments();
|
|
llvm_unreachable("invalid region successor");
|
|
}
|
|
|
|
/// Verify invariants of the LoopOpInterface.
|
|
llvm::LogicalResult detail::verifyLoopOpInterface(mlir::Operation *op) {
|
|
// FIXME: fix this so the conditionop isn't requiring MLIRCIR
|
|
// auto loopOp = mlir::cast<LoopOpInterface>(op);
|
|
// if (!mlir::isa<ConditionOp>(loopOp.getCond().back().getTerminator()))
|
|
// return op->emitOpError(
|
|
// "expected condition region to terminate with 'cir.condition'");
|
|
return llvm::success();
|
|
}
|
|
|
|
} // namespace cir
|