brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.2 KiB · d590ccc Raw
76 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8#include "PassDetail.h"9#include "clang/CIR/Dialect/IR/CIRDialect.h"10#include "clang/CIR/Dialect/Passes.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_GOTOSOLVER20#include "clang/CIR/Dialect/Passes.h.inc"21} // namespace mlir22 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;33  llvm::SmallVector<cir::GotoOp, 4> gotos;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 safe51      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} // namespace72 73std::unique_ptr<Pass> mlir::createGotoSolverPass() {74  return std::make_unique<GotoSolverPass>();75}76