11#include "llvm/ADT/SmallSet.h"
12#include "llvm/Support/TimeProfiler.h"
19#define GEN_PASS_DEF_GOTOSOLVER
20#include "clang/CIR/Dialect/Passes.h.inc"
25struct GotoSolverPass :
public impl::GotoSolverBase<GotoSolverPass> {
26 GotoSolverPass() =
default;
27 void runOnOperation()
override;
30static void process(cir::FuncOp func) {
31 mlir::OpBuilder rewriter(func.getContext());
32 llvm::StringMap<Block *> labels;
34 llvm::SmallSet<StringRef, 4> blockAddrLabel;
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());
46 for (
auto &lab : labels) {
47 StringRef labelName = lab.getKey();
48 Block *block = lab.getValue();
49 if (!blockAddrLabel.contains(labelName)) {
51 if (
auto lab = dyn_cast<cir::LabelOp>(&block->front())) {
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);
66void GotoSolverPass::runOnOperation() {
67 llvm::TimeTraceScope scope(
"Goto Solver");
68 getOperation()->walk(&process);
74 return std::make_unique<GotoSolverPass>();
std::unique_ptr< Pass > createGotoSolverPass()