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