diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1078,7 +1078,7 @@ def d_Joined : Joined<["-"], "d">, Group; def emit_ast : Flag<["-"], "emit-ast">, HelpText<"Emit Clang AST files for source inputs">; -def emit_llvm : Flag<["-"], "emit-llvm">, Flags<[CC1Option, FC1Option]>, Group, +def emit_llvm : Flag<["-"], "emit-llvm">, Flags<[CC1Option, FC1Option, FlangOption]>, Group, HelpText<"Use the LLVM representation for assembler and object files">; def emit_interface_stubs : Flag<["-"], "emit-interface-stubs">, Flags<[CC1Option]>, Group, HelpText<"Generate Interface Stub Files.">; @@ -3894,9 +3894,9 @@ def print_multi_os_directory : Flag<["-", "--"], "print-multi-os-directory">, Flags<[Unsupported]>; def print_target_triple : Flag<["-", "--"], "print-target-triple">, - HelpText<"Print the normalized target triple">; + HelpText<"Print the normalized target triple">, Flags<[FlangOption]>; def print_effective_triple : Flag<["-", "--"], "print-effective-triple">, - HelpText<"Print the effective target triple">; + HelpText<"Print the effective target triple">, Flags<[FlangOption]>; def print_multiarch : Flag<["-", "--"], "print-multiarch">, HelpText<"Print the multiarch target triple">; def print_prog_name_EQ : Joined<["-", "--"], "print-prog-name=">, @@ -4014,7 +4014,7 @@ "system header.">; def : Separate<["--"], "no-system-header-prefix">, Alias; def s : Flag<["-"], "s">, Group; -def target : Joined<["--"], "target=">, Flags<[NoXarchOption, CoreOption]>, +def target : Joined<["--"], "target=">, Flags<[NoXarchOption, CoreOption, FlangOption]>, HelpText<"Generate code for the given target">; def darwin_target_variant : Separate<["-"], "darwin-target-variant">, Flags<[NoXarchOption, CoreOption]>, @@ -4803,7 +4803,7 @@ let Flags = [CC1Option, NoDriverOption] in { //===----------------------------------------------------------------------===// -// Target Options +// Target Options (cc1 + cc1as) //===----------------------------------------------------------------------===// let Flags = [CC1Option, CC1AsOption, NoDriverOption] in { @@ -4817,10 +4817,6 @@ def target_feature : Separate<["-"], "target-feature">, HelpText<"Target specific attributes">, MarshallingInfoStringVector>; -def triple : Separate<["-"], "triple">, - HelpText<"Specify target triple (e.g. i686-apple-darwin9)">, - MarshallingInfoString, "llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple())">, - AlwaysEmit, Normalizer<"normalizeTriple">; def target_abi : Separate<["-"], "target-abi">, HelpText<"Target a particular ABI type">, MarshallingInfoString>; @@ -4834,7 +4830,23 @@ "darwin-target-variant-sdk-version=">, HelpText<"The version of darwin target variant SDK used for compilation">; -} +} // let Flags = [CC1Option, CC1AsOption, NoDriverOption] + +//===----------------------------------------------------------------------===// +// Target Options (cc1 + cc1as + fc1) +//===----------------------------------------------------------------------===// +let Flags = [CC1Option, CC1AsOption, FC1Option, NoDriverOption] in { + +def triple : Separate<["-"], "triple">, + HelpText<"Specify target triple (e.g. i686-apple-darwin9)">, + MarshallingInfoString, "llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple())">, + AlwaysEmit, Normalizer<"normalizeTriple">; + +} // let Flags = [CC1Option, CC1ASOption, FC1Option, NoDriverOption] + +//===----------------------------------------------------------------------===// +// Target Options (other) +//===----------------------------------------------------------------------===// def target_linker_version : Separate<["-"], "target-linker-version">, HelpText<"Target linker version">, diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -54,21 +54,17 @@ const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { const auto &TC = getToolChain(); - // TODO: Once code-generation is available, this will need to be commented - // out. - // const llvm::Triple &Triple = TC.getEffectiveTriple(); - // const std::string &TripleStr = Triple.getTriple(); + const llvm::Triple &Triple = TC.getEffectiveTriple(); + const std::string &TripleStr = Triple.getTriple(); ArgStringList CmdArgs; // Invoke ourselves in -fc1 mode. CmdArgs.push_back("-fc1"); - // TODO: Once code-generation is available, this will need to be commented - // out. // Add the "effective" target triple. - // CmdArgs.push_back("-triple"); - // CmdArgs.push_back(Args.MakeArgString(TripleStr)); + CmdArgs.push_back("-triple"); + CmdArgs.push_back(Args.MakeArgString(TripleStr)); if (isa(JA)) { CmdArgs.push_back("-E"); diff --git a/flang/include/flang/Frontend/CompilerInvocation.h b/flang/include/flang/Frontend/CompilerInvocation.h --- a/flang/include/flang/Frontend/CompilerInvocation.h +++ b/flang/include/flang/Frontend/CompilerInvocation.h @@ -10,6 +10,7 @@ #include "flang/Frontend/FrontendOptions.h" #include "flang/Frontend/PreprocessorOptions.h" +#include "flang/Frontend/TargetOptions.h" #include "flang/Parser/parsing.h" #include "flang/Semantics/semantics.h" #include "clang/Basic/Diagnostic.h" @@ -61,6 +62,9 @@ // of options. Fortran::parser::Options parserOpts_; + /// Options controlling the target. + Fortran::frontend::TargetOptions targetOpts_; + // Semantics context std::unique_ptr semanticsContext_; @@ -117,6 +121,9 @@ Fortran::parser::Options &fortranOpts() { return parserOpts_; } const Fortran::parser::Options &fortranOpts() const { return parserOpts_; } + TargetOptions &targetOpts() { return targetOpts_; } + const TargetOptions &TargetOpts() const { return targetOpts_; } + Fortran::semantics::SemanticsContext &semanticsContext() { return *semanticsContext_; } diff --git a/flang/include/flang/Frontend/TargetOptions.h b/flang/include/flang/Frontend/TargetOptions.h new file mode 100644 --- /dev/null +++ b/flang/include/flang/Frontend/TargetOptions.h @@ -0,0 +1,35 @@ +//===--- TargetOptions.h ----------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Defines the flang::TargetOptions class. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_FLANG_TARGETOPTIONS_H +#define LLVM_FLANG_TARGETOPTIONS_H + +namespace Fortran::frontend { + +/// Options for controlling the target. Currently this is just a placeholder. +/// In the future, we will use this to specify various target options that +/// will affect the generated code e.g.: +/// * CPU to tune the code for +/// * available CPU/hardware extensions +/// * target specific features to enable/disable +/// * options for accelerators (e.g. GPUs) +/// * (...) +class TargetOptions { +public: + /// The name of the target triple to compile for. + std::string triple; +}; + +} // end namespace Fortran::frontend + +#endif diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -9,6 +9,7 @@ #include "flang/Frontend/CompilerInvocation.h" #include "flang/Common/Fortran-features.h" #include "flang/Frontend/PreprocessorOptions.h" +#include "flang/Frontend/TargetOptions.h" #include "flang/Semantics/semantics.h" #include "flang/Version.inc" #include "clang/Basic/AllDiagnostics.h" @@ -88,6 +89,15 @@ return true; } +/// Parses all target input arguments and populates the target +/// options accordingly. +/// +/// \param [in] opts The target options instance to update +/// \param [in] args The list of input arguments (from the compiler invocation) +static void ParseTargetArgs(TargetOptions &opts, llvm::opt::ArgList &args) { + opts.triple = args.getLastArgValue(clang::driver::options::OPT_triple); +} + // Tweak the frontend configuration based on the frontend action static void setUpFrontendBasedOnAction(FrontendOptions &opts) { assert(opts.programAction != Fortran::frontend::InvalidAction && @@ -563,6 +573,7 @@ } success &= ParseFrontendArgs(res.frontendOpts(), args, diags); + ParseTargetArgs(res.targetOpts(), args); parsePreprocessorArgs(res.preprocessorOpts(), args); success &= parseSemaArgs(res, args, diags); success &= parseDialectArgs(res, args, diags); diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -81,7 +81,7 @@ llvm::ArrayRef{fir::fromDefaultKinds(defKinds)}); lower::LoweringBridge lb = Fortran::lower::LoweringBridge::create(*mlirCtx, defKinds, ci.invocation().semanticsContext().intrinsics(), - ci.parsing().allCooked(), /*triple=*/"native", kindMap); + ci.parsing().allCooked(), ci.invocation().targetOpts().triple, kindMap); // Create a parse tree and lower it to FIR Fortran::parser::Program &parseTree{*ci.parsing().parseTree()}; diff --git a/flang/test/Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90 --- a/flang/test/Driver/driver-help-hidden.f90 +++ b/flang/test/Driver/driver-help-hidden.f90 @@ -21,6 +21,7 @@ ! CHECK-NEXT: -cpp Enable predefined and command line preprocessor macros ! CHECK-NEXT: -c Only run preprocess, compile, and assemble steps ! CHECK-NEXT: -D = Define to (or 1 if 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 @@ -50,8 +51,11 @@ ! CHECK-NEXT: -nocpp Disable predefined and command line preprocessor macros ! CHECK-NEXT: -o Write output to ! 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: -P Disable linemarker output in -E mode ! CHECK-NEXT: -std= Language standard to compile for +! CHECK-NEXT: --target= Generate code for the given target ! CHECK-NEXT: -U Undefine macro ! CHECK-NEXT: --version Print version information ! CHECK-NEXT: -W Enable the specified warning diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90 --- a/flang/test/Driver/driver-help.f90 +++ b/flang/test/Driver/driver-help.f90 @@ -21,6 +21,7 @@ ! HELP-NEXT: -cpp Enable predefined and command line preprocessor macros ! HELP-NEXT: -c Only run preprocess, compile, and assemble steps ! HELP-NEXT: -D = Define to (or 1 if omitted) +! HELP-NEXT: -emit-llvm Use the LLVM representation for assembler and object files ! HELP-NEXT: -E Only run the preprocessor ! HELP-NEXT: -falternative-parameter-statement ! HELP-NEXT: Enable the old style PARAMETER statement @@ -50,8 +51,11 @@ ! HELP-NEXT: -nocpp Disable predefined and command line preprocessor macros ! HELP-NEXT: -o Write output to ! HELP-NEXT: -pedantic Warn on language extensions +! HELP-NEXT: -print-effective-triple Print the effective target triple +! HELP-NEXT: -print-target-triple Print the normalized target triple ! HELP-NEXT: -P Disable linemarker output in -E mode ! HELP-NEXT: -std= Language standard to compile for +! HELP-NEXT: --target= Generate code for the given target ! HELP-NEXT: -U Undefine macro ! HELP-NEXT: --version Print version information ! HELP-NEXT: -W Enable the specified warning @@ -124,6 +128,7 @@ ! HELP-FC1-NEXT: -P Disable linemarker output in -E mode ! HELP-FC1-NEXT: -std= Language standard to compile for ! HELP-FC1-NEXT: -test-io Run the InputOuputTest action. Use for development and testing only. +! HELP-FC1-NEXT: -triple Specify target triple (e.g. i686-apple-darwin9) ! HELP-FC1-NEXT: -U Undefine macro ! HELP-FC1-NEXT: --version Print version information ! HELP-FC1-NEXT: -W Enable the specified warning diff --git a/flang/test/Driver/print-effective-triple.f90 b/flang/test/Driver/print-effective-triple.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Driver/print-effective-triple.f90 @@ -0,0 +1,11 @@ +! Test that -print-target-triple prints correct triple. + +!----------------------------------------- +! RUN LINE +!----------------------------------------- +! RUN: %flang -print-effective-triple 2>&1 --target=thumb-linux-gnu | FileCheck %s + +!----------------- +! EXPECTED OUTPUT +!----------------- +! CHECK: armv4t-unknown-linux-gnu diff --git a/flang/test/Driver/print-target-triple.f90 b/flang/test/Driver/print-target-triple.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Driver/print-target-triple.f90 @@ -0,0 +1,16 @@ +! Test that -print-target-triple prints correct triple + +!----------------------------------------- +! RUN LINES +!----------------------------------------- +! RUN: %flang -print-target-triple 2>&1 --target=aarch64-linux-gnu \ +! RUN: | FileCheck --check-prefix=AARCH64 %s + +! RUN: %flang -print-target-triple 2>&1 --target=x86_64-linux-gnu \ +! RUN: | FileCheck --check-prefix=X86_64 %s + +!----------------- +! EXPECTED OUTPUT +!----------------- +! X86_64: x86_64-unknown-linux-gnu +! AARCH64: aarch64-unknown-linux-gnu diff --git a/flang/test/Driver/target.f90 b/flang/test/Driver/target.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Driver/target.f90 @@ -0,0 +1,13 @@ +! Test that --target indeed sets the target + +!----------------------------------------- +! RUN LINES +!----------------------------------------- +! RUN: %flang --target=unknown-unknown-unknown -emit-llvm -c %s \ +! RUN: -o %t.o -### 2>&1 | FileCheck %s + +!----------------- +! EXPECTED OUTPUT +!----------------- +! CHECK: Target: unknown-unknown-unknown +! CHECK: "-triple" "unknown-unknown-unknown"