xref: /llvm-project/flang/lib/Optimizer/Builder/Runtime/Main.cpp (revision ab1ee912be95a864827aadd33175bfeec026f000)
18d538666SDavid Truby //===-- Main.cpp - generate main runtime API calls --------------*- C++ -*-===//
28d538666SDavid Truby //
38d538666SDavid Truby // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
48d538666SDavid Truby // See https://llvm.org/LICENSE.txt for license information.
58d538666SDavid Truby // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
68d538666SDavid Truby //
78d538666SDavid Truby //===----------------------------------------------------------------------===//
88d538666SDavid Truby 
98d538666SDavid Truby #include "flang/Optimizer/Builder/Runtime/Main.h"
10ecec1311SDavid Truby #include "flang/Lower/EnvironmentDefault.h"
118d538666SDavid Truby #include "flang/Optimizer/Builder/BoxValue.h"
128d538666SDavid Truby #include "flang/Optimizer/Builder/FIRBuilder.h"
13ecec1311SDavid Truby #include "flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h"
148d538666SDavid Truby #include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
158d538666SDavid Truby #include "flang/Optimizer/Dialect/FIROps.h"
168d538666SDavid Truby #include "flang/Optimizer/Dialect/FIRType.h"
17*ab1ee912SValentin Clement (バレンタイン クレメン) #include "flang/Runtime/CUDA/init.h"
188d538666SDavid Truby #include "flang/Runtime/main.h"
198d538666SDavid Truby #include "flang/Runtime/stop.h"
208d538666SDavid Truby 
218d538666SDavid Truby using namespace Fortran::runtime;
228d538666SDavid Truby 
238d538666SDavid Truby /// Create a `int main(...)` that calls the Fortran entry point
24ecec1311SDavid Truby void fir::runtime::genMain(
25ecec1311SDavid Truby     fir::FirOpBuilder &builder, mlir::Location loc,
26654b7632SValentin Clement (バレンタイン クレメン)     const std::vector<Fortran::lower::EnvironmentDefault> &defs,
27654b7632SValentin Clement (バレンタイン クレメン)     bool initCuda) {
288d538666SDavid Truby   auto *context = builder.getContext();
298d538666SDavid Truby   auto argcTy = builder.getDefaultIntegerType();
308d538666SDavid Truby   auto ptrTy = mlir::LLVM::LLVMPointerType::get(context);
318d538666SDavid Truby 
328d538666SDavid Truby   // void ProgramStart(int argc, char** argv, char** envp,
338d538666SDavid Truby   //                   _QQEnvironmentDefaults* env)
348d538666SDavid Truby   auto startFn = builder.createFunction(
358d538666SDavid Truby       loc, RTNAME_STRING(ProgramStart),
368d538666SDavid Truby       mlir::FunctionType::get(context, {argcTy, ptrTy, ptrTy, ptrTy}, {}));
378d538666SDavid Truby   // void ProgramStop()
388d538666SDavid Truby   auto stopFn =
398d538666SDavid Truby       builder.createFunction(loc, RTNAME_STRING(ProgramEndStatement),
408d538666SDavid Truby                              mlir::FunctionType::get(context, {}, {}));
418d538666SDavid Truby 
428d538666SDavid Truby   // int main(int argc, char** argv, char** envp)
438d538666SDavid Truby   auto mainFn = builder.createFunction(
448d538666SDavid Truby       loc, "main",
458d538666SDavid Truby       mlir::FunctionType::get(context, {argcTy, ptrTy, ptrTy}, argcTy));
468d538666SDavid Truby   // void _QQmain()
478d538666SDavid Truby   auto qqMainFn = builder.createFunction(
488d538666SDavid Truby       loc, "_QQmain", mlir::FunctionType::get(context, {}, {}));
498d538666SDavid Truby 
508d538666SDavid Truby   mainFn.setPublic();
518d538666SDavid Truby 
528d538666SDavid Truby   auto *block = mainFn.addEntryBlock();
538d538666SDavid Truby   mlir::OpBuilder::InsertionGuard insertGuard(builder);
548d538666SDavid Truby   builder.setInsertionPointToStart(block);
558d538666SDavid Truby 
56ecec1311SDavid Truby   // Create the list of any environment defaults for the runtime to set. The
57ecec1311SDavid Truby   // runtime default list is only created if there is a main program to ensure
58ecec1311SDavid Truby   // it only happens once and to provide consistent results if multiple files
59ecec1311SDavid Truby   // are compiled separately.
60ecec1311SDavid Truby   auto env = fir::runtime::genEnvironmentDefaults(builder, loc, defs);
61ecec1311SDavid Truby 
628d538666SDavid Truby   llvm::SmallVector<mlir::Value, 4> args(block->getArguments());
63ecec1311SDavid Truby   args.push_back(env);
648d538666SDavid Truby 
658d538666SDavid Truby   builder.create<fir::CallOp>(loc, startFn, args);
66654b7632SValentin Clement (バレンタイン クレメン) 
67654b7632SValentin Clement (バレンタイン クレメン)   if (initCuda) {
68654b7632SValentin Clement (バレンタイン クレメン)     auto initFn = builder.createFunction(
69654b7632SValentin Clement (バレンタイン クレメン)         loc, RTNAME_STRING(CUFInit), mlir::FunctionType::get(context, {}, {}));
70654b7632SValentin Clement (バレンタイン クレメン)     builder.create<fir::CallOp>(loc, initFn);
71654b7632SValentin Clement (バレンタイン クレメン)   }
72654b7632SValentin Clement (バレンタイン クレメン) 
738d538666SDavid Truby   builder.create<fir::CallOp>(loc, qqMainFn);
748d538666SDavid Truby   builder.create<fir::CallOp>(loc, stopFn);
758d538666SDavid Truby 
768d538666SDavid Truby   mlir::Value ret = builder.createIntegerConstant(loc, argcTy, 0);
778d538666SDavid Truby   builder.create<mlir::func::ReturnOp>(loc, ret);
788d538666SDavid Truby }
79