[flang] Generate main only when a Fortran program statement is present (#89938)

This patch changes the behaviour for flang to only create and link to a
`main` entry point when the Fortran code has a program statement in it.

This means that flang-new can be used to link even when the program is
a mixed C/Fortran code with `main` present in C and no entry point
present in Fortran.

This also removes the `-fno-fortran-main` flag as this no longer has any
functionality.
This commit is contained in:
David Truby 2024-04-29 14:16:25 +01:00 committed by GitHub
parent de6b2b9dbf
commit 8d5386669e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 287 additions and 226 deletions

View File

@ -6589,12 +6589,6 @@ def J : JoinedOrSeparate<["-"], "J">,
Group<gfortran_Group>,
Alias<module_dir>;
let Visibility = [FlangOption] in {
def no_fortran_main : Flag<["-"], "fno-fortran-main">,
Visibility<[FlangOption]>, Group<f_Group>,
HelpText<"Do not include Fortran_main.a (provided by Flang) when linking">;
} // let Visibility = [ FlangOption ]
//===----------------------------------------------------------------------===//
// FC1 Options
//===----------------------------------------------------------------------===//

View File

@ -1191,118 +1191,10 @@ bool tools::addOpenMPRuntime(const Compilation &C, ArgStringList &CmdArgs,
return true;
}
/// Determines if --whole-archive is active in the list of arguments.
static bool isWholeArchivePresent(const ArgList &Args) {
bool WholeArchiveActive = false;
for (auto *Arg : Args.filtered(options::OPT_Wl_COMMA)) {
if (Arg) {
for (StringRef ArgValue : Arg->getValues()) {
if (ArgValue == "--whole-archive")
WholeArchiveActive = true;
if (ArgValue == "--no-whole-archive")
WholeArchiveActive = false;
}
}
}
return WholeArchiveActive;
}
/// Determine if driver is invoked to create a shared object library (-static)
static bool isSharedLinkage(const ArgList &Args) {
return Args.hasArg(options::OPT_shared);
}
/// Determine if driver is invoked to create a static object library (-shared)
static bool isStaticLinkage(const ArgList &Args) {
return Args.hasArg(options::OPT_static);
}
/// Add Fortran runtime libs for MSVC
static void addFortranRuntimeLibsMSVC(const ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) {
unsigned RTOptionID = options::OPT__SLASH_MT;
if (auto *rtl = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) {
RTOptionID = llvm::StringSwitch<unsigned>(rtl->getValue())
.Case("static", options::OPT__SLASH_MT)
.Case("static_dbg", options::OPT__SLASH_MTd)
.Case("dll", options::OPT__SLASH_MD)
.Case("dll_dbg", options::OPT__SLASH_MDd)
.Default(options::OPT__SLASH_MT);
}
switch (RTOptionID) {
case options::OPT__SLASH_MT:
CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.static.lib");
break;
case options::OPT__SLASH_MTd:
CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.static_dbg.lib");
break;
case options::OPT__SLASH_MD:
CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.dynamic.lib");
break;
case options::OPT__SLASH_MDd:
CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.dynamic_dbg.lib");
break;
}
}
// Add FortranMain runtime lib
static void addFortranMain(const ToolChain &TC, const ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) {
// 0. Shared-library linkage
// If we are attempting to link a library, we should not add
// -lFortran_main.a to the link line, as the `main` symbol is not
// required for a library and should also be provided by one of
// the translation units of the code that this shared library
// will be linked against eventually.
if (isSharedLinkage(Args) || isStaticLinkage(Args)) {
return;
}
// 1. MSVC
if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
addFortranRuntimeLibsMSVC(Args, CmdArgs);
return;
}
// 2. GNU and similar
const Driver &D = TC.getDriver();
const char *FortranMainLinkFlag = "-lFortran_main";
// Warn if the user added `-lFortran_main` - this library is an implementation
// detail of Flang and should be handled automaticaly by the driver.
for (const char *arg : CmdArgs) {
if (strncmp(arg, FortranMainLinkFlag, strlen(FortranMainLinkFlag)) == 0)
D.Diag(diag::warn_drv_deprecated_custom)
<< FortranMainLinkFlag
<< "see the Flang driver documentation for correct usage";
}
// The --whole-archive option needs to be part of the link line to make
// sure that the main() function from Fortran_main.a is pulled in by the
// linker. However, it shouldn't be used if it's already active.
// TODO: Find an equivalent of `--whole-archive` for Darwin and AIX.
if (!isWholeArchivePresent(Args) && !TC.getTriple().isMacOSX() &&
!TC.getTriple().isOSAIX()) {
CmdArgs.push_back("--whole-archive");
CmdArgs.push_back(FortranMainLinkFlag);
CmdArgs.push_back("--no-whole-archive");
return;
}
CmdArgs.push_back(FortranMainLinkFlag);
}
/// Add Fortran runtime libs
void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) {
// 1. Link FortranMain
// FortranMain depends on FortranRuntime, so needs to be listed first. If
// -fno-fortran-main has been passed, skip linking Fortran_main.a
if (!Args.hasArg(options::OPT_no_fortran_main))
addFortranMain(TC, Args, CmdArgs);
// 2. Link FortranRuntime and FortranDecimal
// Link FortranRuntime and FortranDecimal
// These are handled earlier on Windows by telling the frontend driver to
// add the correct libraries to link against as dependents in the object
// file.

View File

@ -282,7 +282,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args,
assert(TC.getTriple().isKnownWindowsMSVCEnvironment() &&
"can only add VS runtime library on Windows!");
// if -fno-fortran-main has been passed, skip linking Fortran_main.a
bool LinkFortranMain = !Args.hasArg(options::OPT_no_fortran_main);
if (TC.getTriple().isKnownWindowsMSVCEnvironment()) {
CmdArgs.push_back(Args.MakeArgString(
"--dependent-lib=" + TC.getCompilerRTBasename(Args, "builtins")));
@ -300,8 +299,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args,
case options::OPT__SLASH_MT:
CmdArgs.push_back("-D_MT");
CmdArgs.push_back("--dependent-lib=libcmt");
if (LinkFortranMain)
CmdArgs.push_back("--dependent-lib=Fortran_main.static.lib");
CmdArgs.push_back("--dependent-lib=FortranRuntime.static.lib");
CmdArgs.push_back("--dependent-lib=FortranDecimal.static.lib");
break;
@ -309,8 +306,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args,
CmdArgs.push_back("-D_MT");
CmdArgs.push_back("-D_DEBUG");
CmdArgs.push_back("--dependent-lib=libcmtd");
if (LinkFortranMain)
CmdArgs.push_back("--dependent-lib=Fortran_main.static_dbg.lib");
CmdArgs.push_back("--dependent-lib=FortranRuntime.static_dbg.lib");
CmdArgs.push_back("--dependent-lib=FortranDecimal.static_dbg.lib");
break;
@ -318,8 +313,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args,
CmdArgs.push_back("-D_MT");
CmdArgs.push_back("-D_DLL");
CmdArgs.push_back("--dependent-lib=msvcrt");
if (LinkFortranMain)
CmdArgs.push_back("--dependent-lib=Fortran_main.dynamic.lib");
CmdArgs.push_back("--dependent-lib=FortranRuntime.dynamic.lib");
CmdArgs.push_back("--dependent-lib=FortranDecimal.dynamic.lib");
break;
@ -328,8 +321,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args,
CmdArgs.push_back("-D_DEBUG");
CmdArgs.push_back("-D_DLL");
CmdArgs.push_back("--dependent-lib=msvcrtd");
if (LinkFortranMain)
CmdArgs.push_back("--dependent-lib=Fortran_main.dynamic_dbg.lib");
CmdArgs.push_back("--dependent-lib=FortranRuntime.dynamic_dbg.lib");
CmdArgs.push_back("--dependent-lib=FortranDecimal.dynamic_dbg.lib");
break;

View File

@ -179,46 +179,20 @@ like this:
```
$ flang -v -o example example.o
"/usr/bin/ld" [...] example.o [...] "--whole-archive" "-lFortran_main"
"--no-whole-archive" "-lFortranRuntime" "-lFortranDecimal" [...]
"/usr/bin/ld" [...] example.o [...] "-lFortranRuntime" "-lFortranDecimal" [...]
```
The automatically added libraries are:
* `Fortran_main`: Provides the main entry point `main` that then invokes
`_QQmain` with the Fortran program unit. This library has a dependency to
the `FortranRuntime` library.
* `FortranRuntime`: Provides most of the Flang runtime library.
* `FortranDecimal`: Provides operations for decimal numbers.
The default is that, when using Flang as the linker, one of the Fortran
translation units provides the program unit and therefore it is assumed that
Fortran is the main code part (calling into C/C++ routines via `BIND (C)`
interfaces). When composing the linker commandline, Flang uses
`--whole-archive` and `--no-whole-archive` (Windows: `/WHOLEARCHIVE:`,
Darwin & AIX: *not implemented yet*) to make sure that all for `Fortran_main`
is processed by the linker. This is done to issue a proper error message when
multiple definitions of `main` occur. This happens, for instance, when linking
a code that has a Fortran program unit with a C/C++ code that also defines a
`main` function. A user may be required to explicitly provide the C++ runtime
libraries at link time (e.g., via `-lstdc++` for STL)
If the code is C/C++ based and invokes Fortran routines, one can either use Clang
or Flang as the linker driver. If Clang is used, it will automatically all
required runtime libraries needed by C++ (e.g., for STL) to the linker invocation.
In this case, one has to explicitly provide the Fortran runtime libraries
`FortranRuntime` and/or `FortranDecimal`. An alternative is to use Flang to link
and use the `-fno-fortran-main` flag. This flag removes
`Fortran_main` from the linker stage and hence requires one of the C/C++
translation units to provide a definition of the `main` function. In this case,
it may be required to explicitly supply C++ runtime libraries as mentioned above.
When creating shared or static libraries using Flang with `-shared` or `-static`
flag, Fortran_main is automatically removed from the linker stage (i.e.,
`-fno-fortran-main` is on by default). It is assumed that when creating a
static or shared library, the generated library does not need a `main`
function, as a final link stage will occur that will provide the `Fortran_main`
library when creating the final executable.
`FortranRuntime` and/or `FortranDecimal`. An alternative is to use Flang to link.
In this case, it may be required to explicitly supply C++ runtime libraries.
On Darwin, the logical root where the system libraries are located (sysroot)
must be specified. This can be done with the CMake build flag `DEFAULT_SYSROOT`

View File

@ -22,6 +22,7 @@
namespace fir {
class FirOpBuilder;
class GlobalOp;
} // namespace fir
namespace mlir {
@ -37,7 +38,7 @@ namespace fir::runtime {
/// Create the list of environment variable defaults for the runtime to set. The
/// form of the generated list is defined in the runtime header file
/// environment-default-list.h
void genEnvironmentDefaults(
fir::GlobalOp genEnvironmentDefaults(
fir::FirOpBuilder &builder, mlir::Location loc,
const std::vector<Fortran::lower::EnvironmentDefault> &envDefaults);

View File

@ -0,0 +1,28 @@
//===-- Main.h - generate main runtime API calls ----------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef FORTRAN_OPTIMIZER_BUILDER_RUNTIME_MAIN_H
#define FORTRAN_OPTIMIZER_BUILDER_RUNTIME_MAIN_H
namespace mlir {
class Location;
} // namespace mlir
namespace fir {
class FirOpBuilder;
class GlobalOp;
} // namespace fir
namespace fir::runtime {
void genMain(fir::FirOpBuilder &builder, mlir::Location loc,
fir::GlobalOp &env);
}
#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_MAIN_H

View File

@ -36,6 +36,7 @@
#include "flang/Optimizer/Builder/Runtime/Character.h"
#include "flang/Optimizer/Builder/Runtime/Derived.h"
#include "flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h"
#include "flang/Optimizer/Builder/Runtime/Main.h"
#include "flang/Optimizer/Builder/Runtime/Ragged.h"
#include "flang/Optimizer/Builder/Runtime/Stop.h"
#include "flang/Optimizer/Builder/Todo.h"
@ -359,8 +360,10 @@ public:
// not need to be generated even if no defaults are specified.
// However, generating main or changing when the runtime reads
// environment variables is required to do so.
fir::runtime::genEnvironmentDefaults(*builder, toLocation(),
bridge.getEnvironmentDefaults());
auto env = fir::runtime::genEnvironmentDefaults(
*builder, toLocation(), bridge.getEnvironmentDefaults());
fir::runtime::genMain(*builder, toLocation(), env);
});
finalizeOpenACCLowering();

View File

@ -23,6 +23,7 @@ add_flang_library(FIRBuilder
Runtime/Execute.cpp
Runtime/Inquiry.cpp
Runtime/Intrinsics.cpp
Runtime/Main.cpp
Runtime/Numeric.cpp
Runtime/Pointer.cpp
Runtime/Ragged.cpp

View File

@ -13,7 +13,7 @@
#include "flang/Optimizer/Support/InternalNames.h"
#include "llvm/ADT/ArrayRef.h"
void fir::runtime::genEnvironmentDefaults(
fir::GlobalOp fir::runtime::genEnvironmentDefaults(
fir::FirOpBuilder &builder, mlir::Location loc,
const std::vector<Fortran::lower::EnvironmentDefault> &envDefaults) {
std::string envDefaultListPtrName =
@ -34,14 +34,13 @@ void fir::runtime::genEnvironmentDefaults(
// If no defaults were specified, initialize with a null pointer.
if (envDefaults.empty()) {
builder.createGlobalConstant(
return builder.createGlobalConstant(
loc, envDefaultListRefTy, envDefaultListPtrName,
[&](fir::FirOpBuilder &builder) {
mlir::Value nullVal =
builder.createNullConstant(loc, envDefaultListRefTy);
builder.create<fir::HasValueOp>(loc, nullVal);
});
return;
}
// Create the Item list.
@ -99,7 +98,7 @@ void fir::runtime::genEnvironmentDefaults(
envDefaultListBuilder, linkOnce);
// Define the pointer to the list used by the runtime.
builder.createGlobalConstant(
return builder.createGlobalConstant(
loc, envDefaultListRefTy, envDefaultListPtrName,
[&](fir::FirOpBuilder &builder) {
mlir::Value addr = builder.create<fir::AddrOfOp>(

View File

@ -0,0 +1,62 @@
//===-- Main.cpp - generate main runtime API calls --------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "flang/Optimizer/Builder/Runtime/Main.h"
#include "flang/Optimizer/Builder/BoxValue.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
#include "flang/Optimizer/Dialect/FIROps.h"
#include "flang/Optimizer/Dialect/FIRType.h"
#include "flang/Runtime/main.h"
#include "flang/Runtime/stop.h"
using namespace Fortran::runtime;
/// Create a `int main(...)` that calls the Fortran entry point
void fir::runtime::genMain(fir::FirOpBuilder &builder, mlir::Location loc,
fir::GlobalOp &env) {
auto *context = builder.getContext();
auto argcTy = builder.getDefaultIntegerType();
auto ptrTy = mlir::LLVM::LLVMPointerType::get(context);
// void ProgramStart(int argc, char** argv, char** envp,
// _QQEnvironmentDefaults* env)
auto startFn = builder.createFunction(
loc, RTNAME_STRING(ProgramStart),
mlir::FunctionType::get(context, {argcTy, ptrTy, ptrTy, ptrTy}, {}));
// void ProgramStop()
auto stopFn =
builder.createFunction(loc, RTNAME_STRING(ProgramEndStatement),
mlir::FunctionType::get(context, {}, {}));
// int main(int argc, char** argv, char** envp)
auto mainFn = builder.createFunction(
loc, "main",
mlir::FunctionType::get(context, {argcTy, ptrTy, ptrTy}, argcTy));
// void _QQmain()
auto qqMainFn = builder.createFunction(
loc, "_QQmain", mlir::FunctionType::get(context, {}, {}));
mainFn.setPublic();
auto *block = mainFn.addEntryBlock();
mlir::OpBuilder::InsertionGuard insertGuard(builder);
builder.setInsertionPointToStart(block);
llvm::SmallVector<mlir::Value, 4> args(block->getArguments());
auto envAddr =
builder.create<fir::AddrOfOp>(loc, env.getType(), env.getSymbol());
args.push_back(envAddr);
builder.create<fir::CallOp>(loc, startFn, args);
builder.create<fir::CallOp>(loc, qqMainFn);
builder.create<fir::CallOp>(loc, stopFn);
mlir::Value ret = builder.createIntegerConstant(loc, argcTy, 0);
builder.create<mlir::func::ReturnOp>(loc, ret);
}

View File

@ -103,7 +103,6 @@ append(${NO_LTO_FLAGS} CMAKE_CXX_FLAGS)
add_definitions(-U_GLIBCXX_ASSERTIONS)
add_definitions(-U_LIBCPP_ENABLE_ASSERTIONS)
add_subdirectory(FortranMain)
add_subdirectory(Float128Math)
set(sources

View File

@ -1,23 +0,0 @@
add_flang_library(Fortran_main STATIC INSTALL_WITH_TOOLCHAIN
Fortran_main.c
)
if (DEFINED MSVC)
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded)
add_flang_library(Fortran_main.static STATIC INSTALL_WITH_TOOLCHAIN
Fortran_main.c
)
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL)
add_flang_library(Fortran_main.dynamic STATIC INSTALL_WITH_TOOLCHAIN
Fortran_main.c
)
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDebug)
add_flang_library(Fortran_main.static_dbg STATIC INSTALL_WITH_TOOLCHAIN
Fortran_main.c
)
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDebugDLL)
add_flang_library(Fortran_main.dynamic_dbg STATIC INSTALL_WITH_TOOLCHAIN
Fortran_main.c
)
add_dependencies(Fortran_main Fortran_main.static Fortran_main.dynamic
Fortran_main.static_dbg Fortran_main.dynamic_dbg)
endif()

View File

@ -1,23 +0,0 @@
//===-- runtime/FortranMain/Fortran_main.c --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "flang/Runtime/main.h"
#include "flang/Runtime/stop.h"
/* main entry into PROGRAM */
void _QQmain(void);
extern const struct EnvironmentDefaultList *_QQEnvironmentDefaults;
/* C main stub */
int main(int argc, const char *argv[], const char *envp[]) {
RTNAME(ProgramStart)(argc, argv, envp, _QQEnvironmentDefaults);
_QQmain();
RTNAME(ProgramEndStatement)();
return 0;
}

View File

@ -62,7 +62,6 @@ set(FLANG_TEST_DEPENDS
llvm-readobj
split-file
FortranRuntime
Fortran_main
FortranDecimal
)
if (LLVM_ENABLE_PLUGINS AND NOT WIN32)

View File

@ -0,0 +1,172 @@
!--------------------------
! FLANG DRIVER (flang-new)
!--------------------------
! RUN: %flang --help-hidden 2>&1 | FileCheck %s
! RUN: not %flang -help-hidden 2>&1 | FileCheck %s --check-prefix=ERROR-FLANG
!----------------------------------------
! FLANG FRONTEND DRIVER (flang-new -fc1)
!----------------------------------------
! RUN: not %flang_fc1 --help-hidden 2>&1 | FileCheck %s --check-prefix=ERROR-FLANG-FC1
! RUN: not %flang_fc1 -help-hidden 2>&1 | FileCheck %s --check-prefix=ERROR-FLANG-FC1
! CHECK:USAGE: flang-new
! CHECK-EMPTY:
! CHECK-NEXT: DRIVER OPTIONS:
! CHECK-NEXT: --driver-mode=<value> Set the driver mode to either 'gcc', 'g++', 'cpp', 'cl' or 'flang'
! CHECK-EMPTY:
! CHECK-NEXT:OPTIONS:
! CHECK-NEXT: -### Print (but do not run) the commands to run for this compilation
! CHECK-NEXT: -ccc-print-phases Dump list of actions to perform
! CHECK-NEXT: -cpp Enable predefined and command line preprocessor macros
! CHECK-NEXT: -c Only run preprocess, compile, and assemble steps
! CHECK-NEXT: -dM Print macro definitions in -E mode instead of normal output
! CHECK-NEXT: -dumpmachine Display the compiler's target processor
! CHECK-NEXT: -dumpversion Display the version of the compiler
! CHECK-NEXT: -D <macro>=<value> Define <macro> to <value> (or 1 if <value> omitted)
! CHECK-NEXT: -emit-llvm Use the LLVM representation for assembler and object files
! CHECK-NEXT: -E Only run the preprocessor
! CHECK-NEXT: -falternative-parameter-statement
! CHECK-NEXT: Enable the old style PARAMETER statement
! CHECK-NEXT: -fapprox-func Allow certain math function calls to be replaced with an approximately equivalent calculation
! CHECK-NEXT: -fbackslash Specify that backslash in string introduces an escape character
! CHECK-NEXT: -fcolor-diagnostics Enable colors in diagnostics
! CHECK-NEXT: -fconvert=<value> Set endian conversion of data for unformatted files
! CHECK-NEXT: -fdefault-double-8 Set the default double precision kind to an 8 byte wide type
! CHECK-NEXT: -fdefault-integer-8 Set the default integer and logical kind to an 8 byte wide type
! CHECK-NEXT: -fdefault-real-8 Set the default real kind to an 8 byte wide type
! CHECK-NEXT: -ffast-math Allow aggressive, lossy floating-point optimizations
! CHECK-NEXT: -ffixed-form Process source files in fixed form
! CHECK-NEXT: -ffixed-line-length=<value>
! CHECK-NEXT: Use <value> as character line width in fixed mode
! CHECK-NEXT: -ffp-contract=<value> Form fused FP ops (e.g. FMAs)
! CHECK-NEXT: -ffree-form Process source files in free form
! CHECK-NEXT: -fhonor-infinities Specify that floating-point optimizations are not allowed that assume arguments and results are not +-inf.
! CHECK-NEXT: -fhonor-nans Specify that floating-point optimizations are not allowed that assume arguments and results are not NANs.
! CHECK-NEXT: -fimplicit-none No implicit typing allowed unless overridden by IMPLICIT statements
! CHECK-NEXT: -finput-charset=<value> Specify the default character set for source files
! CHECK-NEXT: -fintegrated-as Enable the integrated assembler
! CHECK-NEXT: -fintrinsic-modules-path <dir>
! CHECK-NEXT: Specify where to find the compiled intrinsic modules
! CHECK-NEXT: -flang-deprecated-no-hlfir
! CHECK-NEXT: Do not use HLFIR lowering (deprecated)
! CHECK-NEXT: -flang-experimental-hlfir
! CHECK-NEXT: Use HLFIR lowering (experimental)
! CHECK-NEXT: -flarge-sizes Use INTEGER(KIND=8) for the result type in size-related intrinsics
! CHECK-NEXT: -flogical-abbreviations Enable logical abbreviations
! CHECK-NEXT: -flto=auto Enable LTO in 'full' mode
! CHECK-NEXT: -flto=jobserver Enable LTO in 'full' mode
! CHECK-NEXT: -flto=<value> Set LTO mode
! CHECK-NEXT: -flto Enable LTO in 'full' mode
! CHECK-NEXT: -fms-runtime-lib=<value>
! CHECK-NEXT: Select Windows run-time library
! CHECK-NEXT: -fno-automatic Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE
! CHECK-NEXT: -fno-color-diagnostics Disable colors in diagnostics
! CHECK-NEXT: -fno-integrated-as Disable the integrated assembler
! CHECK-NEXT: -fno-lto Disable LTO mode (default)
! CHECK-NEXT: -fno-ppc-native-vector-element-order
! CHECK-NEXT: Specifies PowerPC non-native vector element order
! CHECK-NEXT: -fno-rtlib-add-rpath Do not add -rpath with architecture-specific resource directory to the linker flags. When --hip-link is specified, do not add -rpath with HIP runtime library directory to the linker flags
! CHECK-NEXT: -fno-signed-zeros Allow optimizations that ignore the sign of floating point zeros
! CHECK-NEXT: -fno-stack-arrays Allocate array temporaries on the heap (default)
! CHECK-NEXT: -fno-version-loops-for-stride
! CHECK-NEXT: Do not create unit-strided loops (default)
! CHECK-NEXT: -fomit-frame-pointer Omit the frame pointer from functions that don't need it. Some stack unwinding cases, such as profilers and sanitizers, may prefer specifying -fno-omit-frame-pointer. On many targets, -O1 and higher omit the frame pointer by default. -m[no-]omit-leaf-frame-pointer takes precedence for leaf functions
! CHECK-NEXT: -fopenacc Enable OpenACC
! CHECK-NEXT: -fopenmp-assume-no-nested-parallelism
! CHECK-NEXT: Assert no nested parallel regions in the GPU
! CHECK-NEXT: -fopenmp-assume-no-thread-state
! CHECK-NEXT: Assert no thread in a parallel region modifies an ICV
! CHECK-NEXT: -fopenmp-target-debug Enable debugging in the OpenMP offloading device RTL
! CHECK-NEXT: -fopenmp-targets=<value>
! CHECK-NEXT: Specify comma-separated list of triples OpenMP offloading targets to be supported
! CHECK-NEXT: -fopenmp-version=<value>
! CHECK-NEXT: Set OpenMP version (e.g. 45 for OpenMP 4.5, 51 for OpenMP 5.1). Default value is 11 for Flang
! CHECK-NEXT: -fopenmp Parse OpenMP pragmas and generate parallel code.
! CHECK-NEXT: -foptimization-record-file=<file>
! CHECK-NEXT: Specify the output name of the file containing the optimization remarks. Implies -fsave-optimization-record. On Darwin platforms, this cannot be used with multiple -arch <arch> options.
! CHECK-NEXT: -foptimization-record-passes=<regex>
! CHECK-NEXT: Only include passes which match a specified regular expression in the generated optimization record (by default, include all passes)
! CHECK-NEXT: -fpass-plugin=<dsopath> Load pass plugin from a dynamic shared object file (only with new pass manager).
! CHECK-NEXT: -fppc-native-vector-element-order
! CHECK-NEXT: Specifies PowerPC native vector element order (default)
! CHECK-NEXT: -freciprocal-math Allow division operations to be reassociated
! CHECK-NEXT: -fropi Generate read-only position independent code (ARM only)
! CHECK-NEXT: -frtlib-add-rpath Add -rpath with architecture-specific resource directory to the linker flags. When --hip-link is specified, also add -rpath with HIP runtime library directory to the linker flags
! CHECK-NEXT: -frwpi Generate read-write position independent code (ARM only)
! CHECK-NEXT: -fsave-optimization-record=<format>
! CHECK-NEXT: Generate an optimization record file in a specific format
! CHECK-NEXT: -fsave-optimization-record
! CHECK-NEXT: Generate a YAML optimization record file
! CHECK-NEXT: -fstack-arrays Attempt to allocate array temporaries on the stack, no matter their size
! CHECK-NEXT: -fsyntax-only Run the preprocessor, parser and semantic analysis stages
! CHECK-NEXT: -funderscoring Appends one trailing underscore to external names
! CHECK-NEXT: -fveclib=<value> Use the given vector functions library
! CHECK-NEXT: -fversion-loops-for-stride
! CHECK-NEXT: Create unit-strided versions of loops
! CHECK-NEXT: -fxor-operator Enable .XOR. as a synonym of .NEQV.
! CHECK-NEXT: --gcc-install-dir=<value>
! CHECK-NEXT: Use GCC installation in the specified directory. The directory ends with path components like 'lib{,32,64}/gcc{,-cross}/$triple/$version'. Note: executables (e.g. ld) used by the compiler are not overridden by the selected GCC installation
! CHECK-NEXT: --gcc-toolchain=<value> Specify a directory where Flang can find 'lib{,32,64}/gcc{,-cross}/$triple/$version'. Flang will use the GCC installation with the largest version
! CHECK-NEXT: -gline-directives-only Emit debug line info directives only
! CHECK-NEXT: -gline-tables-only Emit debug line number tables only
! CHECK-NEXT: -gpulibc Link the LLVM C Library for GPUs
! CHECK-NEXT: -g Generate source-level debug information
! CHECK-NEXT: --help-hidden Display help for hidden options
! CHECK-NEXT: -help Display available options
! CHECK-NEXT: -isysroot <dir> Set the system root directory (usually /)
! CHECK-NEXT: -I <dir> Add directory to the end of the list of include search paths
! CHECK-NEXT: -L <dir> Add directory to library search path
! CHECK-NEXT: -march=<value> For a list of available architectures for the target use '-mcpu=help'
! CHECK-NEXT: -mcode-object-version=<value>
! CHECK-NEXT: Specify code object ABI version. Defaults to 5. (AMDGPU only)
! CHECK-NEXT: -mcpu=<value> For a list of available CPUs for the target use '-mcpu=help'
! CHECK-NEXT: -mllvm=<arg> Alias for -mllvm
! CHECK-NEXT: -mllvm <value> Additional arguments to forward to LLVM's option processing
! CHECK-NEXT: -mmlir <value> Additional arguments to forward to MLIR's option processing
! CHECK-NEXT: -mno-outline-atomics Don't generate local calls to out-of-line atomic operations
! CHECK-NEXT: -module-dir <dir> Put MODULE files in <dir>
! CHECK-NEXT: -moutline-atomics Generate local calls to out-of-line atomic operations
! CHECK-NEXT: -mrvv-vector-bits=<value>
! CHECK-NEXT: Specify the size in bits of an RVV vector register
! CHECK-NEXT: -msve-vector-bits=<value>
! CHECK-NEXT: Specify the size in bits of an SVE vector register. Defaults to the vector length agnostic value of "scalable". (AArch64 only)
! CHECK-NEXT: --no-offload-arch=<value>
! CHECK-NEXT: Remove CUDA/HIP offloading device architecture (e.g. sm_35, gfx906) from the list of devices to compile for. 'all' resets the list to its default value.
! CHECK-NEXT: -nocpp Disable predefined and command line preprocessor macros
! CHECK-NEXT: -nogpulib Do not link device library for CUDA/HIP device compilation
! CHECK-NEXT: --offload-arch=<value> Specify an offloading device architecture for CUDA, HIP, or OpenMP. (e.g. sm_35). If 'native' is used the compiler will detect locally installed architectures. For HIP offloading, the device architecture can be followed by target ID features delimited by a colon (e.g. gfx908:xnack+:sramecc-). May be specified more than once.
! CHECK-NEXT: --offload-device-only Only compile for the offloading device.
! CHECK-NEXT: --offload-host-device Compile for both the offloading host and device (default).
! CHECK-NEXT: --offload-host-only Only compile for the offloading host.
! CHECK-NEXT: -o <file> Write output to <file>
! CHECK-NEXT: -pedantic Warn on language extensions
! CHECK-NEXT: -print-effective-triple Print the effective target triple
! CHECK-NEXT: -print-target-triple Print the normalized target triple
! CHECK-NEXT: -pthread Support POSIX threads in generated code
! CHECK-NEXT: -P Disable linemarker output in -E mode
! CHECK-NEXT: -resource-dir <value> The directory which holds the compiler resource files
! CHECK-NEXT: --rocm-path=<value> ROCm installation path, used for finding and automatically linking required bitcode libraries.
! CHECK-NEXT: -Rpass-analysis=<value> Report transformation analysis from optimization passes whose name matches the given POSIX regular expression
! CHECK-NEXT: -Rpass-missed=<value> Report missed transformations by optimization passes whose name matches the given POSIX regular expression
! CHECK-NEXT: -Rpass=<value> Report transformations performed by optimization passes whose name matches the given POSIX regular expression
! CHECK-NEXT: -R<remark> Enable the specified remark
! CHECK-NEXT: -save-temps=<value> Save intermediate compilation results.
! CHECK-NEXT: -save-temps Alias for --save-temps=cwd
! CHECK-NEXT: -std=<value> Language standard to compile for
! CHECK-NEXT: -S Only run preprocess and compilation steps
! CHECK-NEXT: --target=<value> Generate code for the given target
! CHECK-NEXT: -U <macro> Undefine macro <macro>
! CHECK-NEXT: --version Print version information
! CHECK-NEXT: -v Show commands to run and use verbose output
! CHECK-NEXT: -Wl,<arg> Pass the comma separated arguments in <arg> to the linker
! CHECK-NEXT: -W<warning> Enable the specified warning
! CHECK-NEXT: -Xflang <arg> Pass <arg> to the flang compiler
! CHECK-NEXT: -x <language> Treat subsequent input files as having type <language>
! ERROR-FLANG: error: unknown argument '-help-hidden'; did you mean '--help-hidden'?
! Frontend driver -help-hidden is not supported
! ERROR-FLANG-FC1: error: unknown argument: '{{.*}}'

View File

@ -16,7 +16,6 @@
! GNU-LINKER-OPTIONS-SAME: "-shared"
! GNU-LINKER-OPTIONS-SAME: "-static"
! GNU-LINKER-OPTIONS-SAME: "-rpath" "/path/to/dir"
! GNU-LINKER-OPTIONS-NOT: "-lFortran_main.a"
! RDYNAMIC-LINKER-OPTION: "{{.*}}ld"
! RDYNAMIC-LINKER-OPTION-SAME: "-export-dynamic"
@ -25,4 +24,3 @@
! MSVC-LINKER-OPTIONS: "{{.*}}link{{(.exe)?}}"
! MSVC-LINKER-OPTIONS-SAME: "-dll"
! MSVC-LINKER-OPTIONS-SAME: "-rpath" "/path/to/dir"
! MSVC-LINKER-OPTIONS-NOT: "/WHOLEARCHIVE:Fortran_main"

View File

@ -19,6 +19,16 @@
! CHECK-NEXT: %[[VAL_0:.*]] = fir.zero_bits !fir.ref<tuple<i[[int_size]], !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
! CHECK-NEXT: fir.has_value %[[VAL_0]] : !fir.ref<tuple<i[[int_size]], !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
! CHECK-NEXT: }
! CHECK-NEXT: func.func private @_FortranAProgramStart(i32, !llvm.ptr, !llvm.ptr, !llvm.ptr)
! CHECK-NEXT: func.func private @_FortranAProgramEndStatement()
! CHECK-NEXT: func.func @main(%arg0: i32, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> i32 {
! CHECK-NEXT: %c0_i32 = arith.constant 0 : i32
! CHECK-NEXT: %0 = fir.address_of(@_QQEnvironmentDefaults) : !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
! CHECK-NEXT: ir.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %0) {{.*}} : (i32, !llvm.ptr, !llvm.ptr, !fir.ref<tuple<i32, !fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>)
! CHECK-NEXT: fir.call @_QQmain() fastmath<contract> : () -> ()
! CHECK-NEXT: fir.call @_FortranAProgramEndStatement() {{.*}} : () -> ()
! CHECK-NEXT: return %c0_i32 : i32
! CHECK-NEXT: }
! CHECK-NEXT: }
end program

View File

@ -11,7 +11,6 @@
! RUN: %flang -### --target=x86_64-unknown-dragonfly %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,UNIX,UNIX-F128%f128-lib
! RUN: %flang -### --target=x86_64-unknown-haiku %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,HAIKU,HAIKU-F128%f128-lib
! RUN: %flang -### --target=x86_64-windows-gnu %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,MINGW,MINGW-F128%f128-lib
! RUN: %flang -### --target=aarch64-unknown-linux-gnu %S/Inputs/hello.f90 -lFortran_main 2>&1 | FileCheck %s --check-prefixes=DEPRECATED
! NOTE: Clang's driver library, clangDriver, usually adds 'oldnames' on Windows,
! but it is not needed when compiling Fortran code and they might bring in
@ -29,7 +28,6 @@
! executable and may find the GNU linker from MinGW or Cygwin.
! UNIX-LABEL: "{{.*}}ld{{(\.exe)?}}"
! UNIX-SAME: "[[object_file]]"
! UNIX-SAME: "--whole-archive" "-lFortran_main" "--no-whole-archive"
! UNIX-F128NONE-NOT: FortranFloat128Math
! SOLARIS-F128NONE-NOT: FortranFloat128Math
! UNIX-F128LIBQUADMATH-SAME: "-lFortranFloat128Math" "--as-needed" "-lquadmath" "--no-as-needed"
@ -38,7 +36,6 @@
! DARWIN-LABEL: "{{.*}}ld{{(\.exe)?}}"
! DARWIN-SAME: "[[object_file]]"
! DARWIN-SAME: -lFortran_main
! DARWIN-F128NONE-NOT: FortranFloat128Math
! DARWIN-F128LIBQUADMATH-SAME: "-lFortranFloat128Math" "--as-needed" "-lquadmath" "--no-as-needed"
! DARWIN-SAME: -lFortranRuntime
@ -46,14 +43,12 @@
! HAIKU-LABEL: "{{.*}}ld{{(\.exe)?}}"
! HAIKU-SAME: "[[object_file]]"
! HAIKU-SAME: "--whole-archive" "-lFortran_main" "--no-whole-archive"
! HAIKU-F128NONE-NOT: FortranFloat128Math
! HAIKU-F128LIBQUADMATH-SAME: "-lFortranFloat128Math" "--as-needed" "-lquadmath" "--no-as-needed"
! HAIKU-SAME: "-lFortranRuntime" "-lFortranDecimal"
! MINGW-LABEL: "{{.*}}ld{{(\.exe)?}}"
! MINGW-SAME: "[[object_file]]"
! MINGW-SAME: -lFortran_main
! MINGW-F128NONE-NOT: FortranFloat128Math
! MINGW-F128LIBQUADMATH-SAME: "-lFortranFloat128Math" "--as-needed" "-lquadmath" "--no-as-needed"
! MINGW-SAME: -lFortranRuntime
@ -66,6 +61,3 @@
! MSVC-LABEL: link
! MSVC-SAME: /subsystem:console
! MSVC-SAME: "[[object_file]]"
! Check that we warn when using -lFortran_main
! DEPRECATED: warning: argument '-lFortran_main' is deprecated, see the Flang driver documentation for correct usage [-Wdeprecated]

View File

@ -7,7 +7,6 @@
! MSVC-SAME: --dependent-lib=clang_rt.builtins.lib
! MSVC-SAME: -D_MT
! MSVC-SAME: --dependent-lib=libcmt
! MSVC-SAME: --dependent-lib=Fortran_main.static.lib
! MSVC-SAME: --dependent-lib=FortranRuntime.static.lib
! MSVC-SAME: --dependent-lib=FortranDecimal.static.lib
@ -16,7 +15,6 @@
! MSVC-DEBUG-SAME: -D_MT
! MSVC-DEBUG-SAME: -D_DEBUG
! MSVC-DEBUG-SAME: --dependent-lib=libcmtd
! MSVC-DEBUG-SAME: --dependent-lib=Fortran_main.static_dbg.lib
! MSVC-DEBUG-SAME: --dependent-lib=FortranRuntime.static_dbg.lib
! MSVC-DEBUG-SAME: --dependent-lib=FortranDecimal.static_dbg.lib
@ -25,7 +23,6 @@
! MSVC-DLL-SAME: -D_MT
! MSVC-DLL-SAME: -D_DLL
! MSVC-DLL-SAME: --dependent-lib=msvcrt
! MSVC-DLL-SAME: --dependent-lib=Fortran_main.dynamic.lib
! MSVC-DLL-SAME: --dependent-lib=FortranRuntime.dynamic.lib
! MSVC-DLL-SAME: --dependent-lib=FortranDecimal.dynamic.lib
@ -35,6 +32,5 @@
! MSVC-DLL-DEBUG-SAME: -D_DEBUG
! MSVC-DLL-DEBUG-SAME: -D_DLL
! MSVC-DLL-DEBUG-SAME: --dependent-lib=msvcrtd
! MSVC-DLL-DEBUG-SAME: --dependent-lib=Fortran_main.dynamic_dbg.lib
! MSVC-DLL-DEBUG-SAME: --dependent-lib=FortranRuntime.dynamic_dbg.lib
! MSVC-DLL-DEBUG-SAME: --dependent-lib=FortranDecimal.dynamic_dbg.lib

View File

@ -4,8 +4,6 @@
! RUN: %flang -o %t -c %s
! RUN: not %flang -o %t.exe %t %t.c-object 2>&1
! RUN: %flang -fno-fortran-main -o %t.exe %t %t.c-object 2>&1
! TODO: potentially add further checks to ensure that proper
! linker error messages are detected and checked via
! FileCheck.

View File

@ -21,7 +21,6 @@ add_flang_tool(flang-new
# unable to generate executables.
FortranRuntime
FortranDecimal
Fortran_main
)
target_link_libraries(flang-new

View File

@ -50,7 +50,6 @@ AutoExporter::AutoExporter(
"libclang_rt.profile-x86_64",
"libc++",
"libc++abi",
"libFortran_main",
"libFortranRuntime",
"libFortranDecimal",
"libunwind",