82 lines · cpp
1//===-- Main.cpp - generate main runtime API calls --------------*- C++ -*-===//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 "flang/Optimizer/Builder/Runtime/Main.h"10#include "flang/Lower/EnvironmentDefault.h"11#include "flang/Optimizer/Builder/BoxValue.h"12#include "flang/Optimizer/Builder/FIRBuilder.h"13#include "flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h"14#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"15#include "flang/Optimizer/Dialect/FIROps.h"16#include "flang/Optimizer/Dialect/FIRType.h"17#include "flang/Optimizer/Dialect/MIF/MIFOps.h"18#include "flang/Runtime/CUDA/init.h"19#include "flang/Runtime/main.h"20#include "flang/Runtime/stop.h"21 22using namespace Fortran::runtime;23 24/// Create a `int main(...)` that calls the Fortran entry point25void fir::runtime::genMain(26 fir::FirOpBuilder &builder, mlir::Location loc,27 const std::vector<Fortran::lower::EnvironmentDefault> &defs, bool initCuda,28 bool initCoarrayEnv) {29 auto *context = builder.getContext();30 auto argcTy = builder.getDefaultIntegerType();31 auto ptrTy = mlir::LLVM::LLVMPointerType::get(context);32 33 // void ProgramStart(int argc, char** argv, char** envp,34 // _QQEnvironmentDefaults* env)35 auto startFn = builder.createFunction(36 loc, RTNAME_STRING(ProgramStart),37 mlir::FunctionType::get(context, {argcTy, ptrTy, ptrTy, ptrTy}, {}));38 // void ProgramStop()39 auto stopFn =40 builder.createFunction(loc, RTNAME_STRING(ProgramEndStatement),41 mlir::FunctionType::get(context, {}, {}));42 43 // int main(int argc, char** argv, char** envp)44 auto mainFn = builder.createFunction(45 loc, "main",46 mlir::FunctionType::get(context, {argcTy, ptrTy, ptrTy}, argcTy));47 // void _QQmain()48 auto qqMainFn = builder.createFunction(49 loc, "_QQmain", mlir::FunctionType::get(context, {}, {}));50 51 mainFn.setPublic();52 53 auto *block = mainFn.addEntryBlock();54 mlir::OpBuilder::InsertionGuard insertGuard(builder);55 builder.setInsertionPointToStart(block);56 57 // Create the list of any environment defaults for the runtime to set. The58 // runtime default list is only created if there is a main program to ensure59 // it only happens once and to provide consistent results if multiple files60 // are compiled separately.61 auto env = fir::runtime::genEnvironmentDefaults(builder, loc, defs);62 63 llvm::SmallVector<mlir::Value, 4> args(block->getArguments());64 args.push_back(env);65 66 fir::CallOp::create(builder, loc, startFn, args);67 68 if (initCuda) {69 auto initFn = builder.createFunction(70 loc, RTNAME_STRING(CUFInit), mlir::FunctionType::get(context, {}, {}));71 fir::CallOp::create(builder, loc, initFn);72 }73 if (initCoarrayEnv)74 mif::InitOp::create(builder, loc);75 76 fir::CallOp::create(builder, loc, qqMainFn);77 fir::CallOp::create(builder, loc, stopFn);78 79 mlir::Value ret = builder.createIntegerConstant(loc, argcTy, 0);80 mlir::func::ReturnOp::create(builder, loc, ret);81}82