16#include "mlir/IR/Block.h"
17#include "mlir/IR/Region.h"
18#include "mlir/Interfaces/ControlFlowInterfaces.h"
21#include "llvm/ADT/STLExtras.h"
27#define GEN_PASS_DEF_CIRFOLDEMPTYBRANCHES
28#include "clang/CIR/Dialect/Passes.h.inc"
33struct CIRFoldEmptyBranchesPass
34 :
public impl::CIRFoldEmptyBranchesBase<CIRFoldEmptyBranchesPass> {
35 using CIRFoldEmptyBranchesBase::CIRFoldEmptyBranchesBase;
37 void runOnOperation()
override;
46static bool foldEmptyBranch(Block &block) {
47 if (block.isEntryBlock() || block.getNumArguments() != 0 ||
48 !llvm::hasSingleElement(block))
51 auto br = dyn_cast<cir::BrOp>(block.front());
52 if (!br || br.getDest() == &block || br.getLoopIdAttr())
55 Block *dest = br.getDest();
56 if (dest->getSinglePredecessor() != &block)
59 if (!llvm::all_of(block.getPredecessors(), [](Block *pred) {
60 return isa<BranchOpInterface>(pred->getTerminator());
65 for (BlockOperand &use : llvm::make_early_inc_range(block.getUses())) {
66 auto branch = cast<BranchOpInterface>(use.getOwner());
67 unsigned index = use.getOperandNumber();
68 branch.getSuccessorOperands(index).append(operands);
69 branch->setSuccessor(dest, index);
75void CIRFoldEmptyBranchesPass::runOnOperation() {
76 getOperation()->walk([](Region *region) {
80 for (Block &block : llvm::make_early_inc_range(*region))
81 changed |= foldEmptyBranch(block);
89 return std::make_unique<CIRFoldEmptyBranchesPass>();
std::unique_ptr< Pass > createCIRFoldEmptyBranchesPass()