clang 22.0.0git
GotoSolver.cpp
Go to the documentation of this file.
1//====- GotoSolver.cpp -----------------------------------===//
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-exception
6//
7//===----------------------------------------------------------------------===//
8#include "PassDetail.h"
11#include "llvm/ADT/SmallSet.h"
12#include "llvm/Support/TimeProfiler.h"
13#include <memory>
14
15using namespace mlir;
16using namespace cir;
17
18namespace mlir {
19#define GEN_PASS_DEF_GOTOSOLVER
20#include "clang/CIR/Dialect/Passes.h.inc"
21} // namespace mlir
22
23namespace {
24
25struct GotoSolverPass : public impl::GotoSolverBase<GotoSolverPass> {
26 GotoSolverPass() = default;
27 void runOnOperation() override;
28};
29
30static void process(cir::FuncOp func) {
31 mlir::OpBuilder rewriter(func.getContext());
32 llvm::StringMap<Block *> labels;
34 llvm::SmallSet<StringRef, 4> blockAddrLabel;
35
36 func.getBody().walk([&](mlir::Operation *op) {
37 if (auto lab = dyn_cast<cir::LabelOp>(op)) {
38 labels.try_emplace(lab.getLabel(), lab->getBlock());
39 } else if (auto goTo = dyn_cast<cir::GotoOp>(op)) {
40 gotos.push_back(goTo);
41 } else if (auto blockAddr = dyn_cast<cir::BlockAddressOp>(op)) {
42 blockAddrLabel.insert(blockAddr.getBlockAddrInfo().getLabel());
43 }
44 });
45
46 for (auto &lab : labels) {
47 StringRef labelName = lab.getKey();
48 Block *block = lab.getValue();
49 if (!blockAddrLabel.contains(labelName)) {
50 // erase the LabelOp inside the block if safe
51 if (auto lab = dyn_cast<cir::LabelOp>(&block->front())) {
52 lab.erase();
53 }
54 }
55 }
56
57 for (auto goTo : gotos) {
58 mlir::OpBuilder::InsertionGuard guard(rewriter);
59 rewriter.setInsertionPoint(goTo);
60 Block *dest = labels[goTo.getLabel()];
61 cir::BrOp::create(rewriter, goTo.getLoc(), dest);
62 goTo.erase();
63 }
64}
65
66void GotoSolverPass::runOnOperation() {
67 llvm::TimeTraceScope scope("Goto Solver");
68 getOperation()->walk(&process);
69}
70
71} // namespace
72
73std::unique_ptr<Pass> mlir::createGotoSolverPass() {
74 return std::make_unique<GotoSolverPass>();
75}
std::unique_ptr< Pass > createGotoSolverPass()