brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.5 KiB · 1e226c0 Raw
106 lines · cpp
1//===- RuntimeOpVerification.cpp - Op Verification ------------------------===//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 9#include "mlir/IR/AsmState.h"10#include "mlir/Transforms/Passes.h"11 12#include "mlir/IR/Builders.h"13#include "mlir/IR/Operation.h"14#include "mlir/Interfaces/RuntimeVerifiableOpInterface.h"15 16namespace mlir {17#define GEN_PASS_DEF_GENERATERUNTIMEVERIFICATION18#include "mlir/Transforms/Passes.h.inc"19} // namespace mlir20 21using namespace mlir;22 23namespace {24struct GenerateRuntimeVerificationPass25    : public impl::GenerateRuntimeVerificationBase<26          GenerateRuntimeVerificationPass> {27  void runOnOperation() override;28};29 30/// Default error message generator for runtime verification failures.31///32/// This class generates error messages with different levels of verbosity:33/// - Level 0: Shows only the error message and operation location34/// - Level 1: Shows the full operation string, error message, and location35///36/// Clients can call getVerboseLevel() to retrieve the current verbose level37/// and use it to customize their own error message generators with similar38/// behavior patterns.39class DefaultErrMsgGenerator {40private:41  unsigned vLevel;42  AsmState &state;43 44public:45  DefaultErrMsgGenerator(unsigned verboseLevel, AsmState &asmState)46      : vLevel(verboseLevel), state(asmState) {}47 48  std::string operator()(Operation *op, StringRef msg) {49    std::string buffer;50    llvm::raw_string_ostream stream(buffer);51    stream << "ERROR: Runtime op verification failed\n";52    if (vLevel == 1) {53      op->print(stream, state);54      stream << "\n^ " << msg;55    } else {56      stream << "^ " << msg;57    }58    stream << "\nLocation: ";59    op->getLoc().print(stream);60    return buffer;61  }62 63  unsigned getVerboseLevel() const { return vLevel; }64};65} // namespace66 67void GenerateRuntimeVerificationPass::runOnOperation() {68  // Check verboseLevel is in range [0, 1].69  if (verboseLevel > 1) {70    getOperation()->emitError(71        "generate-runtime-verification pass: set verboseLevel to 0 or 1");72    signalPassFailure();73    return;74  }75 76  // The implementation of the RuntimeVerifiableOpInterface may create ops that77  // can be verified. We don't want to generate verification for IR that78  // performs verification, so gather all runtime-verifiable ops first.79  SmallVector<RuntimeVerifiableOpInterface> ops;80  getOperation()->walk([&](RuntimeVerifiableOpInterface verifiableOp) {81    ops.push_back(verifiableOp);82  });83 84  // We may generate a lot of error messages and so we need to ensure the85  // printing is fast.86  OpPrintingFlags flags;87  flags.elideLargeElementsAttrs();88  flags.skipRegions();89  flags.useLocalScope();90  AsmState state(getOperation(), flags);91 92  // Client can call getVerboseLevel() to fetch verbose level.93  DefaultErrMsgGenerator defaultErrMsgGenerator(verboseLevel.getValue(), state);94 95  OpBuilder builder(getOperation()->getContext());96  for (RuntimeVerifiableOpInterface verifiableOp : ops) {97    builder.setInsertionPoint(verifiableOp);98    verifiableOp.generateRuntimeVerification(builder, verifiableOp.getLoc(),99                                             defaultErrMsgGenerator);100  };101}102 103std::unique_ptr<Pass> mlir::createGenerateRuntimeVerificationPass() {104  return std::make_unique<GenerateRuntimeVerificationPass>();105}106