brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.1 KiB · 699be12 Raw
107 lines · cpp
1//===- GenRuntimeCallsForTest.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 9//===----------------------------------------------------------------------===//10/// \file11/// This pass is only for developers to generate declarations/calls12/// of Fortran runtime function recognized in13/// flang/Optimizer/Transforms/RuntimeFunctions.inc table.14/// Sample of the generated FIR:15///   func.func private16///       @_FortranAioSetStatus(!fir.ref<i8>, !fir.ref<i8>, i64) ->17///       i1 attributes {fir.io, fir.runtime}18///19///   func.func @test__FortranAioSetStatus(20///       %arg0: !fir.ref<i8>, %arg1: !fir.ref<i8>, %arg2: i64) -> i1 {21///    %0 = fir.call @_FortranAioSetStatus(%arg0, %arg1, %arg2) :22///        (!fir.ref<i8>, !fir.ref<i8>, i64) -> i123///    return %0 : i124///  }25//===----------------------------------------------------------------------===//26#include "flang/Common/static-multimap-view.h"27#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"28#include "flang/Optimizer/Dialect/FIRDialect.h"29#include "flang/Optimizer/Dialect/FIROpsSupport.h"30#include "flang/Optimizer/Support/InternalNames.h"31#include "flang/Optimizer/Transforms/Passes.h"32#include "flang/Runtime/io-api.h"33#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"34 35namespace fir {36#define GEN_PASS_DEF_GENRUNTIMECALLSFORTEST37#include "flang/Optimizer/Transforms/Passes.h.inc"38} // namespace fir39 40#define DEBUG_TYPE "gen-runtime-calls-for-test"41 42using namespace Fortran::runtime;43using namespace Fortran::runtime::io;44 45#define mkIOKey(X) FirmkKey(IONAME(X))46#define mkRTKey(X) FirmkKey(RTNAME(X))47 48namespace {49class GenRuntimeCallsForTestPass50    : public fir::impl::GenRuntimeCallsForTestBase<GenRuntimeCallsForTestPass> {51  using GenRuntimeCallsForTestBase<52      GenRuntimeCallsForTestPass>::GenRuntimeCallsForTestBase;53 54public:55  void runOnOperation() override;56};57} // end anonymous namespace58 59static constexpr llvm::StringRef testPrefix = "test_";60 61void GenRuntimeCallsForTestPass::runOnOperation() {62  mlir::ModuleOp moduleOp = getOperation();63  mlir::OpBuilder mlirBuilder(moduleOp.getRegion());64  fir::FirOpBuilder builder(mlirBuilder, moduleOp);65  mlir::Location loc = mlir::UnknownLoc::get(builder.getContext());66 67#define KNOWN_IO_FUNC(X)                                                       \68  fir::runtime::getIORuntimeFunc<mkIOKey(X)>(loc, builder)69#define KNOWN_RUNTIME_FUNC(X)                                                  \70  fir::runtime::getRuntimeFunc<mkRTKey(X)>(loc, builder)71 72  mlir::func::FuncOp runtimeFuncsTable[] = {73#include "flang/Optimizer/Transforms/RuntimeFunctions.inc"74  };75 76  if (!doGenerateCalls)77    return;78 79  // Generate thin wrapper functions calling the known Fortran80  // runtime functions.81  llvm::SmallVector<mlir::Operation *> newFuncs;82  for (unsigned i = 0;83       i < sizeof(runtimeFuncsTable) / sizeof(runtimeFuncsTable[0]); ++i) {84    mlir::func::FuncOp funcOp = runtimeFuncsTable[i];85    mlir::FunctionType funcTy = funcOp.getFunctionType();86    std::string name = (llvm::Twine(testPrefix) + funcOp.getName()).str();87    mlir::func::FuncOp callerFunc = builder.createFunction(loc, name, funcTy);88    callerFunc.setVisibility(mlir::SymbolTable::Visibility::Public);89    mlir::OpBuilder::InsertPoint insertPt = builder.saveInsertionPoint();90 91    // Generate the wrapper function body that consists of a call and return.92    builder.setInsertionPointToStart(callerFunc.addEntryBlock());93    mlir::Block::BlockArgListType args = callerFunc.front().getArguments();94    auto callOp = fir::CallOp::create(builder, loc, funcOp, args);95    mlir::func::ReturnOp::create(builder, loc, callOp.getResults());96 97    newFuncs.push_back(callerFunc.getOperation());98    builder.restoreInsertionPoint(insertPt);99  }100 101  // Make sure all wrapper functions are at the beginning102  // of the module.103  auto moduleBegin = moduleOp.getBody()->begin();104  for (auto func : newFuncs)105    func->moveBefore(moduleOp.getBody(), moduleBegin);106}107