From 57efb1033b1e66f39fc338ad8d582b5e7a601fbe Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Tue, 18 Oct 2022 18:24:25 -0400 Subject: [PATCH 01/32] [workflows] Minimal workflow to create an AArch64 container AArch64 GitHub workflows require a Docker container named after the branch. This commit adds the minimal workflow required to create the container image for building and testing subsequent pull requests. --- .github/workflows/Ubuntu20Dockerfile | 65 +++++++++++++++++++ .../build_push_docker_image_Ubuntu20.yml | 49 ++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 .github/workflows/Ubuntu20Dockerfile create mode 100644 .github/workflows/build_push_docker_image_Ubuntu20.yml diff --git a/.github/workflows/Ubuntu20Dockerfile b/.github/workflows/Ubuntu20Dockerfile new file mode 100644 index 000000000000..fda4dd1f48b4 --- /dev/null +++ b/.github/workflows/Ubuntu20Dockerfile @@ -0,0 +1,65 @@ +FROM ubuntu:20.04 + +ARG DEBIAN_FRONTEND=noninteractive +ENV TZ=Europe/London +RUN apt-get update && \ + apt-get upgrade -y && \ + apt-get install -y \ + curl \ + gcc \ + g++ \ + make \ + htop \ + jq \ + ninja-build \ + tmux \ + git \ + wget \ + patch \ + python3-minimal \ + python-is-python3 \ + libdata-dumper-simple-perl \ + unzip + +RUN apt-get install -y software-properties-common && \ + apt-get update && \ + add-apt-repository ppa:ubuntu-toolchain-r/test && \ + apt-get install -f -y gcc-9 g++-9 && \ + apt-get install -f -y gcc-10 g++-10 && \ + echo 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-11 main' | tee -a /etc/apt/sources.list.d/llvm.list && \ + echo 'deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-11 main' | tee -a /etc/apt/sources.list.d/llvm.list && \ + wget -q -O - http://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - && \ + apt-get update && \ + apt-get install -f -y llvm-9 clang-9 && \ + apt-get install -f -y llvm-10 clang-10 && \ + apt-get install -f -y llvm-11 clang-11 + +# Install the tools for release_13x and newer +RUN apt --fix-missing update && \ + apt install -y build-essential manpages-dev \ + libssl-dev zlib1g-dev \ + libbz2-dev libreadline-dev libsqlite3-dev libncurses5-dev && \ + apt install -y python3-distutils python3-psutil \ + libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev python-openssl + +RUN cd /opt && \ + wget https://github.com/Kitware/CMake/releases/download/v3.20.0/cmake-3.20.0-linux-aarch64.sh && \ + /bin/sh cmake-3.20.0-linux-aarch64.sh --skip-license --include-subdir && \ + ln -s /opt/cmake-3.20.0-linux-aarch64/bin/* /usr/local/bin + +RUN ln -s /usr/bin/ninja-build /usr/local/bin/ninja + +RUN mkdir /home/github/ + +ARG BRANCH_NAME +ARG INITIAL_BUILD +RUN if [ "$INITIAL_BUILD" != "true" ]; then \ + mkdir /home/root && cd home/root && \ + git clone --depth 1 --single-branch --branch $BRANCH_NAME https://github.com/flang-compiler/classic-flang-llvm-project.git classic-flang-llvm-project && \ + cd classic-flang-llvm-project && \ + ./build-llvm-project.sh -t AArch64 -p /home/github/usr/local -n `nproc --ignore=1` -a /usr/bin/gcc-10 -b /usr/bin/g++-10 -i -v; \ + fi + +RUN useradd github && \ + chown -R github:github /home/github +USER github diff --git a/.github/workflows/build_push_docker_image_Ubuntu20.yml b/.github/workflows/build_push_docker_image_Ubuntu20.yml new file mode 100644 index 000000000000..f4b7fb3bab44 --- /dev/null +++ b/.github/workflows/build_push_docker_image_Ubuntu20.yml @@ -0,0 +1,49 @@ +name: Pre-compile llvm ARM64 + +on: + workflow_dispatch: + inputs: + initialBuild: + description: "True if creating an initial Docker image for this branch" + required: true + type: boolean + push: + branches: + - 'release_*x' + paths-include: + - '**/.github/workflows/build_push_docker_image_Ubuntu20.yml' + - '**/.github/workflows/Ubuntu20Dockerfile.yml' + +jobs: + docker: + runs-on: self-hosted + steps: + - name: Extract branch name + run: echo "::set-output name=branch::${GITHUB_REF#refs/heads/}" + id: extract_branch + + - name: Checkout + uses: actions/checkout@v2 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Log in + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v2 + with: + file: .github/workflows/Ubuntu20Dockerfile + push: true + no-cache: true + context: .github/workflows + tags: ghcr.io/${{ github.repository_owner }}/ubuntu20-flang-${{ steps.extract_branch.outputs.branch }}:latest + platforms: linux/arm64 + build-args: | + BRANCH_NAME=${{ steps.extract_branch.outputs.branch }} + INITIAL_BUILD=${{ inputs.initialBuild }} -- Gitee From 67b7fa1eb1215db65a820bf4ab9b9b7330988869 Mon Sep 17 00:00:00 2001 From: Eric Schweitz Date: Wed, 21 Aug 2019 13:26:26 -0700 Subject: [PATCH 02/32] Port Classic Flang to LLVM 15 This commit cherry-picks 427c0e83a9f271c3b3f0028201a0c310c7143464 from the release_14x branch, which is a combination of the following legacy patches: Commit 82b38d24a518: [ClassicFlang] Port release_90 changes from flang-compiler/llvm Cherry-picked commit 2085211cfcca70411dc63f0d08763facc8a02090 by Eric Schweitz, resolved merge conflicts, fixed build failures (e.g. adapted CGDebugInfo.cpp to the new API), and fixed the DIGlobalVariable unit tests, which have been broken since commit edfad65eebdf045b050f37380b6b61d673513982. Commit 885dd87e5fdc: [DebugInfo] Removal of DIFortranArrayType and DIFortranSubrange These extensions are no more required after merge of below PR. Commit 5c9b2e0867d5: Modification to incorporate comments from @bryanpkc. Commit 822de2c2a9cc: [AsmPrinter] Fix redundant names and types A bug was introduced in 82b38d24a51871a210a184dd558e9b955a421e8e while cherry-picking a DIGlobalVariable-related patch. Commit 45a70a89626a: Port driver changes from release/11x Cherry-picked c51f89679135f84675f492d560ec5535c2000cfe by Varun Jayathirtha from release_90, and resolved merge conflicts. To avoid conflicts with the new Flang, lib/Driver/ToolChains/Flang.{cpp,h} have been renamed to ClassicFlang.{cpp,h}, and the ENABLE_CLASSIC_FLANG macro is introduced to select which incarnation of Flang to build. The macro is set by running CMake with -DLLVM_ENABLE_CLASSIC_FLANG. After merge with LLVM 11: Move flang options to the end of the definitions list. Commit a9a803645a7d: Port Classic Flang to LLVM 13 File changes to TargetLibraryInfo and DebugLocEntry to adapt to the code from release/13.x and make it work. Comment out the changes due a segmentation fault, code need to be reviewed properly once all commits are in Commit fe989b724392: Fix -fveclib=PGMATH The use of #ifdef in include/clang/Driver/Options.td was incorrect and unsupported. As a result -fveclib=PGMATH was silently ignored, and in LLVM 12, it causes the invocation to fail. This patch unguards the option so that it is parsed correctly, but lets the FLANG_LLVM_EXTENSIONS macro continue to toggle the feature. Commit 7c224ae4708d: Fix use of classic Flang as preprocessor Commit 8403c8335f9a: Merge FLANG_LLVM_EXTENSIONS macro into ENABLE_CLASSIC_FLANG Commit 486741e2e30f: Fix test failures when in classic Flang mode Add a new lit feature tag "classic_flang" to select which tests can or cannot be run when the driver is built for classic Flang. Handle LLVM_ENABLE_CLASSIC_FLANG in llvm/cmake/modules/HandleLLVMOptions.cmake instead of clang/CMakeLists.txt so that macro works in both clang and llvm. Commit a10f592d3b02: Port Classic Flang to LLVM 13 LLVM port from release_12x to release_13x, changes done in order to make project able to be build. Commit d3853218de1a (partial): Change to Options.td in order to add the correct invocation for ffixed_line_length_VALUE. This commit also includes the following legacy patch: Commit 5da2c11605e0: Add DebugInfo tests Commit c379c8d515c0: [ClassicFlang][Driver] Correct the LLVM version passed by the Driver --- clang/CMakeLists.txt | 5 + clang/include/clang/Basic/CodeGenOptions.h | 1 + .../clang/Basic/DiagnosticDriverKinds.td | 6 + clang/include/clang/Basic/MacroBuilder.h | 3 +- clang/include/clang/Basic/Sanitizers.def | 2 + clang/include/clang/Driver/Action.h | 11 + clang/include/clang/Driver/Options.td | 199 ++- clang/include/clang/Driver/Phases.h | 1 + clang/include/clang/Driver/ToolChain.h | 15 + clang/include/clang/Driver/Types.def | 7 + clang/include/clang/Driver/Types.h | 8 + clang/include/clang/Frontend/Utils.h | 31 + clang/lib/CodeGen/BackendUtil.cpp | 5 + clang/lib/CodeGen/CGDebugInfo.cpp | 10 +- clang/lib/Driver/Action.cpp | 7 + clang/lib/Driver/CMakeLists.txt | 5 + clang/lib/Driver/Driver.cpp | 41 + clang/lib/Driver/Phases.cpp | 1 + clang/lib/Driver/ToolChain.cpp | 57 +- clang/lib/Driver/ToolChains/Clang.cpp | 61 + clang/lib/Driver/ToolChains/ClassicFlang.cpp | 1064 +++++++++++++++++ clang/lib/Driver/ToolChains/ClassicFlang.h | 49 + clang/lib/Driver/ToolChains/CommonArgs.cpp | 35 + clang/lib/Driver/ToolChains/CommonArgs.h | 2 + clang/lib/Driver/ToolChains/Cuda.cpp | 33 + clang/lib/Driver/ToolChains/Cuda.h | 3 + clang/lib/Driver/ToolChains/Gnu.cpp | 10 + clang/lib/Driver/ToolChains/Linux.cpp | 188 +++ clang/lib/Driver/ToolChains/Linux.h | 3 + clang/lib/Driver/Types.cpp | 49 + clang/lib/Frontend/InitPreprocessor.cpp | 20 - clang/test/Driver/autocomplete.c | 2 +- clang/test/Driver/flang/classic_flang.f95 | 28 + clang/test/Driver/flang/flang.f90 | 2 + clang/test/Driver/flang/flang_ucase.F90 | 2 + .../Driver/flang/multiple-inputs-mixed.f90 | 2 + clang/test/Driver/flang/multiple-inputs.f90 | 2 + clang/test/Driver/fortran.f95 | 2 + clang/test/Driver/gfortran.f90 | 1 + clang/test/lit.cfg.py | 3 + clang/test/lit.site.cfg.py.in | 1 + .../ClangOffloadBundler.cpp | 2 + clang/tools/driver/CMakeLists.txt | 2 +- llvm/cmake/modules/HandleLLVMOptions.cmake | 8 + llvm/include/llvm-c/DebugInfo.h | 5 +- .../include/llvm/Analysis/TargetLibraryInfo.h | 1 + llvm/include/llvm/IR/DIBuilder.h | 19 +- llvm/include/llvm/IR/DebugInfoMetadata.h | 32 +- llvm/lib/Analysis/TargetLibraryInfo.cpp | 454 ++++++- llvm/lib/AsmParser/LLParser.cpp | 22 +- llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 42 +- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 3 +- llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h | 89 ++ .../lib/CodeGen/AsmPrinter/DebugLocStream.cpp | 5 +- llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h | 7 +- .../CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 3 + .../lib/CodeGen/AsmPrinter/DwarfCompileUnit.h | 8 + llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 76 ++ llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 12 + llvm/lib/IR/AsmWriter.cpp | 1 + llvm/lib/IR/DIBuilder.cpp | 12 +- llvm/lib/IR/DebugInfo.cpp | 10 +- llvm/lib/IR/DebugInfoMetadata.cpp | 12 +- llvm/lib/IR/LLVMContextImpl.h | 11 +- .../Instrumentation/InstrProfiling.cpp | 4 +- .../Transforms/Vectorize/LoopVectorize.cpp | 6 +- .../invalid-diglobalvariable-empty-name.ll | 1 + .../Generic/fortran-subprogram-at.ll | 24 + .../DebugInfo/Generic/more-subprogram-attr.ll | 38 + llvm/test/DebugInfo/X86/DICommonBlock.ll | 36 + llvm/test/lit.cfg.py | 3 + llvm/test/lit.site.cfg.py.in | 1 + llvm/tools/llvm-c-test/debuginfo.c | 4 +- llvm/unittests/IR/MetadataTest.cpp | 47 +- 74 files changed, 2853 insertions(+), 124 deletions(-) create mode 100644 clang/lib/Driver/ToolChains/ClassicFlang.cpp create mode 100644 clang/lib/Driver/ToolChains/ClassicFlang.h mode change 100644 => 100755 clang/lib/Driver/Types.cpp create mode 100644 clang/test/Driver/flang/classic_flang.f95 create mode 100644 llvm/test/DebugInfo/Generic/fortran-subprogram-at.ll create mode 100644 llvm/test/DebugInfo/Generic/more-subprogram-attr.ll create mode 100644 llvm/test/DebugInfo/X86/DICommonBlock.ll diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index e3bc4b468fb6..4c100422f9dc 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -491,6 +491,11 @@ endif() add_definitions( -D_GNU_SOURCE ) +option(LLVM_ENABLE_CLASSIC_FLANG "Build support for classic Flang instead of the new built-in Flang" OFF) +if(LLVM_ENABLE_CLASSIC_FLANG) + add_definitions( -DENABLE_CLASSIC_FLANG ) +endif() + option(CLANG_BUILD_TOOLS "Build the Clang tools. If OFF, just generate build targets." ON) diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index cd204e5d7c15..fe320acc9caf 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -59,6 +59,7 @@ public: Accelerate, // Use the Accelerate framework. LIBMVEC, // GLIBC vector math library. MASSV, // IBM MASS vector library. + PGMATH, // PGI math library. SVML, // Intel short vector math library. Darwin_libsystem_m // Use Darwin's libsytem_m vector functions. }; diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 2f600d28fea0..fb78977b2699 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -117,6 +117,10 @@ def err_drv_invalid_linker_name : Error< "invalid linker name in argument '%0'">; def err_drv_invalid_rtlib_name : Error< "invalid runtime library name in argument '%0'">; +def err_drv_invalid_allocatable_mode : Error< + "invalid semantic mode for assignments to allocatables in argument '%0'">; +def err_drv_unsupported_fixed_line_length : Error< + "unsupported fixed-format line length in argument '%0'">; def err_drv_unsupported_rtlib_for_platform : Error< "unsupported runtime library '%0' for platform '%1'">; def err_drv_invalid_unwindlib_name : Error< @@ -335,6 +339,8 @@ def err_drv_negative_columns : Error< "invalid value '%1' in '%0', value must be 'none' or a positive integer">; def err_drv_small_columns : Error< "invalid value '%1' in '%0', value must be '%2' or greater">; +def err_drv_clang_unsupported_minfo_arg : Error< + "'%0' option does not support '%1' value">; def err_drv_invalid_malign_branch_EQ : Error< "invalid argument '%0' to -malign-branch=; each element must be one of: %1">; diff --git a/clang/include/clang/Basic/MacroBuilder.h b/clang/include/clang/Basic/MacroBuilder.h index 96e67cbbfa3f..bfc5e38c15e3 100644 --- a/clang/include/clang/Basic/MacroBuilder.h +++ b/clang/include/clang/Basic/MacroBuilder.h @@ -24,9 +24,10 @@ class MacroBuilder { raw_ostream &Out; public: MacroBuilder(raw_ostream &Output) : Out(Output) {} + virtual ~MacroBuilder() {} /// Append a \#define line for macro of the form "\#define Name Value\n". - void defineMacro(const Twine &Name, const Twine &Value = "1") { + virtual void defineMacro(const Twine &Name, const Twine &Value = "1") { Out << "#define " << Name << ' ' << Value << '\n'; } diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def index 8e7b6cd0a7e2..24dc2b668404 100644 --- a/clang/include/clang/Basic/Sanitizers.def +++ b/clang/include/clang/Basic/Sanitizers.def @@ -107,6 +107,8 @@ SANITIZER("signed-integer-overflow", SignedIntegerOverflow) SANITIZER("unreachable", Unreachable) SANITIZER("vla-bound", VLABound) SANITIZER("vptr", Vptr) +// fortran contiguous pointer checks +SANITIZER("discontiguous", Discontiguous) // IntegerSanitizer SANITIZER("unsigned-integer-overflow", UnsignedIntegerOverflow) diff --git a/clang/include/clang/Driver/Action.h b/clang/include/clang/Driver/Action.h index 684ccd358275..b1a91edb6158 100644 --- a/clang/include/clang/Driver/Action.h +++ b/clang/include/clang/Driver/Action.h @@ -63,6 +63,7 @@ public: AnalyzeJobClass, MigrateJobClass, CompileJobClass, + FortranFrontendJobClass, BackendJobClass, AssembleJobClass, LinkJobClass, @@ -487,6 +488,16 @@ public: } }; +class FortranFrontendJobAction : public JobAction { + void anchor() override; +public: + FortranFrontendJobAction(Action *Input, types::ID OutputType); + + static bool classof(const Action *A) { + return A->getKind() == FortranFrontendJobClass; + } +}; + class CompileJobAction : public JobAction { void anchor() override; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 3cab37b21aaf..29b328429752 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -533,7 +533,7 @@ class InternalDriverOpt : Group, Flags<[NoXarchOption, HelpHidden]>; def driver_mode : Joined<["--"], "driver-mode=">, Group, Flags<[CoreOption, NoXarchOption, HelpHidden]>, - HelpText<"Set the driver mode to either 'gcc', 'g++', 'cpp', or 'cl'">; + HelpText<"Set the driver mode to either 'gcc', 'g++', 'cpp', 'cl', or 'fortran'">; def rsp_quoting : Joined<["--"], "rsp-quoting=">, Group, Flags<[CoreOption, NoXarchOption, HelpHidden]>, HelpText<"Set the rsp quoting to either 'posix', or 'windows'">; @@ -2397,9 +2397,9 @@ def fno_experimental_isel : Flag<["-"], "fno-experimental-isel">, Group; def fveclib : Joined<["-"], "fveclib=">, Group, Flags<[CC1Option]>, HelpText<"Use the given vector functions library">, - Values<"Accelerate,libmvec,MASSV,SVML,Darwin_libsystem_m,none">, + Values<"Accelerate,libmvec,MASSV,PGMATH,SVML,Darwin_libsystem_m,none">, NormalizedValuesScope<"CodeGenOptions">, - NormalizedValues<["Accelerate", "LIBMVEC", "MASSV", "SVML", + NormalizedValues<["Accelerate", "LIBMVEC", "MASSV", "PGMATH", "SVML", "Darwin_libsystem_m", "NoLibrary"]>, MarshallingInfoEnum, "NoLibrary">; def fno_lax_vector_conversions : Flag<["-"], "fno-lax-vector-conversions">, Group, @@ -4790,6 +4790,12 @@ defm devirtualize : BooleanFFlag<"devirtualize">, Group, Group; +// gfortran options that we recognize in the driver and pass along when +// invoking GCC to compile Fortran code. +def flang_rt_Group : OptionGroup<"Flang runtime library Group">; +def pgi_fortran_Group : OptionGroup<"PGI Fortran compatibility Group">, + Flags<[HelpHidden]>; + // Generic gfortran options. def A_DASH : Joined<["-"], "A-">, Group; def static_libgfortran : Flag<["-"], "static-libgfortran">, Group; @@ -4811,6 +4817,8 @@ def fmax_stack_var_size_EQ : Joined<["-"], "fmax-stack-var-size=">, Group, Group; // "f" flags for gfortran. defm aggressive_function_elimination : BooleanFFlag<"aggressive-function-elimination">, Group; defm align_commons : BooleanFFlag<"align-commons">, Group; @@ -4822,13 +4830,19 @@ defm check_array_temporaries : BooleanFFlag<"check-array-temporaries">, Group, Group; defm d_lines_as_code : BooleanFFlag<"d-lines-as-code">, Group; defm d_lines_as_comments : BooleanFFlag<"d-lines-as-comments">, Group; +def default_integer_8_fno : Flag<["-"], "fno-default-integer-8">, Group; +def default_real_8_fno : Flag<["-"], "fno-default-real-8">, Group; defm dollar_ok : BooleanFFlag<"dollar-ok">, Group; defm dump_fortran_optimized : BooleanFFlag<"dump-fortran-optimized">, Group; defm dump_fortran_original : BooleanFFlag<"dump-fortran-original">, Group; defm dump_parse_tree : BooleanFFlag<"dump-parse-tree">, Group; defm external_blas : BooleanFFlag<"external-blas">, Group; defm f2c : BooleanFFlag<"f2c">, Group; -defm frontend_optimize : BooleanFFlag<"frontend-optimize">, Group; +def fixed_form_off : Flag<["-"], "fno-fixed-form">, Group, + HelpText<"Disable fixed-form format for Fortran">; +def free_form_off : Flag<["-"], "fno-free-form">, Group, + HelpText<"Disable free-form format for Fortran">; +defm frontend_optimize : BooleanFFlag<"frontend-optimize">, Group; defm init_local_zero : BooleanFFlag<"init-local-zero">, Group; defm integer_4_integer_8 : BooleanFFlag<"integer-4-integer-8">, Group; defm max_identifier_length : BooleanFFlag<"max-identifier-length">, Group; @@ -4880,9 +4894,9 @@ def Xflang : Separate<["-"], "Xflang">, let Flags = [FC1Option, FlangOption, FlangOnlyOption] in { -def cpp : Flag<["-"], "cpp">, Group, +def cpp : Flag<["-"], "cpp">, Group, HelpText<"Enable predefined and command line preprocessor macros">; -def nocpp : Flag<["-"], "nocpp">, Group, +def nocpp : Flag<["-"], "nocpp">, Group, HelpText<"Disable predefined and command line preprocessor macros">; def module_dir : JoinedOrSeparate<["-"], "module-dir">, MetaVarName<"">, HelpText<"Put MODULE files in ">, @@ -4890,33 +4904,47 @@ def module_dir : JoinedOrSeparate<["-"], "module-dir">, MetaVarName<"">, It is also added to the list of directories to be searched by an USE statement. The default is the current directory.}]>; -def ffixed_form : Flag<["-"], "ffixed-form">, Group, +def ffixed_form : Flag<["-"], "ffixed-form">, Group, HelpText<"Process source files in fixed form">; -def ffree_form : Flag<["-"], "ffree-form">, Group, +#ifdef ENABLE_CLASSIC_FLANG +def fno_fixed_form : Flag<["-"], "fno-fixed-form">, Group, + HelpText<"Disable fixed-form format for Fortran">; +#endif +def ffree_form : Flag<["-"], "ffree-form">, Group, HelpText<"Process source files in free form">; -def ffixed_line_length_EQ : Joined<["-"], "ffixed-line-length=">, Group, +#ifdef ENABLE_CLASSIC_FLANG +def fno_free_form : Flag<["-"], "fno-free-form">, Group, + HelpText<"Disable free-form format for Fortran">; +#endif +def ffixed_line_length_EQ : Joined<["-"], "ffixed-line-length=">, Group, HelpText<"Use as character line width in fixed mode">, DocBrief<[{Set column after which characters are ignored in typical fixed-form lines in the source file}]>; -def ffixed_line_length_VALUE : Joined<["-"], "ffixed-line-length-">, Group, Alias; +def ffixed_line_length_VALUE : Joined<["-"], "ffixed-line-length-">, Group, + HelpText<"Set line length in fixed-form format Fortran, current supporting only 72 and 132 characters">; def fopenacc : Flag<["-"], "fopenacc">, Group, HelpText<"Enable OpenACC">; -def fdefault_double_8 : Flag<["-"],"fdefault-double-8">, Group, +def fdefault_double_8 : Flag<["-"],"fdefault-double-8">, Group, HelpText<"Set the default double precision kind to an 8 byte wide type">; -def fdefault_integer_8 : Flag<["-"],"fdefault-integer-8">, Group, +def fdefault_integer_8 : Flag<["-"],"fdefault-integer-8">, Group, HelpText<"Set the default integer kind to an 8 byte wide type">; -def fdefault_real_8 : Flag<["-"],"fdefault-real-8">, Group, +def fdefault_real_8 : Flag<["-"],"fdefault-real-8">, Group, HelpText<"Set the default real kind to an 8 byte wide type">; def flarge_sizes : Flag<["-"],"flarge-sizes">, Group, HelpText<"Use INTEGER(KIND=8) for the result type in size-related intrinsics">; - def falternative_parameter_statement : Flag<["-"], "falternative-parameter-statement">, Group, HelpText<"Enable the old style PARAMETER statement">; def fintrinsic_modules_path : Separate<["-"], "fintrinsic-modules-path">, Group, MetaVarName<"">, HelpText<"Specify where to find the compiled intrinsic modules">, DocBrief<[{This option specifies the location of pre-compiled intrinsic modules, if they are not in the default location expected by the compiler.}]>; - +#ifdef ENABLE_CLASSIC_FLANG +def fbackslash : Flag<["-"], "fbackslash">, Group, + HelpText<"Specify that backslash in string introduces an escape character">, + DocBrief<[{Change the interpretation of backslashes in string literals from +a single backslash character to "C-style" escape characters.}]>; +def fno_backslash : Flag<["-"], "fno-backslash">, Group; +#else defm backslash : OptInFC1FFlag<"backslash", "Specify that backslash in string introduces an escape character">; defm xor_operator : OptInFC1FFlag<"xor-operator", "Enable .XOR. as a synonym of .NEQV.">; defm logical_abbreviations : OptInFC1FFlag<"logical-abbreviations", "Enable logical abbreviations">; @@ -4924,13 +4952,19 @@ defm implicit_none : OptInFC1FFlag<"implicit-none", "No implicit typing allowed def fno_automatic : Flag<["-"], "fno-automatic">, Group, HelpText<"Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE">; - +#endif } // let Flags = [FC1Option, FlangOption, FlangOnlyOption] +#ifdef ENABLE_CLASSIC_FLANG +def J : JoinedOrSeparate<["-"], "J">, + Flags<[RenderJoined]>, + Group; +#else def J : JoinedOrSeparate<["-"], "J">, Flags<[RenderJoined, FlangOption, FC1Option, FlangOnlyOption]>, Group, Alias; +#endif //===----------------------------------------------------------------------===// // FC1 Options @@ -6913,3 +6947,136 @@ def fcgl : DXCFlag<"fcgl">, Alias; def enable_16bit_types : DXCFlag<"enable-16bit-types">, Alias, HelpText<"Enable 16-bit types and disable min precision types." "Available in HLSL 2018 and shader model 6.2.">; + +// Classic Flang-specific options +multiclass BooleanKFlag { + def _on : Flag<["-"], "K"#name>; + def _off : Flag<["-"], "Kno"#name>; +} + +multiclass BooleanMFlag { + def _on : Flag<["-"], "M"#name>; + def _off : Flag<["-"], "Mno"#name>; +} + +def Mfixed : Flag<["-"], "Mfixed">, Group, + HelpText<"Force fixed-form format Fortran">, + Flags<[HelpHidden]>; +def Mfree_on: Flag<["-"], "Mfree">, Group, + HelpText<"Enable free-form format for Fortran">, + Flags<[HelpHidden]>; +def Mfree_off: Flag<["-"], "Mnofree">, Group, + HelpText<"Disable free-form format for Fortran">, + Flags<[HelpHidden]>; +def Mfreeform_on: Flag<["-"], "Mfreeform">, Group, + HelpText<"Enable free-form format for Fortran">, + Flags<[HelpHidden]>; +def Mfreeform_off: Flag<["-"], "Mnofreeform">, Group, + HelpText<"Disable free-form format for Fortran">, + Flags<[HelpHidden]>; + +def Minfo_EQ : CommaJoined<["-"], "Minfo=">, + HelpText<"Diagnostic information about successful optimizations">, + Values<"all,vect,inline">; +def Minfoall : Flag<["-"], "Minfo">, + HelpText<"Diagnostic information about all successful optimizations">; +def Mneginfo_EQ : CommaJoined<["-"], "Mneginfo=">, + HelpText<"Diagnostic information about missed optimizations">, + Values<"all,vect,inline">; +def Mneginfoall : Flag<["-"], "Mneginfo">, + HelpText<"Diagnostic information about all missed optimizations">; + +def Mipa: Joined<["-"], "Mipa">, Group; +def Mstackarrays: Joined<["-"], "Mstack_arrays">, Group; +def pc: JoinedOrSeparate<["-"], "pc">, Group; +def Mfprelaxed: Joined<["-"], "Mfprelaxed">, Group; +def Mnofprelaxed: Joined<["-"], "Mnofprelaxed">, Group; +defm Mstride0: BooleanMFlag<"stride0">, Group; +defm Mrecursive: BooleanMFlag<"recursive">, Group; +defm Mreentrant: BooleanMFlag<"reentrant">, Group; +defm Mbounds: BooleanMFlag<"bounds">, Group; +def Mdaz_on: Flag<["-"], "Mdaz">, Group, + HelpText<"Treat denormalized numbers as zero">; +def Mdaz_off: Flag<["-"], "Mnodaz">, Group, + HelpText<"Disable treating denormalized numbers as zero">; +def Kieee_on : Flag<["-"], "Kieee">, Group, + HelpText<"Enable IEEE division">; +def Kieee_off : Flag<["-"], "Knoieee">, Group, + HelpText<"Disable IEEE division">; +def Mextend : Flag<["-"], "Mextend">, Group, + HelpText<"Allow lines up to 132 characters in Fortran sources">; +def Mpreprocess : Flag<["-"], "Mpreprocess">, Group, + HelpText<"Preprocess Fortran files">; +def Mstandard: Flag<["-"], "Mstandard">, Group, + HelpText<"Check Fortran standard conformance">; +def Mchkptr: Flag<["-"], "Mchkptr">, Group; +def Mwritable_constants: Flag<["-"], "Mwritable-constants">, Group, + HelpText<"Store constants in the writable data segment">; +defm Minline: BooleanMFlag<"inline">, Group; +def fma: Flag<["-"], "fma">, Group, + HelpText<"Enable generation of FMA instructions">; +def nofma: Flag<["-"], "nofma">, Group, + HelpText<"Disable generation of FMA instructions">; +defm Mfma: BooleanMFlag<"fma">, Group, + HelpText<"Enable generation of FMA instructions">; +def mp: Flag<["-"], "mp">, Group, + HelpText<"Enable OpenMP">; +def nomp: Flag<["-"], "nomp">, Group, + HelpText<"Do not link with OpenMP library libomp">; +def Mflushz_on: Flag<["-"], "Mflushz">, Group, + HelpText<"Set SSE to flush-to-zero mode">; +def Mflushz_off: Flag<["-"], "Mnoflushz">, Group, + HelpText<"Disabling setting SSE to flush-to-zero mode">; +def Msave_on: Flag<["-"], "Msave">, Group, + HelpText<"Assume all Fortran variables have SAVE attribute">; +def Msave_off: Flag<["-"], "Mnosave">, Group, + HelpText<"Assume no Fortran variables have SAVE attribute">; +def Mcache_align_on: Flag<["-"], "Mcache_align">, Group, + HelpText<"Align large objects on cache-line boundaries">; +def Mcache_align_off: Flag<["-"], "Mnocache_align">, Group, + HelpText<"Disable aligning large objects on cache-line boundaries">; +def ModuleDir : Separate<["-"], "module">, Group, + HelpText<"Fortran module path">; +def Minform_EQ : Joined<["-"], "Minform=">, + HelpText<"Set error level of messages to display">; +def Mallocatable_EQ : Joined<["-"], "Mallocatable=">, + HelpText<"Select semantics for assignments to allocatables (F03 or F95)">; +def Mbyteswapio: Flag<["-"], "Mbyteswapio">, Group, + HelpText<"Swap byte-order for unformatted input/output">; +def byteswapio: Flag<["-"], "byteswapio">, Group, + HelpText<"Swap byte-order for unformatted input/output">; +def Mbackslash: Flag<["-"], "Mbackslash">, Group, + HelpText<"Treat backslash like any other character in character strings">; +def Mnobackslash: Flag<["-"], "Mnobackslash">, Group, + HelpText<"Treat backslash as C-style escape character">; +def staticFlangLibs: Flag<["-"], "static-flang-libs">, Group, + HelpText<"Link using static Flang libraries">; +def noFlangLibs: Flag<["-"], "no-flang-libs">, Group, + HelpText<"Do not link against Flang libraries">; +def r8: Flag<["-"], "r8">, Group, + HelpText<"Treat REAL as REAL*8">; +def i8: Flag<["-"], "i8">, Group, + HelpText<"Treat INTEGER and LOGICAL as INTEGER*8 and LOGICAL*8">; +def no_fortran_main: Flag<["-"], "fno-fortran-main">, Group, + HelpText<"Don't link in Fortran main">; +def Mnomain: Flag<["-"], "Mnomain">, Group, + HelpText<"Don't link in Fortran main">; +def frelaxed_math : Flag<["-"], "frelaxed-math">, Group, + HelpText<"Use relaxed Math intrinsic functions">; +def Memit_dwarf_common_blocks_name: Flag<["-"], "Memit-dwarf-common-blocks-name">, + Group, HelpText<"Emit COMMON blocks name in DWARF">; +def Munixlogical: Flag<["-"], "Munixlogical">, Group, + HelpText<"Use unixlogical for all loigical operations">; + +// Flang internal debug options +def Mx_EQ : Joined<["-"], "Mx,">, Group; +def My_EQ : Joined<["-"], "My,">, Group; +def Hx_EQ : Joined<["-"], "Hx,">, Group; +def Hy_EQ : Joined<["-"], "Hy,">, Group; +def Wm_EQ : Joined<["-"], "Wm,">, Group; + +def Mq_EQ : Joined<["-"], "Mq,">, Group; +def Hq_EQ : Joined<["-"], "Hq,">, Group; +def Mqq_EQ : Joined<["-"], "Mqq,">, Group; +def Hqq_EQ : Joined<["-"], "Hqq,">, Group; +def Wh_EQ : Joined<["-"], "Wh,">, Group; diff --git a/clang/include/clang/Driver/Phases.h b/clang/include/clang/Driver/Phases.h index 9003c5857351..f8cac9548d02 100644 --- a/clang/include/clang/Driver/Phases.h +++ b/clang/include/clang/Driver/Phases.h @@ -17,6 +17,7 @@ namespace phases { enum ID { Preprocess, Precompile, + FortranFrontend, Compile, Backend, Assemble, diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index 53c86ee82936..66cd1823033d 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -145,6 +145,7 @@ private: mutable std::unique_ptr Clang; mutable std::unique_ptr Flang; + mutable std::unique_ptr FortranFrontend; mutable std::unique_ptr Assemble; mutable std::unique_ptr Link; mutable std::unique_ptr StaticLibTool; @@ -156,6 +157,7 @@ private: Tool *getClang() const; Tool *getFlang() const; + Tool *getFortranFrontend() const; Tool *getAssemble() const; Tool *getLink() const; Tool *getStaticLibTool() const; @@ -621,6 +623,14 @@ public: AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const; + /// \brief Add the flang arguments for system include paths. + /// + /// This routine is responsible for adding the -stdinc argument to + /// include headers and module files from standard system header directories. + virtual void + AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &Flang1Args) const { } + /// Add options that need to be passed to cc1 for this target. virtual void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, @@ -718,6 +728,11 @@ public: virtual void AddHIPRuntimeLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const {} + /// AddFortranStdlibLibArgs - Add the system specific linker arguments to use + /// for the given Fortran runtime library type. + virtual void AddFortranStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const; + /// Return sanitizers which are available in this toolchain. virtual SanitizerMask getSupportedSanitizers() const; diff --git a/clang/include/clang/Driver/Types.def b/clang/include/clang/Driver/Types.def index d00d520d7514..7f91e348d875 100644 --- a/clang/include/clang/Driver/Types.def +++ b/clang/include/clang/Driver/Types.def @@ -77,8 +77,15 @@ TYPE("c++-module-cpp-output", PP_CXXModule, INVALID, "iim", phases TYPE("ada", Ada, INVALID, nullptr, phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("assembler", PP_Asm, INVALID, "s", phases::Assemble, phases::Link) TYPE("assembler-with-cpp", Asm, PP_Asm, "S", phases::Preprocess, phases::Assemble, phases::Link) +#ifdef ENABLE_CLASSIC_FLANG +TYPE("f77", PP_F_FixedForm, INVALID, "f", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link) +TYPE("f77-cpp-input", F_FixedForm, PP_F_FixedForm, "F", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link) +TYPE("f95", PP_F_FreeForm, INVALID, "f95", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link) +TYPE("f95-cpp-input", F_FreeForm, PP_F_FreeForm, "F95", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link) +#else TYPE("f95", PP_Fortran, INVALID, "i", phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("f95-cpp-input", Fortran, PP_Fortran, nullptr, phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link) +#endif TYPE("java", Java, INVALID, nullptr, phases::Compile, phases::Backend, phases::Assemble, phases::Link) // LLVM IR/LTO types. We define separate types for IR and LTO because LTO diff --git a/clang/include/clang/Driver/Types.h b/clang/include/clang/Driver/Types.h index fc5dd7bbfd6f..e8000778076a 100644 --- a/clang/include/clang/Driver/Types.h +++ b/clang/include/clang/Driver/Types.h @@ -95,6 +95,14 @@ namespace types { /// isOpenCL - Is this an "OpenCL" input. bool isOpenCL(ID Id); +#ifdef ENABLE_CLASSIC_FLANG + /// isFreeFormFortran -- is it a free form layout Fortran input + bool isFreeFormFortran(ID Id); + + /// isFixedFormFortran -- is it a fixed form layout Fortran input + bool isFixedFormFortran(ID Id); +#endif + /// isSrcFile - Is this a source file, i.e. something that still has to be /// preprocessed. The logic behind this is the same that decides if the first /// compilation phase is a preprocessing one. diff --git a/clang/include/clang/Frontend/Utils.h b/clang/include/clang/Frontend/Utils.h index 143cf4359f00..f9a7e25c0049 100644 --- a/clang/include/clang/Frontend/Utils.h +++ b/clang/include/clang/Frontend/Utils.h @@ -17,6 +17,7 @@ #include "clang/Basic/LLVM.h" #include "clang/Driver/OptionUtils.h" #include "clang/Frontend/DependencyOutputOptions.h" +#include "clang/Basic/TargetInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringMap.h" @@ -31,6 +32,12 @@ #include #include +namespace llvm { + +class StringRef; + +} // namespace llvm + namespace clang { class ASTReader; @@ -39,6 +46,7 @@ class CompilerInvocation; class DiagnosticsEngine; class ExternalSemaSource; class FrontendOptions; +class MacroBuilder; class PCHContainerReader; class Preprocessor; class PreprocessorOptions; @@ -54,6 +62,29 @@ void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts, void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS, const PreprocessorOutputOptions &Opts); +/// DefineTypeSize - Emit a macro to the predefines buffer that declares a macro +/// named MacroName with the max value for a type with width 'TypeWidth' a +/// signedness of 'isSigned' and with a value suffix of 'ValSuffix' (e.g. LL). +template +static void DefineTypeSize(const Twine &MacroName, unsigned TypeWidth, + StringRef ValSuffix, bool isSigned, + T &Builder) { + static_assert(std::is_base_of::value, "Illegal T value"); + llvm::APInt MaxVal = isSigned ? llvm::APInt::getSignedMaxValue(TypeWidth) + : llvm::APInt::getMaxValue(TypeWidth); + Builder.defineMacro(MacroName, toString(MaxVal, 10, isSigned) + ValSuffix); +} + +/// DefineTypeSize - An overloaded helper that uses TargetInfo to determine +/// the width, suffix, and signedness of the given type +template +static void DefineTypeSize(const Twine &MacroName, TargetInfo::IntType Ty, + const TargetInfo &TI, T &Builder) { + static_assert(std::is_base_of::value, "Illegal T value"); + DefineTypeSize(MacroName, TI.getTypeWidth(Ty), TI.getTypeConstantSuffix(Ty), + TI.isTypeSigned(Ty), Builder); +} + /// An interface for collecting the dependencies of a compilation. Users should /// use \c attachToPreprocessor and \c attachToASTReader to get all of the /// dependencies. diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 7c4e35634e5d..985ef011f301 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -272,6 +272,11 @@ static TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple, TLII->addVectorizableFunctionsFromVecLib( TargetLibraryInfoImpl::DarwinLibSystemM); break; +#ifdef ENABLE_CLASSIC_FLANG + case CodeGenOptions::PGMATH: + TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::PGMATH); + break; +#endif default: break; } diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 94c48316add7..ff4496a6ee18 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -3840,7 +3840,8 @@ CGDebugInfo::getGlobalVariableForwardDeclaration(const VarDecl *VD) { auto Align = getDeclAlignIfRequired(VD, CGM.getContext()); auto *GV = DBuilder.createTempGlobalVariableFwdDecl( DContext, Name, LinkageName, Unit, Line, getOrCreateType(T, Unit), - !VD->isExternallyVisible(), nullptr, TemplateParameters, Align); + !VD->isExternallyVisible(), nullptr, TemplateParameters, + llvm::DINode::FlagZero, Align); FwdDeclReplaceMap.emplace_back( std::piecewise_construct, std::make_tuple(cast(VD->getCanonicalDecl())), @@ -5311,7 +5312,7 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, Var->hasLocalLinkage(), true, Expr.empty() ? nullptr : DBuilder.createExpression(Expr), getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters, - Align, Annotations); + llvm::DINode::FlagZero, Align, Annotations); Var->addDebugInfo(GVE); } DeclCache[D->getCanonicalDecl()].reset(GVE); @@ -5399,7 +5400,7 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) { GV.reset(DBuilder.createGlobalVariableExpression( DContext, Name, StringRef(), Unit, getLineNumber(VD->getLocation()), Ty, true, true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD), - TemplateParameters, Align)); + TemplateParameters, llvm::DINode::FlagZero, Align)); } void CGDebugInfo::EmitExternalVariable(llvm::GlobalVariable *Var, @@ -5417,7 +5418,8 @@ void CGDebugInfo::EmitExternalVariable(llvm::GlobalVariable *Var, llvm::DIGlobalVariableExpression *GVE = DBuilder.createGlobalVariableExpression( DContext, Name, StringRef(), Unit, getLineNumber(D->getLocation()), - Ty, false, false, nullptr, nullptr, nullptr, Align); + Ty, false, false, nullptr, nullptr, nullptr, llvm::DINode::FlagZero, + Align); Var->addDebugInfo(GVE); } diff --git a/clang/lib/Driver/Action.cpp b/clang/lib/Driver/Action.cpp index ead3a23da418..d77b525cd8b0 100644 --- a/clang/lib/Driver/Action.cpp +++ b/clang/lib/Driver/Action.cpp @@ -30,6 +30,7 @@ const char *Action::getClassName(ActionClass AC) { return "api-extractor"; case AnalyzeJobClass: return "analyzer"; case MigrateJobClass: return "migrator"; + case FortranFrontendJobClass: return "fortran-frontend"; case CompileJobClass: return "compiler"; case BackendJobClass: return "backend"; case AssembleJobClass: return "assembler"; @@ -363,6 +364,12 @@ void MigrateJobAction::anchor() {} MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType) : JobAction(MigrateJobClass, Input, OutputType) {} +void FortranFrontendJobAction::anchor() {} + +FortranFrontendJobAction::FortranFrontendJobAction(Action *Input, + types::ID OutputType) + : JobAction(FortranFrontendJobClass, Input, OutputType) {} + void CompileJobAction::anchor() {} CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType) diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt index 18c9b2d042f6..24a795ba09ad 100644 --- a/clang/lib/Driver/CMakeLists.txt +++ b/clang/lib/Driver/CMakeLists.txt @@ -12,6 +12,10 @@ if(WIN32) set(system_libs version) endif() +if(LLVM_ENABLE_CLASSIC_FLANG) + set(CLASSIC_FLANG_FILES ToolChains/ClassicFlang.cpp) +endif() + add_clang_library(clangDriver Action.cpp Compilation.cpp @@ -86,6 +90,7 @@ add_clang_library(clangDriver ToolChains/ZOS.cpp Types.cpp XRayArgs.cpp + ${CLASSIC_FLANG_FILES} DEPENDS ClangDriverOptions diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 3f29afd35971..e5a4aa955f63 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -333,11 +333,30 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, // -{E,EP,P,M,MM} only run the preprocessor. if (CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) || +#ifdef ENABLE_CLASSIC_FLANG + (PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) || +#endif (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) || (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) || (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) || CCGenDiagnostics) { +#ifdef ENABLE_CLASSIC_FLANG + // -fsyntax-only or -E stops Fortran compilation after FortranFrontend + if (IsFlangMode() && (DAL.getLastArg(options::OPT_E) || + DAL.getLastArg(options::OPT_fsyntax_only))) { + FinalPhase = phases::FortranFrontend; + + // if not Fortran, fsyntax_only implies 'Compile' is the FinalPhase + } else if (DAL.getLastArg(options::OPT_fsyntax_only)) { + FinalPhase = phases::Compile; + + // everything else has 'Preprocess' as its FinalPhase + } else { + FinalPhase = phases::Preprocess; + } +#else FinalPhase = phases::Preprocess; +#endif // --precompile only runs up to precompilation. // Options that cause the output of C++20 compiled module interfaces or @@ -347,9 +366,15 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, (PhaseArg = DAL.getLastArg(options::OPT_fmodule_header, options::OPT_fmodule_header_EQ))) { FinalPhase = phases::Precompile; + +#ifdef ENABLE_CLASSIC_FLANG + // -{analyze,emit-ast} only run up to the compiler. + } else if ((PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) || +#else // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler. } else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) || (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) || +#endif (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) || (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) || (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) || @@ -2481,7 +2506,11 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, // stdin must be handled specially. if (memcmp(Value, "-", 2) == 0) { if (IsFlangMode()) { +#ifdef ENABLE_CLASSIC_FLANG + Ty = types::TY_C; +#else Ty = types::TY_Fortran; +#endif } else { // If running with -E, treat as a C input (this changes the // builtin macros, for example). This may be overridden by -ObjC @@ -3938,6 +3967,11 @@ void Driver::handleArguments(Compilation &C, DerivedArgList &Args, if (InputArg->isClaimed()) continue; + // Fortran input is preprocessed using the frontend. + if (InitialPhase == phases::FortranFrontend && + FinalPhase == phases::Preprocess) + continue; + // Claim here to avoid the more general unused warning. InputArg->claim(); @@ -4607,6 +4641,13 @@ Action *Driver::ConstructPhaseAction( ModName); return C.MakeAction(Input, OutputTy); } + case phases::FortranFrontend: { + if (Args.hasArg(options::OPT_fsyntax_only)) + return C.MakeAction(Input, + types::TY_Nothing); + return C.MakeAction(Input, + types::TY_LLVM_IR); + } case phases::Compile: { if (Args.hasArg(options::OPT_fsyntax_only)) return C.MakeAction(Input, types::TY_Nothing); diff --git a/clang/lib/Driver/Phases.cpp b/clang/lib/Driver/Phases.cpp index 01598c59bd9e..f0216c5ab7c2 100644 --- a/clang/lib/Driver/Phases.cpp +++ b/clang/lib/Driver/Phases.cpp @@ -16,6 +16,7 @@ const char *phases::getPhaseName(ID Id) { switch (Id) { case Preprocess: return "preprocessor"; case Precompile: return "precompiler"; + case FortranFrontend: return "fortran-frontend"; case Compile: return "compiler"; case Backend: return "backend"; case Assemble: return "assembler"; diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 7a4319ea680f..8626c338dda3 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -9,6 +9,7 @@ #include "clang/Driver/ToolChain.h" #include "ToolChains/Arch/ARM.h" #include "ToolChains/Clang.h" +#include "ToolChains/ClassicFlang.h" #include "ToolChains/Flang.h" #include "ToolChains/InterfaceStubs.h" #include "clang/Basic/ObjCRuntime.h" @@ -321,6 +322,16 @@ Tool *ToolChain::getAssemble() const { return Assemble.get(); } +Tool *ToolChain::getFortranFrontend() const { +#ifdef ENABLE_CLASSIC_FLANG + if (!FortranFrontend) + FortranFrontend.reset(new tools::ClassicFlang(*this)); + return FortranFrontend.get(); +#else + llvm_unreachable("Fortran is not supported by this toolchain"); +#endif +} + Tool *ToolChain::getClangAs() const { if (!Assemble) Assemble.reset(new tools::ClangAs(*this)); @@ -412,6 +423,9 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const { return getOffloadPackager(); case Action::LinkerWrapperJobClass: return getLinkerWrapper(); + + case Action::FortranFrontendJobClass: + return getFortranFrontend(); } llvm_unreachable("Invalid tool kind."); @@ -686,13 +700,13 @@ std::string ToolChain::GetStaticLibToolPath() const { types::ID ToolChain::LookupTypeForExtension(StringRef Ext) const { types::ID id = types::lookupTypeForExtension(Ext); - +#ifndef ENABLE_CLASSIC_FLANG // Flang always runs the preprocessor and has no notion of "preprocessed // fortran". Here, TY_PP_Fortran is coerced to TY_Fortran to avoid treating // them differently. if (D.IsFlangMode() && id == types::TY_PP_Fortran) id = types::TY_Fortran; - +#endif return id; } @@ -1035,6 +1049,45 @@ void ToolChain::AddCCKextLibArgs(const ArgList &Args, CmdArgs.push_back("-lcc_kext"); } +void ToolChain::AddFortranStdlibLibArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + bool staticFlangLibs = false; + bool useOpenMP = false; + + if (Args.hasArg(options::OPT_staticFlangLibs)) { + for (auto *A: Args.filtered(options::OPT_staticFlangLibs)) { + A->claim(); + staticFlangLibs = true; + } + } + + Arg *A = Args.getLastArg(options::OPT_mp, options::OPT_nomp, + options::OPT_fopenmp, options::OPT_fno_openmp); + if (A && + (A->getOption().matches(options::OPT_mp) || + A->getOption().matches(options::OPT_fopenmp))) { + useOpenMP = true; + } + + if (staticFlangLibs) + CmdArgs.push_back("-Bstatic"); + CmdArgs.push_back("-lflang"); + CmdArgs.push_back("-lflangrti"); + CmdArgs.push_back("-lpgmath"); + if (useOpenMP) + CmdArgs.push_back("-lomp"); + else + CmdArgs.push_back("-lompstub"); + if (staticFlangLibs) + CmdArgs.push_back("-Bdynamic"); + + CmdArgs.push_back("-lm"); + CmdArgs.push_back("-lrt"); + + // Allways link Fortran executables with Pthreads + CmdArgs.push_back("-lpthread"); +} + bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args, std::string &Path) const { // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 3704ed858668..1f7b81a6f04b 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5096,7 +5096,68 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } +#ifdef ENABLE_CLASSIC_FLANG + if (Args.getLastArg(options::OPT_fveclib)) + Args.AddLastArg(CmdArgs, options::OPT_fveclib); + else + CmdArgs.push_back("-fveclib=PGMATH"); +#else Args.AddLastArg(CmdArgs, options::OPT_fveclib); +#endif + + std::string PassRemarkVal(""), PassRemarkOpt(""); + if (Args.getLastArg(options::OPT_Minfoall)) { + PassRemarkVal = ".*"; + Args.ClaimAllArgs(options::OPT_Minfoall); + } else if (Arg *A = Args.getLastArg(options::OPT_Minfo_EQ)) { + for (const StringRef &val : A->getValues()) { + if (val.equals("all")) { + PassRemarkVal = ".*"; + break; + } else if (val.equals("inline") || val.equals("vect")) { + PassRemarkVal += PassRemarkVal.empty() ? "" : "|"; + PassRemarkVal += val; + } else { + D.Diag(diag::err_drv_clang_unsupported_minfo_arg) + << A->getOption().getName() + << val.str(); + break; + } + } + } + PassRemarkOpt = "-pass-remarks=" + PassRemarkVal; + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString(PassRemarkOpt)); + Args.ClaimAllArgs(options::OPT_Minfo_EQ); + PassRemarkVal.clear(); + PassRemarkOpt.clear(); + + if (Args.getLastArg(options::OPT_Mneginfoall)) { + PassRemarkVal = ".*"; + Args.ClaimAllArgs(options::OPT_Mneginfoall); + } else if (Arg *A = Args.getLastArg(options::OPT_Mneginfo_EQ)) { + for (const StringRef &val : A->getValues()) { + if (val.equals("all")) { + PassRemarkVal = ".*"; + break; + } else if (val.equals("inline") || val.equals("vect")) { + PassRemarkVal += PassRemarkVal.empty() ? "" : "|"; + PassRemarkVal += val; + } else { + D.Diag(diag::err_drv_clang_unsupported_minfo_arg) + << A->getOption().getName() + << val.str(); + break; + } + } + } + PassRemarkOpt = "-pass-remarks-missed=" + PassRemarkVal; + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString(PassRemarkOpt)); + PassRemarkOpt = "-pass-remarks-analysis=" + PassRemarkVal; + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString(PassRemarkOpt)); + Args.ClaimAllArgs(options::OPT_Mneginfo_EQ); if (Args.hasFlag(options::OPT_fmerge_all_constants, options::OPT_fno_merge_all_constants, false)) diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp new file mode 100644 index 000000000000..a68ec58e5e66 --- /dev/null +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -0,0 +1,1064 @@ +//===-- ClassicFlang.cpp - Flang+LLVM ToolChain Implementations -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ClassicFlang.h" +#include "CommonArgs.h" +#include "clang/Driver/InputInfo.h" +#include "clang/Basic/CharInfo.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/MacroBuilder.h" +#include "clang/Basic/ObjCRuntime.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/Basic/TargetOptions.h" +#include "clang/Basic/Version.h" +#include "clang/Config/config.h" +#include "clang/Driver/DriverDiagnostic.h" +#include "clang/Driver/Options.h" +#include "clang/Driver/SanitizerArgs.h" +#include "clang/Driver/XRayArgs.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/Utils.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Support/CodeGen.h" +#include "llvm/Support/Compression.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/Process.h" +#include "llvm/Support/TargetParser.h" +#include "llvm/Support/YAMLParser.h" + +#ifdef LLVM_ON_UNIX +#include // For getuid(). +#endif + +using namespace clang::driver; +using namespace clang::driver::tools; +using namespace clang; +using namespace llvm::opt; + +class ClassicFlangMacroBuilder : public MacroBuilder { + ArgStringList &CmdArgs; + const ArgList &DriverArgs; + public: + ClassicFlangMacroBuilder(ArgStringList &UpperCmdArgs, const ArgList &DriverArgs, llvm::raw_string_ostream &Output) + : MacroBuilder(Output), CmdArgs(UpperCmdArgs), DriverArgs(DriverArgs) { + } + virtual void defineMacro(const Twine &Name, const Twine &Value = "1") { + CmdArgs.push_back("-def"); + CmdArgs.push_back(DriverArgs.MakeArgString(Name + Twine('=') + Value)); + } +}; + +void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const ArgList &Args, const char *LinkingOutput) const { + ArgStringList CommonCmdArgs; + ArgStringList UpperCmdArgs; + ArgStringList LowerCmdArgs; + SmallString<256> Stem; + std::string OutFile; + bool NeedIEEE = false; + bool NeedFastMath = false; + bool NeedRelaxedMath = false; + + // Check number of inputs for sanity. We need at least one input. + assert(Inputs.size() >= 1 && "Must have at least one input."); + + /***** Process file arguments to both parts *****/ + const InputInfo &Input = Inputs[0]; + types::ID InputType = Input.getType(); + // Check file type sanity + assert(types::isAcceptedByFlang(InputType) && "Can only accept Fortran"); + + if (Args.hasArg(options::OPT_fsyntax_only)) { + // For -fsyntax-only produce temp files only + Stem = C.getDriver().GetTemporaryPath("", ""); + } else { + OutFile = Output.getFilename(); + Stem = llvm::sys::path::filename(OutFile); + llvm::sys::path::replace_extension(Stem, ""); + } + + // Add input file name to the compilation line + UpperCmdArgs.push_back(Input.getBaseInput()); + + // Add temporary output for ILM + const char * ILMFile = Args.MakeArgString(Stem + ".ilm"); + LowerCmdArgs.push_back(ILMFile); + C.addTempFile(ILMFile); + + // Generate -cmdline + std::string CmdLine("'+flang"); + // ignore the first argument which reads "--driver-mode=fortran" + for (unsigned i = 1; i < Args.getNumInputArgStrings(); ++i) { + CmdLine.append(" "); + CmdLine.append(Args.getArgString(i)); + } + CmdLine.append("'"); + + CommonCmdArgs.push_back("-cmdline"); + CommonCmdArgs.push_back(Args.MakeArgString(CmdLine)); + + /***** Process common args *****/ + + // Add "inform level" flag + if (Args.hasArg(options::OPT_Minform_EQ)) { + // Parse arguments to set its value + for (Arg *A : Args.filtered(options::OPT_Minform_EQ)) { + A->claim(); + CommonCmdArgs.push_back("-inform"); + CommonCmdArgs.push_back(A->getValue(0)); + } + } else { + // Default value + CommonCmdArgs.push_back("-inform"); + CommonCmdArgs.push_back("warn"); + } + + for (auto Arg : Args.filtered(options::OPT_Msave_on)) { + Arg->claim(); + CommonCmdArgs.push_back("-save"); + } + + for (auto Arg : Args.filtered(options::OPT_Msave_off)) { + Arg->claim(); + CommonCmdArgs.push_back("-nosave"); + } + + // Treat denormalized numbers as zero: On + for (auto Arg : Args.filtered(options::OPT_Mdaz_on)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("129"); + CommonCmdArgs.push_back("4"); + CommonCmdArgs.push_back("-y"); + CommonCmdArgs.push_back("129"); + CommonCmdArgs.push_back("0x400"); + } + + // Treat denormalized numbers as zero: Off + for (auto Arg : Args.filtered(options::OPT_Mdaz_off)) { + Arg->claim(); + CommonCmdArgs.push_back("-y"); + CommonCmdArgs.push_back("129"); + CommonCmdArgs.push_back("4"); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("129"); + CommonCmdArgs.push_back("0x400"); + } + + // Store constants in writable data segment + for (auto Arg : Args.filtered(options::OPT_Mwritable_constants)) { + Arg->claim(); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("183"); + LowerCmdArgs.push_back("0x20000000"); + } + + // Bounds checking: On + for (auto Arg : Args.filtered(options::OPT_Mbounds_on)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("70"); + CommonCmdArgs.push_back("2"); + } + + // Bounds checking: Off + for (auto Arg : Args.filtered(options::OPT_Mbounds_off)) { + Arg->claim(); + CommonCmdArgs.push_back("-y"); + CommonCmdArgs.push_back("70"); + CommonCmdArgs.push_back("2"); + } + + // Generate code allowing recursive subprograms + for (auto Arg : Args.filtered(options::OPT_Mrecursive_on)) { + Arg->claim(); + CommonCmdArgs.push_back("-recursive"); + } + + // Disable recursive subprograms + for (auto Arg : Args.filtered(options::OPT_Mrecursive_off)) { + Arg->claim(); + CommonCmdArgs.push_back("-norecursive"); + } + + // Enable generating reentrant code (disable optimizations that inhibit it) + for (auto Arg : Args.filtered(options::OPT_Mreentrant_on)) { + Arg->claim(); + CommonCmdArgs.push_back("-reentrant"); + } + + // Allow optimizations inhibiting reentrancy + for (auto Arg : Args.filtered(options::OPT_Mreentrant_off)) { + Arg->claim(); + CommonCmdArgs.push_back("-noreentrant"); + } + + // Swap byte order for unformatted IO + for (auto Arg : Args.filtered(options::OPT_Mbyteswapio, options::OPT_byteswapio)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("125"); + CommonCmdArgs.push_back("2"); + } + + // Contiguous pointer checks + if (Arg *A = Args.getLastArg(options::OPT_fsanitize_EQ)) { + for (const StringRef &val : A->getValues()) { + if (val.equals("discontiguous") || val.equals("undefined") ) { + // -x 54 0x40 -x 54 0x80 -x 54 0x200 + UpperCmdArgs.push_back("-x"); + UpperCmdArgs.push_back("54"); + UpperCmdArgs.push_back("0x2c0"); + + // -fsanitze=discontiguous has no meaning in LLVM, only flang driver needs to + // recognize it. However -fsanitize=undefined needs to be passed on for further + // processing by the non-flang part of the driver. + if (val.equals("discontiguous")) + A->claim(); + break; + } + } + } + + // Treat backslashes as regular characters + for (auto Arg : Args.filtered(options::OPT_fno_backslash, options::OPT_Mbackslash)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("124"); + CommonCmdArgs.push_back("0x40"); + } + + // Treat backslashes as C-style escape characters + for (auto Arg : Args.filtered(options::OPT_fbackslash, options::OPT_Mnobackslash)) { + Arg->claim(); + CommonCmdArgs.push_back("-y"); + CommonCmdArgs.push_back("124"); + CommonCmdArgs.push_back("0x40"); + } + + // handle OpemMP options + if (auto *A = Args.getLastArg(options::OPT_mp, options::OPT_nomp, + options::OPT_fopenmp, options::OPT_fno_openmp)) { + for (auto Arg : Args.filtered(options::OPT_mp, options::OPT_nomp)) { + Arg->claim(); + } + for (auto Arg : Args.filtered(options::OPT_fopenmp, + options::OPT_fno_openmp)) { + Arg->claim(); + } + + if (A->getOption().matches(options::OPT_mp) || + A->getOption().matches(options::OPT_fopenmp)) { + + CommonCmdArgs.push_back("-mp"); + + // Allocate threadprivate data local to the thread + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("69"); + CommonCmdArgs.push_back("0x200"); + + // Use the 'fair' schedule as the default static schedule + // for parallel do loops + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("69"); + CommonCmdArgs.push_back("0x400"); + + // Disable use of native atomic instructions + // for OpenMP atomics pending either a named + // option or a libatomic bundled with flang. + UpperCmdArgs.push_back("-x"); + UpperCmdArgs.push_back("69"); + UpperCmdArgs.push_back("0x1000"); + } + } + + // Align large objects on cache lines + for (auto Arg : Args.filtered(options::OPT_Mcache_align_on)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("119"); + CommonCmdArgs.push_back("0x10000000"); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("129"); + LowerCmdArgs.push_back("0x40000000"); + } + + // Disable special alignment of large objects + for (auto Arg : Args.filtered(options::OPT_Mcache_align_off)) { + Arg->claim(); + CommonCmdArgs.push_back("-y"); + CommonCmdArgs.push_back("119"); + CommonCmdArgs.push_back("0x10000000"); + LowerCmdArgs.push_back("-y"); + LowerCmdArgs.push_back("129"); + LowerCmdArgs.push_back("0x40000000"); + } + + // -Mstack_arrays + for (auto Arg : Args.filtered(options::OPT_Mstackarrays)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("54"); + CommonCmdArgs.push_back("8"); + } + + // -Memit-dwarf-common-blocks-name, only add xbit to flang2. + for (auto Arg : Args.filtered(options::OPT_Memit_dwarf_common_blocks_name)) { + Arg->claim(); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("183"); + LowerCmdArgs.push_back("0x40000000"); + } + + // -Munixlogical, only add xbit to flang2. + for (auto Arg : Args.filtered(options::OPT_Munixlogical)) { + Arg->claim(); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("125"); + LowerCmdArgs.push_back("0x8"); + } + + // -g should produce DWARFv2 + for (auto Arg : Args.filtered(options::OPT_g_Flag)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("120"); + CommonCmdArgs.push_back("0x200"); + } + + // -gdwarf-2 + for (auto Arg : Args.filtered(options::OPT_gdwarf_2)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("120"); + CommonCmdArgs.push_back("0x200"); + } + + // -gdwarf-3 + for (auto Arg : Args.filtered(options::OPT_gdwarf_3)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("120"); + CommonCmdArgs.push_back("0x4000"); + } + + // -Mipa has no effect + if (Arg *A = Args.getLastArg(options::OPT_Mipa)) { + getToolChain().getDriver().Diag(diag::warn_drv_clang_unsupported) + << A->getAsString(Args); + } + + // -Minline has no effect + if (Arg *A = Args.getLastArg(options::OPT_Minline_on)) { + getToolChain().getDriver().Diag(diag::warn_drv_clang_unsupported) + << A->getAsString(Args); + } + + // Handle -fdefault-real-8 (and its alias, -r8) and -fno-default-real-8 + if (Arg *A = Args.getLastArg(options::OPT_r8, + options::OPT_fdefault_real_8, + options::OPT_default_real_8_fno)) { + const char * fl; + // For -f version add -x flag, for -fno add -y + if (A->getOption().matches(options::OPT_default_real_8_fno)) { + fl = "-y"; + } else { + fl = "-x"; + } + + for (Arg *A : Args.filtered(options::OPT_r8, + options::OPT_fdefault_real_8, + options::OPT_default_real_8_fno)) { + A->claim(); + } + + UpperCmdArgs.push_back(fl); + UpperCmdArgs.push_back("124"); + UpperCmdArgs.push_back("0x8"); + UpperCmdArgs.push_back(fl); + UpperCmdArgs.push_back("124"); + UpperCmdArgs.push_back("0x80000"); + } + + // Process and claim -i8/-fdefault-integer-8/-fno-default-integer-8 argument + if (Arg *A = Args.getLastArg(options::OPT_i8, + options::OPT_fdefault_integer_8, + options::OPT_default_integer_8_fno)) { + const char * fl; + + if (A->getOption().matches(options::OPT_default_integer_8_fno)) { + fl = "-y"; + } else { + fl = "-x"; + } + + for (Arg *A : Args.filtered(options::OPT_i8, + options::OPT_fdefault_integer_8, + options::OPT_default_integer_8_fno)) { + A->claim(); + } + + UpperCmdArgs.push_back(fl); + UpperCmdArgs.push_back("124"); + UpperCmdArgs.push_back("0x10"); + } + + // Pass an arbitrary flag for first part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_Wh_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + SmallVector PassArgs; + Value.split(PassArgs, StringRef(",")); + for (StringRef PassArg : PassArgs) { + UpperCmdArgs.push_back(Args.MakeArgString(PassArg)); + } + } + + // Flush to zero mode + // Disabled by default, but can be enabled by a switch + if (Args.hasArg(options::OPT_Mflushz_on)) { + // For -Mflushz set -x 129 2 for second part of Fortran frontend + for (Arg *A: Args.filtered(options::OPT_Mflushz_on)) { + A->claim(); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("129"); + LowerCmdArgs.push_back("2"); + } + } else { + LowerCmdArgs.push_back("-y"); + LowerCmdArgs.push_back("129"); + LowerCmdArgs.push_back("2"); + for (Arg *A: Args.filtered(options::OPT_Mflushz_off)) { + A->claim(); + } + } + + // Enable FMA + for (Arg *A: Args.filtered(options::OPT_Mfma_on, options::OPT_fma)) { + A->claim(); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("172"); + LowerCmdArgs.push_back("0x40000000"); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("179"); + LowerCmdArgs.push_back("1"); + } + + // Disable FMA + for (Arg *A: Args.filtered(options::OPT_Mfma_off, options::OPT_nofma)) { + A->claim(); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("171"); + LowerCmdArgs.push_back("0x40000000"); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("178"); + LowerCmdArgs.push_back("1"); + } + + // For -fPIC set -x 62 8 for second part of Fortran frontend + for (Arg *A: Args.filtered(options::OPT_fPIC)) { + A->claim(); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("62"); + LowerCmdArgs.push_back("8"); + } + + StringRef OptOStr("0"); + if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { + if (A->getOption().matches(options::OPT_O4)) { + OptOStr = "4"; // FIXME what should this be? + } else if (A->getOption().matches(options::OPT_Ofast)) { + OptOStr = "2"; // FIXME what should this be? + } else if (A->getOption().matches(options::OPT_O0)) { + // intentionally do nothing + } else { + assert(A->getOption().matches(options::OPT_O) && "Must have a -O flag"); + StringRef S(A->getValue()); + if ((S == "s") || (S == "z")) { + // -Os = size; -Oz = more size + OptOStr = "2"; // FIXME -Os|-Oz => -opt ? + } else if ((S == "1") || (S == "2") || (S == "3")) { + OptOStr = S; + } else { + OptOStr = "4"; + } + } + } + unsigned OptLevel = std::stoi(OptOStr.str()); + + if (Args.hasArg(options::OPT_g_Group)) { + // pass -g to lower and upper + CommonCmdArgs.push_back("-debug"); + } + + /* Pick the last among conflicting flags, if a positive and negative flag + exists for ex. "-ffast-math -fno-fast-math" they get nullified. Also any + previously overwritten flag remains that way. + For ex. "-Kieee -ffast-math -fno-fast-math". -Kieee gets overwritten by + -ffast-math which then gets negated by -fno-fast-math, finally behaving as + if none of those flags were passed. + */ + for(Arg *A: Args.filtered(options::OPT_ffast_math, options::OPT_fno_fast_math, + options::OPT_Ofast, options::OPT_Kieee_off, + options::OPT_Kieee_on, options::OPT_frelaxed_math)) { + if (A->getOption().matches(options::OPT_ffast_math) || + A->getOption().matches(options::OPT_Ofast)) { + NeedIEEE = NeedRelaxedMath = false; + NeedFastMath = true; + } else if (A->getOption().matches(options::OPT_Kieee_on)) { + NeedFastMath = NeedRelaxedMath = false; + NeedIEEE = true; + } else if (A->getOption().matches(options::OPT_frelaxed_math)) { + NeedFastMath = NeedIEEE = false; + NeedRelaxedMath = true; + } else if (A->getOption().matches(options::OPT_fno_fast_math)) { + NeedFastMath = false; + } else if (A->getOption().matches(options::OPT_Kieee_off)) { + NeedIEEE = false; + } + A->claim(); + } + + if (NeedFastMath) { + // Lower: -x 216 1 + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("216"); + LowerCmdArgs.push_back("1"); + // Lower: -ieee 0 + CommonCmdArgs.push_back("-ieee"); + CommonCmdArgs.push_back("0"); + } else if (NeedIEEE) { + // Common: -y 129 2 + CommonCmdArgs.push_back("-y"); + CommonCmdArgs.push_back("129"); + CommonCmdArgs.push_back("2"); + // Lower: -x 6 0x100 + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("6"); + LowerCmdArgs.push_back("0x100"); + // Lower: -x 42 0x400000 + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("42"); + LowerCmdArgs.push_back("0x400000"); + // Lower: -y 129 4 + LowerCmdArgs.push_back("-y"); + LowerCmdArgs.push_back("129"); + LowerCmdArgs.push_back("4"); + // Lower: -x 129 0x400 + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("129"); + LowerCmdArgs.push_back("0x400"); + // Lower: -y 216 1 (OPT_fno_fast_math) + LowerCmdArgs.push_back("-y"); + LowerCmdArgs.push_back("216"); + LowerCmdArgs.push_back("1"); + // Lower: -ieee 1 + CommonCmdArgs.push_back("-ieee"); + CommonCmdArgs.push_back("1"); + } else if (NeedRelaxedMath) { + // Lower: -x 15 0x400 + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("15"); + LowerCmdArgs.push_back("0x400"); + // Lower: -y 216 1 (OPT_fno_fast_math) + LowerCmdArgs.push_back("-y"); + LowerCmdArgs.push_back("216"); + LowerCmdArgs.push_back("1"); + // Lower: -ieee 0 + CommonCmdArgs.push_back("-ieee"); + CommonCmdArgs.push_back("0"); + } else { + // Lower: -ieee 0 + CommonCmdArgs.push_back("-ieee"); + CommonCmdArgs.push_back("0"); + } + + /***** Upper part of the Fortran frontend *****/ + + // TODO do we need to invoke this under GDB sometimes? + const char *UpperExec = Args.MakeArgString(getToolChain().GetProgramPath("flang1")); + + UpperCmdArgs.push_back("-opt"); UpperCmdArgs.push_back(Args.MakeArgString(OptOStr)); + UpperCmdArgs.push_back("-terse"); UpperCmdArgs.push_back("1"); + UpperCmdArgs.push_back("-inform"); UpperCmdArgs.push_back("warn"); + UpperCmdArgs.push_back("-nohpf"); + UpperCmdArgs.push_back("-nostatic"); + UpperCmdArgs.append(CommonCmdArgs.begin(), CommonCmdArgs.end()); // Append common arguments + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("19"); UpperCmdArgs.push_back("0x400000"); + UpperCmdArgs.push_back("-quad"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("68"); UpperCmdArgs.push_back("0x1"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("59"); UpperCmdArgs.push_back("4"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("15"); UpperCmdArgs.push_back("2"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("49"); UpperCmdArgs.push_back("0x400004"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("51"); UpperCmdArgs.push_back("0x20"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("57"); UpperCmdArgs.push_back("0x4c"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("58"); UpperCmdArgs.push_back("0x10000"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("124"); UpperCmdArgs.push_back("0x1000"); + UpperCmdArgs.push_back("-tp"); UpperCmdArgs.push_back("px"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("57"); UpperCmdArgs.push_back("0xfb0000"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("58"); UpperCmdArgs.push_back("0x78031040"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("47"); UpperCmdArgs.push_back("0x08"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("48"); UpperCmdArgs.push_back("4608"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("49"); UpperCmdArgs.push_back("0x100"); + if (OptLevel >= 2) { + UpperCmdArgs.push_back("-x"); + UpperCmdArgs.push_back("70"); + UpperCmdArgs.push_back("0x6c00"); + UpperCmdArgs.push_back("-x"); + UpperCmdArgs.push_back("119"); + UpperCmdArgs.push_back("0x10000000"); + UpperCmdArgs.push_back("-x"); + UpperCmdArgs.push_back("129"); + UpperCmdArgs.push_back("2"); + UpperCmdArgs.push_back("-x"); + UpperCmdArgs.push_back("47"); + UpperCmdArgs.push_back("0x400000"); + UpperCmdArgs.push_back("-x"); + UpperCmdArgs.push_back("52"); + UpperCmdArgs.push_back("2"); + } + + // Add system include arguments. + getToolChain().AddFlangSystemIncludeArgs(Args, UpperCmdArgs); + + // Use clang's predefined macros + DiagnosticsEngine DE(new DiagnosticIDs(), new DiagnosticOptions, new IgnoringDiagConsumer()); + std::shared_ptr TO = std::make_shared(); + TO->Triple = getToolChain().getEffectiveTriple().getTriple(); + std::shared_ptr TI(clang::TargetInfo::CreateTargetInfo(DE, TO)); + std::string PredefineBuffer; + llvm::raw_string_ostream Predefines(PredefineBuffer); + ClassicFlangMacroBuilder Builder(UpperCmdArgs, Args, Predefines); + + LangOptions LO; + VersionTuple VT = getToolChain().computeMSVCVersion(&getToolChain().getDriver(), Args); + if (!VT.empty()) { + // Set the MSCompatibility version. Subminor version has 5 decimal digits. + // Minor and major versions have 2 decimal digits each. + LO.MSCompatibilityVersion = VT.getMajor() * 10000000 + + VT.getMinor().value_or(0) * 100000 + + VT.getSubminor().value_or(0); + } + + // Define Target specific macros like __linux__ + TI->getTargetDefines(LO, Builder); + + Builder.defineMacro("__SIZE_TYPE__", TargetInfo::getTypeName(TI->getSizeType())); + Builder.defineMacro("__PTRDIFF_TYPE__", TargetInfo::getTypeName(TI->getPtrDiffType(0))); + + if (TI->getPointerWidth(0) == 64 && TI->getLongWidth() == 64 + && TI->getIntWidth() == 32) { + Builder.defineMacro("_LP64"); + Builder.defineMacro("__LP64__"); + } + + if (TI->getPointerWidth(0) == 32 && TI->getLongWidth() == 32 + && TI->getIntWidth() == 32) { + Builder.defineMacro("_ILP32"); + Builder.defineMacro("__ILP32__"); + } + + DefineTypeSize("__LONG_MAX__", TargetInfo::SignedLong, *TI, Builder); + + // Add additional predefined macros + switch (getToolChain().getEffectiveTriple().getArch()) { + case llvm::Triple::aarch64: + UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__ARM_ARCH__=8"); + break; + case llvm::Triple::x86_64: + UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__amd_64__amd64__"); + UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__k8"); + UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__k8__"); + break; + default: /* generic 64-bit */ + ; + } + UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__THROW="); + UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__extension__="); + UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__PGLLVM__"); + + // Enable preprocessor + if (Args.hasArg(options::OPT_Mpreprocess) || + Args.hasArg(options::OPT_cpp) || + Args.hasArg(options::OPT_E) || + types::getPreprocessedType(InputType) != types::TY_INVALID) { + UpperCmdArgs.push_back("-preprocess"); + for (auto Arg : Args.filtered(options::OPT_Mpreprocess, options::OPT_cpp, options::OPT_E)) { + Arg->claim(); + } + + // When -E option is provided, run only the fortran preprocessor. + // Only in -E mode, consume -P if it exists + if (Args.hasArg(options::OPT_E)) { + UpperCmdArgs.push_back("-es"); + // Line marker mode is disabled + if (Args.hasArg(options::OPT_P)) { + Args.ClaimAllArgs(options::OPT_P); + } else { + // -pp enables line marker mode in fortran preprocessor + UpperCmdArgs.push_back("-pp"); + } + } + } + + // Enable standards checking + if (Args.hasArg(options::OPT_Mstandard)) { + UpperCmdArgs.push_back("-standard"); + for (auto Arg : Args.filtered(options::OPT_Mstandard)) { + Arg->claim(); + } + } + + // Free or fixed form file + if (Args.hasArg(options::OPT_fortran_format_Group)) { + // Override file name suffix, scan arguments for that + for (Arg *A : Args.filtered(options::OPT_fortran_format_Group)) { + A->claim(); + switch (A->getOption().getID()) { + default: + llvm_unreachable("missed a case"); + case options::OPT_ffixed_form: + case options::OPT_free_form_off: + case options::OPT_Mfixed: + case options::OPT_Mfree_off: + case options::OPT_Mfreeform_off: + UpperCmdArgs.push_back("-nofreeform"); + break; + case options::OPT_ffree_form: + case options::OPT_fixed_form_off: + case options::OPT_Mfree_on: + case options::OPT_Mfreeform_on: + UpperCmdArgs.push_back("-freeform"); + break; + } + } + } else { + // Deduce format from file name suffix + if (types::isFreeFormFortran(InputType)) { + UpperCmdArgs.push_back("-freeform"); + } else { + UpperCmdArgs.push_back("-nofreeform"); + } + } + + // Extend lines to 132 characters + for (auto Arg : Args.filtered(options::OPT_Mextend)) { + Arg->claim(); + UpperCmdArgs.push_back("-extend"); + } + + for (auto Arg : Args.filtered(options::OPT_ffixed_line_length_VALUE)) { + StringRef Value = Arg->getValue(); + if (Value == "72") { + Arg->claim(); + } else if (Value == "132") { + Arg->claim(); + UpperCmdArgs.push_back("-extend"); + } else { + getToolChain().getDriver().Diag(diag::err_drv_unsupported_fixed_line_length) + << Arg->getAsString(Args); + } + } + + // Add user-defined include directories + for (auto Arg : Args.filtered(options::OPT_I)) { + Arg->claim(); + UpperCmdArgs.push_back("-idir"); + UpperCmdArgs.push_back(Arg->getValue(0)); + } + + // Add user-defined module directories + for (auto Arg : Args.filtered(options::OPT_ModuleDir, options::OPT_J)) { + Arg->claim(); + UpperCmdArgs.push_back("-moddir"); + UpperCmdArgs.push_back(Arg->getValue(0)); + } + + // "Define" preprocessor flags + for (auto Arg : Args.filtered(options::OPT_D)) { + Arg->claim(); + UpperCmdArgs.push_back("-def"); + UpperCmdArgs.push_back(Arg->getValue(0)); + } + + // "Define" preprocessor flags + for (auto Arg : Args.filtered(options::OPT_U)) { + Arg->claim(); + UpperCmdArgs.push_back("-undef"); + UpperCmdArgs.push_back(Arg->getValue(0)); + } + + UpperCmdArgs.push_back("-vect"); UpperCmdArgs.push_back("48"); + + // Semantics for assignments to allocatables + if (Arg *A = Args.getLastArg(options::OPT_Mallocatable_EQ)) { + // Argument is passed explicitly + StringRef Value = A->getValue(); + if (Value == "03") { // Enable Fortran 2003 semantics + UpperCmdArgs.push_back("-x"); // Set XBIT + } else if (Value == "95") { // Enable Fortran 2003 semantics + UpperCmdArgs.push_back("-y"); // Unset XBIT + } else { + getToolChain().getDriver().Diag(diag::err_drv_invalid_allocatable_mode) + << A->getAsString(Args); + } + } else { // No argument passed + UpperCmdArgs.push_back("-x"); // Default is 03 + } + UpperCmdArgs.push_back("54"); UpperCmdArgs.push_back("1"); // XBIT value + + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("70"); UpperCmdArgs.push_back("0x40000000"); + UpperCmdArgs.push_back("-y"); UpperCmdArgs.push_back("163"); UpperCmdArgs.push_back("0xc0000000"); + UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("189"); UpperCmdArgs.push_back("0x10"); + + // Enable NULL pointer checking + if (Args.hasArg(options::OPT_Mchkptr)) { + UpperCmdArgs.push_back("-x"); + UpperCmdArgs.push_back("70"); + UpperCmdArgs.push_back("4"); + for (auto Arg : Args.filtered(options::OPT_Mchkptr)) { + Arg->claim(); + } + } + + // Set a -x flag for first part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_Hx_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + auto XFlag = Value.split(","); + UpperCmdArgs.push_back("-x"); + UpperCmdArgs.push_back(Args.MakeArgString(XFlag.first)); + UpperCmdArgs.push_back(Args.MakeArgString(XFlag.second)); + } + + // Set a -y flag for first part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_Hy_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + auto XFlag = Value.split(","); + UpperCmdArgs.push_back("-y"); + UpperCmdArgs.push_back(Args.MakeArgString(XFlag.first)); + UpperCmdArgs.push_back(Args.MakeArgString(XFlag.second)); + } + + // Set a -q (debug) flag for first part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_Hq_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + auto XFlag = Value.split(","); + UpperCmdArgs.push_back("-q"); + UpperCmdArgs.push_back(Args.MakeArgString(XFlag.first)); + UpperCmdArgs.push_back(Args.MakeArgString(XFlag.second)); + } + + // Set a -qq (debug) flag for first part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_Hqq_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + auto XFlag = Value.split(","); + UpperCmdArgs.push_back("-qq"); + UpperCmdArgs.push_back(Args.MakeArgString(XFlag.first)); + UpperCmdArgs.push_back(Args.MakeArgString(XFlag.second)); + } + + const char * STBFile = Args.MakeArgString(Stem + ".stb"); + C.addTempFile(STBFile); + UpperCmdArgs.push_back("-stbfile"); + UpperCmdArgs.push_back(STBFile); + + const char * ModuleExportFile = Args.MakeArgString(Stem + ".cmod"); + C.addTempFile(ModuleExportFile); + UpperCmdArgs.push_back("-modexport"); + UpperCmdArgs.push_back(ModuleExportFile); + + const char * ModuleIndexFile = Args.MakeArgString(Stem + ".cmdx"); + C.addTempFile(ModuleIndexFile); + UpperCmdArgs.push_back("-modindex"); + UpperCmdArgs.push_back(ModuleIndexFile); + + UpperCmdArgs.push_back("-output"); + UpperCmdArgs.push_back(ILMFile); + + SmallString<256> Path; + if(Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() > 0) { + SmallString<128> TargetInfo; + Path = llvm::sys::path::parent_path(Output.getFilename()); + Arg* Tgts = Args.getLastArg(options::OPT_fopenmp_targets_EQ); + assert(Tgts && Tgts->getNumValues() && + "OpenMP offloading has to have targets specified."); + for (unsigned i = 0; i < Tgts->getNumValues(); ++i) { + if (i) + TargetInfo += ','; + llvm::Triple T(Tgts->getValue(i)); + TargetInfo += T.getTriple(); + } + UpperCmdArgs.push_back("-fopenmp-targets"); + UpperCmdArgs.push_back(Args.MakeArgString(TargetInfo.str())); + } + + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::AtFileUTF8(), UpperExec, UpperCmdArgs, Inputs)); + + // For -fsyntax-only or -E that is it + if (Args.hasArg(options::OPT_fsyntax_only) || + Args.hasArg(options::OPT_E)) return; + + /***** Lower part of Fortran frontend *****/ + + const char *LowerExec = Args.MakeArgString(getToolChain().GetProgramPath("flang2")); + + // TODO FLANG arg handling + LowerCmdArgs.push_back("-fn"); LowerCmdArgs.push_back(Input.getBaseInput()); + LowerCmdArgs.push_back("-opt"); LowerCmdArgs.push_back(Args.MakeArgString(OptOStr)); + LowerCmdArgs.push_back("-terse"); LowerCmdArgs.push_back("1"); + LowerCmdArgs.push_back("-inform"); LowerCmdArgs.push_back("warn"); + LowerCmdArgs.append(CommonCmdArgs.begin(), CommonCmdArgs.end()); // Append common arguments + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("68"); LowerCmdArgs.push_back("0x1"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("51"); LowerCmdArgs.push_back("0x20"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("119"); LowerCmdArgs.push_back("0xa10000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("122"); LowerCmdArgs.push_back("0x40"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("123"); LowerCmdArgs.push_back("0x1000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("127"); LowerCmdArgs.push_back("4"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("127"); LowerCmdArgs.push_back("17"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("19"); LowerCmdArgs.push_back("0x400000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("28"); LowerCmdArgs.push_back("0x40000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("120"); LowerCmdArgs.push_back("0x10000000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("70"); LowerCmdArgs.push_back("0x8000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("122"); LowerCmdArgs.push_back("1"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("125"); LowerCmdArgs.push_back("0x20000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("164"); LowerCmdArgs.push_back("0x800000"); + LowerCmdArgs.push_back("-quad"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("59"); LowerCmdArgs.push_back("4"); + LowerCmdArgs.push_back("-tp"); LowerCmdArgs.push_back("px"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("120"); LowerCmdArgs.push_back("0x1000"); // debug lite + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("124"); LowerCmdArgs.push_back("0x1400"); + LowerCmdArgs.push_back("-y"); LowerCmdArgs.push_back("15"); LowerCmdArgs.push_back("2"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("57"); LowerCmdArgs.push_back("0x3b0000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("58"); LowerCmdArgs.push_back("0x48000000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("49"); LowerCmdArgs.push_back("0x100"); + LowerCmdArgs.push_back("-astype"); LowerCmdArgs.push_back("0"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("183"); LowerCmdArgs.push_back("4"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("121"); LowerCmdArgs.push_back("0x800"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("54"); LowerCmdArgs.push_back("0x10"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("70"); LowerCmdArgs.push_back("0x40000000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("249"); LowerCmdArgs.push_back("150"); // LLVM version + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("124"); LowerCmdArgs.push_back("1"); + LowerCmdArgs.push_back("-y"); LowerCmdArgs.push_back("163"); LowerCmdArgs.push_back("0xc0000000"); + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("189"); LowerCmdArgs.push_back("0x10"); + LowerCmdArgs.push_back("-y"); LowerCmdArgs.push_back("189"); LowerCmdArgs.push_back("0x4000000"); + + // Remove "noinline" attriblute + LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("183"); LowerCmdArgs.push_back("0x10"); + + // Set a -x flag for second part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_Mx_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + auto XFlag = Value.split(","); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back(Args.MakeArgString(XFlag.first)); + LowerCmdArgs.push_back(Args.MakeArgString(XFlag.second)); + } + + // Set a -y flag for second part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_My_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + auto XFlag = Value.split(","); + LowerCmdArgs.push_back("-y"); + LowerCmdArgs.push_back(Args.MakeArgString(XFlag.first)); + LowerCmdArgs.push_back(Args.MakeArgString(XFlag.second)); + } + + // Set a -q (debug) flag for second part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_Mq_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + auto XFlag = Value.split(","); + LowerCmdArgs.push_back("-q"); + LowerCmdArgs.push_back(Args.MakeArgString(XFlag.first)); + LowerCmdArgs.push_back(Args.MakeArgString(XFlag.second)); + } + + // Set a -qq (debug) flag for second part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_Mqq_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + auto XFlag = Value.split(","); + LowerCmdArgs.push_back("-qq"); + LowerCmdArgs.push_back(Args.MakeArgString(XFlag.first)); + LowerCmdArgs.push_back(Args.MakeArgString(XFlag.second)); + } + + // Pass an arbitrary flag for second part of Fortran frontend + for (Arg *A : Args.filtered(options::OPT_Wm_EQ)) { + A->claim(); + StringRef Value = A->getValue(); + SmallVector PassArgs; + Value.split(PassArgs, StringRef(",")); + for (StringRef PassArg : PassArgs) { + LowerCmdArgs.push_back(Args.MakeArgString(PassArg)); + } + } + + LowerCmdArgs.push_back("-stbfile"); + LowerCmdArgs.push_back(STBFile); + + Path = llvm::sys::path::parent_path(Output.getFilename()); + bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP); + + /* OpenMP GPU Offload */ + if(Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() > 0) { + SmallString<128> TargetInfo;//("-fopenmp-targets "); + SmallString<256> TargetInfoAsm;//("-fopenmp-targets-asm "); + + Arg* Tgts = Args.getLastArg(options::OPT_fopenmp_targets_EQ); + assert(Tgts && Tgts->getNumValues() && + "OpenMP offloading has to have targets specified."); + for (unsigned i = 0; i < Tgts->getNumValues(); ++i) { + if (i) + TargetInfo += ','; + // We need to get the string from the triple because it may be not exactly + // the same as the one we get directly from the arguments. + llvm::Triple T(Tgts->getValue(i)); + TargetInfo += T.getTriple(); + // We also need to give a output file + TargetInfoAsm += Path; + TargetInfoAsm += "/"; + TargetInfoAsm += Stem; + TargetInfoAsm += "-"; + TargetInfoAsm += T.getTriple(); + TargetInfoAsm += ".ll"; + } + // The driver is aware that flang2 can generate multiple files at the same time. + // We mimic it here by exchanging the output files. + // The driver always uses the output file of -asm. + LowerCmdArgs.push_back("-fopenmp-targets"); + LowerCmdArgs.push_back(Args.MakeArgString(TargetInfo.str())); + if(IsOpenMPDevice) { + LowerCmdArgs.push_back("-fopenmp-targets-asm"); + LowerCmdArgs.push_back(Args.MakeArgString(OutFile)); + LowerCmdArgs.push_back("-asm"); + LowerCmdArgs.push_back(Args.MakeArgString(TargetInfoAsm.str())); + } else { + LowerCmdArgs.push_back("-fopenmp-targets-asm"); + LowerCmdArgs.push_back(Args.MakeArgString(TargetInfoAsm.str())); + LowerCmdArgs.push_back("-asm"); + LowerCmdArgs.push_back(Args.MakeArgString(OutFile)); + } + } else { + LowerCmdArgs.push_back("-asm"); + LowerCmdArgs.push_back(Args.MakeArgString(OutFile)); + } + + C.addCommand(std::make_unique(JA, *this, ResponseFileSupport::AtFileUTF8(), LowerExec, LowerCmdArgs, Inputs)); +} + diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.h b/clang/lib/Driver/ToolChains/ClassicFlang.h new file mode 100644 index 000000000000..23ea1fe6b95d --- /dev/null +++ b/clang/lib/Driver/ToolChains/ClassicFlang.h @@ -0,0 +1,49 @@ +//===--- ClassicFlang.h - Flang ToolChain Implementations -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ClassicFlang_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ClassicFlang_H + +#include "MSVC.h" +#include "clang/Basic/DebugInfoOptions.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/Tool.h" +#include "clang/Driver/Types.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Option/Option.h" +#include "llvm/Support/raw_ostream.h" + +namespace clang { +namespace driver { + +namespace tools { + +/// \brief Flang Fortran frontend +class LLVM_LIBRARY_VISIBILITY ClassicFlang : public Tool { +public: + ClassicFlang(const ToolChain &TC) + : Tool("flang:frontend", + "Fortran frontend to LLVM", TC) {} + + bool hasGoodDiagnostics() const override { return true; } + bool hasIntegratedAssembler() const override { return false; } + bool hasIntegratedCPP() const override { return false; } + + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; +}; + +} // end namespace tools + +} // end namespace driver +} // end namespace clang + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_ClassicFlang_H diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 443725f7d8a8..84e9233a4aab 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -120,6 +120,23 @@ static void renderRemarksHotnessOptions(const ArgList &Args, Twine("--plugin-opt=opt-remarks-hotness-threshold=") + A->getValue())); } +/// \brief Determine if Fortran "main" object is needed +static bool needFortranMain(const Driver &D, const ArgList &Args) { + return (needFortranLibs(D, Args) + && (!Args.hasArg(options::OPT_Mnomain) || + !Args.hasArg(options::OPT_no_fortran_main))); +} + +/// \brief Determine if Fortran link libraies are needed +bool tools::needFortranLibs(const Driver &D, const ArgList &Args) { + if (D.IsFlangMode() && !Args.hasArg(options::OPT_nostdlib) && + !Args.hasArg(options::OPT_noFlangLibs)) { + return true; + } + + return false; +} + void tools::addPathIfExists(const Driver &D, const Twine &Path, ToolChain::path_list &Paths) { if (D.getVFS().exists(Path)) @@ -215,6 +232,7 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, const ArgList &Args, ArgStringList &CmdArgs, const JobAction &JA) { const Driver &D = TC.getDriver(); + bool SeenFirstLinkerInput = false; // Add extra linker input arguments which are not treated as inputs // (constructed via -Xarch_). @@ -248,6 +266,14 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, if (II.isNothing()) continue; + // Add Fortan "main" before the first linker input + if (!SeenFirstLinkerInput) { + if (needFortranMain(D, Args)) { + CmdArgs.push_back("-lflangmain"); + } + SeenFirstLinkerInput = true; + } + // Otherwise, this is a linker input argument. const Arg &A = II.getInputArg(); @@ -273,6 +299,15 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, A.renderAsInput(Args, CmdArgs); } } + + if (!SeenFirstLinkerInput && needFortranMain(D, Args)) { + CmdArgs.push_back("-lflangmain"); + } + + // Claim "no Fortran main" arguments + for (auto Arg : Args.filtered(options::OPT_no_fortran_main, options::OPT_Mnomain)) { + Arg->claim(); + } } void tools::addLinkerCompressDebugSectionsOption( diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index 8e62af70ff7f..82ad2f387f08 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -20,6 +20,8 @@ namespace clang { namespace driver { namespace tools { +bool needFortranLibs(const Driver &D, const llvm::opt::ArgList &Args); + void addPathIfExists(const Driver &D, const Twine &Path, ToolChain::path_list &Paths); diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp index 7ad990dda467..997b1e9ce7fc 100644 --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -919,3 +919,36 @@ VersionTuple CudaToolChain::computeMSVCVersion(const Driver *D, const ArgList &Args) const { return HostTC.computeMSVCVersion(D, Args); } + +static void AddFlangSysIncludeArg(const ArgList &DriverArgs, + ArgStringList &Flang1Args, + ToolChain::path_list IncludePathList) { + std::string ArgValue; // Path argument value + + // Make up argument value consisting of paths separated by colons + bool first = true; + for (auto P : IncludePathList) { + if (first) { + first = false; + } else { + ArgValue += ":"; + } + ArgValue += P; + } + + // Add the argument + Flang1Args.push_back("-stdinc"); + Flang1Args.push_back(DriverArgs.MakeArgString(ArgValue)); +} + +void CudaToolChain::AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &Flang1Args) const { + path_list IncludePathList; + const Driver &D = getDriver(); + if (DriverArgs.hasArg(options::OPT_nostdinc)) + return; + SmallString<128> P(D.InstalledDir); + llvm::sys::path::append(P, "../include"); + IncludePathList.push_back(P.c_str()); + AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList); +} diff --git a/clang/lib/Driver/ToolChains/Cuda.h b/clang/lib/Driver/ToolChains/Cuda.h index 809a25227ac4..d860c7a433f6 100644 --- a/clang/lib/Driver/ToolChains/Cuda.h +++ b/clang/lib/Driver/ToolChains/Cuda.h @@ -198,6 +198,9 @@ public: const ToolChain &HostTC; CudaInstallationDetector CudaInstallation; + void + AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &Flang1Args) const override; protected: Tool *buildAssembler() const override; // ptxas Tool *buildLinker() const override; // fatbinary (ok, not really a linker) diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index 665cdc3132fb..1c0800fdbc77 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -567,6 +567,16 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, // The profile runtime also needs access to system libraries. getToolChain().addProfileRTLibs(Args, CmdArgs); + // Add Fortran runtime libraries + if (needFortranLibs(D, Args)) { + ToolChain.AddFortranStdlibLibArgs(Args, CmdArgs); + } else { + // Claim "no Flang libraries" arguments if any + for (auto Arg : Args.filtered(options::OPT_noFlangLibs)) { + Arg->claim(); + } + } + if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, options::OPT_r)) { diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index ceb1a982c3a4..23838ee992b2 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -566,6 +566,194 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const { return "/" + LibDir + "/" + Loader; } +/// Convert path list to Fortran frontend argument +static void AddFlangSysIncludeArg(const ArgList &DriverArgs, + ArgStringList &Flang1Args, + ToolChain::path_list IncludePathList) { + std::string ArgValue; // Path argument value + + // Make up argument value consisting of paths separated by colons + bool first = true; + for (auto P : IncludePathList) { + if (first) { + first = false; + } else { + ArgValue += ":"; + } + ArgValue += P; + } + + // Add the argument + Flang1Args.push_back("-stdinc"); + Flang1Args.push_back(DriverArgs.MakeArgString(ArgValue)); +} + +void Linux::AddFlangSystemIncludeArgs(const ArgList &DriverArgs, + ArgStringList &Flang1Args) const { + path_list IncludePathList; + const Driver &D = getDriver(); + std::string SysRoot = computeSysRoot(); + + if (DriverArgs.hasArg(options::OPT_nostdinc)) + return; + + { + SmallString<128> P(D.InstalledDir); + llvm::sys::path::append(P, "../include"); + IncludePathList.push_back(P.c_str()); + } + + if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) + IncludePathList.push_back(SysRoot + "/usr/local/include"); + + if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { + SmallString<128> P(D.ResourceDir); + llvm::sys::path::append(P, "include"); + IncludePathList.push_back(P.c_str()); + } + + if (DriverArgs.hasArg(options::OPT_nostdlibinc)) { + AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList); + return; + } + + // Check for configure-time C include directories. + StringRef CIncludeDirs(C_INCLUDE_DIRS); + if (CIncludeDirs != "") { + SmallVector dirs; + CIncludeDirs.split(dirs, ":"); + for (StringRef dir : dirs) { + StringRef Prefix = + llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : ""; + IncludePathList.push_back(Prefix.str() + dir.str()); + } + AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList); + return; + } + + // Lacking those, try to detect the correct set of system includes for the + // target triple. + + // Add include directories specific to the selected multilib set and multilib. + if (GCCInstallation.isValid()) { + const auto &Callback = Multilibs.includeDirsCallback(); + if (Callback) { + for (const auto &Path : Callback(GCCInstallation.getMultilib())) + addExternCSystemIncludeIfExists( + DriverArgs, Flang1Args, GCCInstallation.getInstallPath() + Path); + } + } + + // Implement generic Debian multiarch support. + const StringRef X86_64MultiarchIncludeDirs[] = { + "/usr/include/x86_64-linux-gnu", + + // FIXME: These are older forms of multiarch. It's not clear that they're + // in use in any released version of Debian, so we should consider + // removing them. + "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64"}; + const StringRef X86MultiarchIncludeDirs[] = { + "/usr/include/i386-linux-gnu", + + // FIXME: These are older forms of multiarch. It's not clear that they're + // in use in any released version of Debian, so we should consider + // removing them. + "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu", + "/usr/include/i486-linux-gnu"}; + const StringRef AArch64MultiarchIncludeDirs[] = { + "/usr/include/aarch64-linux-gnu"}; + const StringRef ARMMultiarchIncludeDirs[] = { + "/usr/include/arm-linux-gnueabi"}; + const StringRef ARMHFMultiarchIncludeDirs[] = { + "/usr/include/arm-linux-gnueabihf"}; + const StringRef MIPSMultiarchIncludeDirs[] = {"/usr/include/mips-linux-gnu"}; + const StringRef MIPSELMultiarchIncludeDirs[] = { + "/usr/include/mipsel-linux-gnu"}; + const StringRef MIPS64MultiarchIncludeDirs[] = { + "/usr/include/mips64-linux-gnu", "/usr/include/mips64-linux-gnuabi64"}; + const StringRef MIPS64ELMultiarchIncludeDirs[] = { + "/usr/include/mips64el-linux-gnu", + "/usr/include/mips64el-linux-gnuabi64"}; + const StringRef PPCMultiarchIncludeDirs[] = { + "/usr/include/powerpc-linux-gnu"}; + const StringRef PPC64MultiarchIncludeDirs[] = { + "/usr/include/powerpc64-linux-gnu"}; + const StringRef PPC64LEMultiarchIncludeDirs[] = { + "/usr/include/powerpc64le-linux-gnu"}; + const StringRef SparcMultiarchIncludeDirs[] = { + "/usr/include/sparc-linux-gnu"}; + const StringRef Sparc64MultiarchIncludeDirs[] = { + "/usr/include/sparc64-linux-gnu"}; + ArrayRef MultiarchIncludeDirs; + switch (getTriple().getArch()) { + case llvm::Triple::x86_64: + MultiarchIncludeDirs = X86_64MultiarchIncludeDirs; + break; + case llvm::Triple::x86: + MultiarchIncludeDirs = X86MultiarchIncludeDirs; + break; + case llvm::Triple::aarch64: + case llvm::Triple::aarch64_be: + MultiarchIncludeDirs = AArch64MultiarchIncludeDirs; + break; + case llvm::Triple::arm: + if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) + MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs; + else + MultiarchIncludeDirs = ARMMultiarchIncludeDirs; + break; + case llvm::Triple::mips: + MultiarchIncludeDirs = MIPSMultiarchIncludeDirs; + break; + case llvm::Triple::mipsel: + MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs; + break; + case llvm::Triple::mips64: + MultiarchIncludeDirs = MIPS64MultiarchIncludeDirs; + break; + case llvm::Triple::mips64el: + MultiarchIncludeDirs = MIPS64ELMultiarchIncludeDirs; + break; + case llvm::Triple::ppc: + MultiarchIncludeDirs = PPCMultiarchIncludeDirs; + break; + case llvm::Triple::ppc64: + MultiarchIncludeDirs = PPC64MultiarchIncludeDirs; + break; + case llvm::Triple::ppc64le: + MultiarchIncludeDirs = PPC64LEMultiarchIncludeDirs; + break; + case llvm::Triple::sparc: + MultiarchIncludeDirs = SparcMultiarchIncludeDirs; + break; + case llvm::Triple::sparcv9: + MultiarchIncludeDirs = Sparc64MultiarchIncludeDirs; + break; + default: + break; + } + for (StringRef Dir : MultiarchIncludeDirs) { + if (llvm::sys::fs::exists(SysRoot + Dir)) { + IncludePathList.push_back(SysRoot + Dir.str()); + break; + } + } + + if (getTriple().getOS() == llvm::Triple::RTEMS) { + AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList); + return; + } + + // Add an include of '/include' directly. This isn't provided by default by + // system GCCs, but is often used with cross-compiling GCCs, and harmless to + // add even when Clang is acting as-if it were a system compiler. + IncludePathList.push_back(SysRoot + "/include"); + + IncludePathList.push_back(SysRoot + "/usr/include"); + + AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList); +} + void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { const Driver &D = getDriver(); diff --git a/clang/lib/Driver/ToolChains/Linux.h b/clang/lib/Driver/ToolChains/Linux.h index 188cb1f09788..58e8f0358305 100644 --- a/clang/lib/Driver/ToolChains/Linux.h +++ b/clang/lib/Driver/ToolChains/Linux.h @@ -28,6 +28,9 @@ public: StringRef SysRoot) const override; void + AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &Flang1Args) const override; + void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; void addLibStdCxxIncludePaths( diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp old mode 100644 new mode 100755 index 66da6fe97059..e147666d9663 --- a/clang/lib/Driver/Types.cpp +++ b/clang/lib/Driver/Types.cpp @@ -55,9 +55,11 @@ const char *types::getTypeName(ID Id) { types::ID types::getPreprocessedType(ID Id) { ID PPT = getInfo(Id).PreprocessedType; +#ifndef ENABLE_CLASSIC_FLANG assert((getInfo(Id).Phases.contains(phases::Preprocess) != (PPT == TY_INVALID)) && "Unexpected Preprocess Type."); +#endif return PPT; } @@ -134,6 +136,10 @@ bool types::isAcceptedByClang(ID Id) { case TY_Asm: case TY_C: case TY_PP_C: case TY_CL: case TY_CLCXX: +#ifdef ENABLE_CLASSIC_FLANG + case TY_F_FreeForm: case TY_PP_F_FreeForm: + case TY_F_FixedForm: case TY_PP_F_FixedForm: +#endif case TY_CUDA: case TY_PP_CUDA: case TY_CUDA_DEVICE: case TY_HIP: @@ -164,8 +170,15 @@ bool types::isAcceptedByFlang(ID Id) { default: return false; +#ifdef ENABLE_CLASSIC_FLANG + case TY_F_FreeForm: + case TY_PP_F_FreeForm: + case TY_F_FixedForm: + case TY_PP_F_FixedForm: +#else case TY_Fortran: case TY_PP_Fortran: +#endif return true; case TY_LLVM_IR: case TY_LLVM_BC: @@ -286,6 +299,22 @@ bool types::isHIP(ID Id) { } } +#ifdef ENABLE_CLASSIC_FLANG +bool types::isFreeFormFortran(ID Id) { + if (!isAcceptedByFlang(Id)) + return false; + + return (Id == TY_F_FreeForm || Id == TY_PP_F_FreeForm); +} + +bool types::isFixedFormFortran(ID Id) { + if (!isAcceptedByFlang(Id)) + return false; + + return (Id == TY_F_FixedForm || Id == TY_PP_F_FixedForm); +} +#endif + bool types::isSrcFile(ID Id) { return Id != TY_Object && getPreprocessedType(Id) != TY_INVALID; } @@ -294,8 +323,13 @@ types::ID types::lookupTypeForExtension(llvm::StringRef Ext) { return llvm::StringSwitch(Ext) .Case("c", TY_C) .Case("C", TY_CXX) +#ifdef ENABLE_CLASSIC_FLANG + .Case("F", TY_F_FixedForm) + .Case("f", TY_PP_F_FixedForm) +#else .Case("F", TY_Fortran) .Case("f", TY_PP_Fortran) +#endif .Case("h", TY_CHeader) .Case("H", TY_CXXHeader) .Case("i", TY_PP_C) @@ -329,6 +363,20 @@ types::ID types::lookupTypeForExtension(llvm::StringRef Ext) { .Case("cui", TY_PP_CUDA) .Case("cxx", TY_CXX) .Case("CXX", TY_CXX) +#ifdef ENABLE_CLASSIC_FLANG + .Case("for", TY_PP_F_FixedForm) + .Case("FOR", TY_PP_F_FixedForm) + .Case("fpp", TY_F_FixedForm) + .Case("FPP", TY_F_FixedForm) + .Case("f90", TY_PP_F_FreeForm) + .Case("f95", TY_PP_F_FreeForm) + .Case("f03", TY_PP_F_FreeForm) + .Case("f08", TY_PP_F_FreeForm) + .Case("F90", TY_F_FreeForm) + .Case("F95", TY_F_FreeForm) + .Case("F03", TY_F_FreeForm) + .Case("F08", TY_F_FreeForm) +#else .Case("F90", TY_Fortran) .Case("f90", TY_PP_Fortran) .Case("F95", TY_Fortran) @@ -337,6 +385,7 @@ types::ID types::lookupTypeForExtension(llvm::StringRef Ext) { .Case("FOR", TY_PP_Fortran) .Case("fpp", TY_Fortran) .Case("FPP", TY_Fortran) +#endif .Case("gch", TY_PCH) .Case("hip", TY_HIP) .Case("hpp", TY_CXXHeader) diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 20bfbf144a30..db02d65a1d9d 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -160,26 +160,6 @@ static void DefineFloatMacros(MacroBuilder &Builder, StringRef Prefix, Builder.defineMacro(DefPrefix + "MIN__", Twine(Min)+Ext); } - -/// DefineTypeSize - Emit a macro to the predefines buffer that declares a macro -/// named MacroName with the max value for a type with width 'TypeWidth' a -/// signedness of 'isSigned' and with a value suffix of 'ValSuffix' (e.g. LL). -static void DefineTypeSize(const Twine &MacroName, unsigned TypeWidth, - StringRef ValSuffix, bool isSigned, - MacroBuilder &Builder) { - llvm::APInt MaxVal = isSigned ? llvm::APInt::getSignedMaxValue(TypeWidth) - : llvm::APInt::getMaxValue(TypeWidth); - Builder.defineMacro(MacroName, toString(MaxVal, 10, isSigned) + ValSuffix); -} - -/// DefineTypeSize - An overloaded helper that uses TargetInfo to determine -/// the width, suffix, and signedness of the given type -static void DefineTypeSize(const Twine &MacroName, TargetInfo::IntType Ty, - const TargetInfo &TI, MacroBuilder &Builder) { - DefineTypeSize(MacroName, TI.getTypeWidth(Ty), TI.getTypeConstantSuffix(Ty), - TI.isTypeSigned(Ty), Builder); -} - static void DefineFmt(const Twine &Prefix, TargetInfo::IntType Ty, const TargetInfo &TI, MacroBuilder &Builder) { bool IsSigned = TI.isTypeSigned(Ty); diff --git a/clang/test/Driver/autocomplete.c b/clang/test/Driver/autocomplete.c index 59055efac2ce..1cb2cebeeac8 100644 --- a/clang/test/Driver/autocomplete.c +++ b/clang/test/Driver/autocomplete.c @@ -84,7 +84,7 @@ // FVECLIBALL-NEXT: libmvec // FVECLIBALL-NEXT: MASSV // FVECLIBALL-NEXT: none -// FVECLIBALL-NEXT: SVML +// FVECLIBALL: SVML // RUN: %clang --autocomplete=-fshow-overloads= | FileCheck %s -check-prefix=FSOVERALL // FSOVERALL: all // FSOVERALL-NEXT: best diff --git a/clang/test/Driver/flang/classic_flang.f95 b/clang/test/Driver/flang/classic_flang.f95 new file mode 100644 index 000000000000..5d3098786905 --- /dev/null +++ b/clang/test/Driver/flang/classic_flang.f95 @@ -0,0 +1,28 @@ +! Check that the driver can invoke flang1 and flang2 to compile Fortran with +! --driver-mode=flang (default when the file extension is .f95). + +! REQUIRES: classic_flang + +! RUN: %clang -target x86_64-unknown-linux-gnu -integrated-as -c %s -### 2>&1 \ +! RUN: | FileCheck --check-prefix=CHECK-OBJECT %s +! CHECK-OBJECT: flang1 +! CHECK-OBJECT: flang2 +! CHECK-OBJECT-SAME: "-asm" [[LLFILE:.*.ll]] +! CHECK-OBJECT-NOT: cc1as +! CHECK-OBJECT: clang +! CHECK-OBJECT-SAME: -cc1 +! CHECK-OBJECT-SAME: "-o" "classic_flang.o" +! CHECK-OBJECT-SAME: "-x" "ir" +! CHECK-OBJECT-SAME: [[LLFILE]] + +! RUN: %clang -target x86_64-unknown-linux-gnu -integrated-as -S %s -### 2>&1 \ +! RUN: | FileCheck --check-prefix=CHECK-ASM %s +! CHECK-ASM: flang1 +! CHECK-ASM: flang2 +! CHECK-ASM-SAME: "-asm" [[LLFILE:.*.ll]] +! CHECK-ASM-NOT: cc1as +! CHECK-ASM: clang +! CHECK-ASM-SAME: -cc1 +! CHECK-ASM-SAME: "-o" "classic_flang.s" +! CHECK-ASM-SAME: "-x" "ir" +! CHECK-ASM-SAME: [[LLFILE]] diff --git a/clang/test/Driver/flang/flang.f90 b/clang/test/Driver/flang/flang.f90 index 9b16f233b231..5ff05ccccdce 100644 --- a/clang/test/Driver/flang/flang.f90 +++ b/clang/test/Driver/flang/flang.f90 @@ -1,5 +1,7 @@ ! Check that flang -fc1 is invoked when in --driver-mode=flang. +! UNSUPPORTED: classic_flang + ! This is a copy of flang_ucase.F90 because the driver has logic in it which ! differentiates between F90 and f90 files. Flang will not treat these files ! differently. diff --git a/clang/test/Driver/flang/flang_ucase.F90 b/clang/test/Driver/flang/flang_ucase.F90 index 113ef75f45b8..93a4d792e217 100644 --- a/clang/test/Driver/flang/flang_ucase.F90 +++ b/clang/test/Driver/flang/flang_ucase.F90 @@ -1,5 +1,7 @@ ! Check that flang -fc1 is invoked when in --driver-mode=flang. +! UNSUPPORTED: classic_flang + ! This is a copy of flang.f90 because the driver has logic in it which ! differentiates between F90 and f90 files. Flang will not treat these files ! differently. diff --git a/clang/test/Driver/flang/multiple-inputs-mixed.f90 b/clang/test/Driver/flang/multiple-inputs-mixed.f90 index 2395dbecf1fe..8f3918f7cb21 100644 --- a/clang/test/Driver/flang/multiple-inputs-mixed.f90 +++ b/clang/test/Driver/flang/multiple-inputs-mixed.f90 @@ -1,5 +1,7 @@ ! Check that flang can handle mixed C and fortran inputs. +! UNSUPPORTED: classic_flang + ! RUN: %clang --driver-mode=flang -### -fsyntax-only %S/Inputs/one.f90 %S/Inputs/other.c 2>&1 | FileCheck --check-prefixes=CHECK-SYNTAX-ONLY %s ! CHECK-SYNTAX-ONLY-LABEL: "{{[^"]*}}flang-new{{[^"/]*}}" "-fc1" ! CHECK-SYNTAX-ONLY: "{{[^"]*}}/Inputs/one.f90" diff --git a/clang/test/Driver/flang/multiple-inputs.f90 b/clang/test/Driver/flang/multiple-inputs.f90 index f6ee60e48fef..59b7e1f21227 100644 --- a/clang/test/Driver/flang/multiple-inputs.f90 +++ b/clang/test/Driver/flang/multiple-inputs.f90 @@ -1,5 +1,7 @@ ! Check that flang driver can handle multiple inputs at once. +! UNSUPPORTED: classic_flang + ! RUN: %clang --driver-mode=flang -### -fsyntax-only %S/Inputs/one.f90 %S/Inputs/two.f90 2>&1 | FileCheck --check-prefixes=CHECK-SYNTAX-ONLY %s ! CHECK-SYNTAX-ONLY-LABEL: "{{[^"]*}}flang-new" "-fc1" ! CHECK-SYNTAX-ONLY: "{{[^"]*}}/Inputs/one.f90" diff --git a/clang/test/Driver/fortran.f95 b/clang/test/Driver/fortran.f95 index db3ff2da17e8..e364180a1f9c 100644 --- a/clang/test/Driver/fortran.f95 +++ b/clang/test/Driver/fortran.f95 @@ -1,6 +1,8 @@ ! Check that the clang driver can invoke gcc to compile Fortran when in ! --driver-mode=clang. This is legacy behaviour - see also --driver-mode=flang. +! UNSUPPORTED: classic_flang + ! RUN: %clang -target x86_64-unknown-linux-gnu -integrated-as -c %s -### 2>&1 \ ! RUN: | FileCheck --check-prefix=CHECK-OBJECT %s ! CHECK-OBJECT: gcc diff --git a/clang/test/Driver/gfortran.f90 b/clang/test/Driver/gfortran.f90 index c985428650ec..1276703b1f6e 100644 --- a/clang/test/Driver/gfortran.f90 +++ b/clang/test/Driver/gfortran.f90 @@ -1,4 +1,5 @@ ! XFAIL: * +! UNSUPPORTED: classic_flang ! Test that Clang can forward all of the flags which are documented as ! being supported by gfortran to GCC when falling back to GCC for ! a fortran input file. diff --git a/clang/test/lit.cfg.py b/clang/test/lit.cfg.py index d95ea5d2da19..702121b68645 100644 --- a/clang/test/lit.cfg.py +++ b/clang/test/lit.cfg.py @@ -274,3 +274,6 @@ if 'AIXTHREAD_STK' in os.environ: config.environment['AIXTHREAD_STK'] = os.environ['AIXTHREAD_STK'] elif platform.system() == 'AIX': config.environment['AIXTHREAD_STK'] = '4194304' + +if config.use_classic_flang: + config.available_features.add("classic_flang") diff --git a/clang/test/lit.site.cfg.py.in b/clang/test/lit.site.cfg.py.in index 8a9849fe4549..f9abbba41236 100644 --- a/clang/test/lit.site.cfg.py.in +++ b/clang/test/lit.site.cfg.py.in @@ -37,6 +37,7 @@ config.use_z3_solver = lit_config.params.get('USE_Z3_SOLVER', "@USE_Z3_SOLVER@") config.has_plugins = @CLANG_PLUGIN_SUPPORT@ config.clang_vendor_uti = "@CLANG_VENDOR_UTI@" config.llvm_external_lit = path(r"@LLVM_EXTERNAL_LIT@") +config.use_classic_flang = @LLVM_ENABLE_CLASSIC_FLANG@ import lit.llvm lit.llvm.initialize(lit_config, config) diff --git a/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp b/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp index 77370ed8342d..e8cc37884e74 100644 --- a/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp +++ b/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp @@ -898,6 +898,8 @@ CreateFileHandler(MemoryBuffer &FirstInput) { return std::make_unique(/*Comment=*/"#"); if (FilesType == "ll") return std::make_unique(/*Comment=*/";"); + if (FilesType == "f95") + return std::make_unique(/*Comment=*/"!"); if (FilesType == "bc") return std::make_unique(); if (FilesType == "s") diff --git a/clang/tools/driver/CMakeLists.txt b/clang/tools/driver/CMakeLists.txt index d05b71db13f2..0727c7ff7300 100644 --- a/clang/tools/driver/CMakeLists.txt +++ b/clang/tools/driver/CMakeLists.txt @@ -58,7 +58,7 @@ endif() add_dependencies(clang clang-resource-headers) if(NOT CLANG_LINKS_TO_CREATE) - set(CLANG_LINKS_TO_CREATE clang++ clang-cl clang-cpp) + set(CLANG_LINKS_TO_CREATE clang++ clang-cl clang-cpp flang) endif() foreach(link ${CLANG_LINKS_TO_CREATE}) diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake index 0fca934be9cf..a3d93b077040 100644 --- a/llvm/cmake/modules/HandleLLVMOptions.cmake +++ b/llvm/cmake/modules/HandleLLVMOptions.cmake @@ -85,6 +85,14 @@ if( LLVM_ENABLE_ASSERTIONS ) endif() endif() +option(LLVM_ENABLE_CLASSIC_FLANG "Build support for classic Flang instead of the new built-in Flang" OFF) +if(LLVM_ENABLE_CLASSIC_FLANG) + set(LLVM_ENABLE_CLASSIC_FLANG 1) + add_definitions( -DENABLE_CLASSIC_FLANG ) +else() + set(LLVM_ENABLE_CLASSIC_FLANG 0) +endif() + if(LLVM_ENABLE_EXPENSIVE_CHECKS) add_definitions(-DEXPENSIVE_CHECKS) diff --git a/llvm/include/llvm-c/DebugInfo.h b/llvm/include/llvm-c/DebugInfo.h index 8554a0199873..bcce786654ef 100644 --- a/llvm/include/llvm-c/DebugInfo.h +++ b/llvm/include/llvm-c/DebugInfo.h @@ -1137,7 +1137,8 @@ LLVMMetadataRef LLVMDIBuilderCreateGlobalVariableExpression( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, const char *Linkage, size_t LinkLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit, - LLVMMetadataRef Expr, LLVMMetadataRef Decl, uint32_t AlignInBits); + LLVMMetadataRef Expr, LLVMMetadataRef Decl, LLVMDIFlags Flags, + uint32_t AlignInBits); /** * Retrieves the \c DIVariable associated with this global variable expression. @@ -1229,7 +1230,7 @@ LLVMMetadataRef LLVMDIBuilderCreateTempGlobalVariableFwdDecl( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, const char *Linkage, size_t LnkLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit, - LLVMMetadataRef Decl, uint32_t AlignInBits); + LLVMMetadataRef Decl, LLVMDIFlags Flags, uint32_t AlignInBits); /** * Insert a new llvm.dbg.declare intrinsic call before the given instruction. diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h index 7bfda0124de7..bf642394b806 100644 --- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h +++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h @@ -93,6 +93,7 @@ public: DarwinLibSystemM, // Use Darwin's libsystem_m. LIBMVEC_X86, // GLIBC Vector Math library. MASSV, // IBM MASS vector library. + PGMATH, // PGI math library. SVML // Intel short vector math library. }; diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index 9afa715b650c..15600635d28e 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -675,15 +675,17 @@ namespace llvm { DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DIType *Ty, bool IsLocalToUnit, bool isDefined = true, DIExpression *Expr = nullptr, MDNode *Decl = nullptr, - MDTuple *TemplateParams = nullptr, uint32_t AlignInBits = 0, + MDTuple *TemplateParams = nullptr, + DINode::DIFlags Flags = DINode::FlagZero, uint32_t AlignInBits = 0, DINodeArray Annotations = nullptr); /// Identical to createGlobalVariable /// except that the resulting DbgNode is temporary and meant to be RAUWed. DIGlobalVariable *createTempGlobalVariableFwdDecl( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, - unsigned LineNo, DIType *Ty, bool IsLocalToUnit, MDNode *Decl = nullptr, - MDTuple *TemplateParams= nullptr, uint32_t AlignInBits = 0); + unsigned LineNo, DIType *Ty, bool isLocalToUnit, MDNode *Decl = nullptr, + MDTuple *TemplateParams = nullptr, + DINode::DIFlags Flags = DINode::FlagZero, uint32_t AlignInBits = 0); /// Create a new descriptor for an auto variable. This is a local variable /// that is not a subprogram parameter. @@ -814,6 +816,17 @@ namespace llvm { StringRef Name, DIFile *File, unsigned LineNo); + /// Create common block entry for a Fortran common block + /// \param Scope Scope of this common block + /// \param Name The name of this common block + /// \param File The file this common block is defined + /// \param LineNo Line number + /// \param VarList List of variables that a located in common block + /// \param AlignInBits Common block alignment + DICommonBlock *createCommonBlock(DIScope *Scope, DIGlobalVariable *decl, + StringRef Name, DIFile *File, + unsigned LineNo, uint32_t AlignInBits = 0); + /// This creates new descriptor for a namespace with the specified /// parent scope. /// \param Scope Namespace scope diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index db1d031a062d..e7bb525736dc 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -2917,12 +2917,14 @@ class DIGlobalVariable : public DIVariable { bool IsLocalToUnit; bool IsDefinition; + DIFlags Flags; DIGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line, - bool IsLocalToUnit, bool IsDefinition, uint32_t AlignInBits, - ArrayRef Ops) + bool IsLocalToUnit, bool IsDefinition, DIFlags Flags, + uint32_t AlignInBits, ArrayRef Ops) : DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits), - IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {} + IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition), + Flags(Flags) {} ~DIGlobalVariable() = default; static DIGlobalVariable * @@ -2930,12 +2932,12 @@ class DIGlobalVariable : public DIVariable { StringRef LinkageName, DIFile *File, unsigned Line, DIType *Type, bool IsLocalToUnit, bool IsDefinition, DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams, - uint32_t AlignInBits, DINodeArray Annotations, StorageType Storage, - bool ShouldCreate = true) { + DIFlags Flags, uint32_t AlignInBits, DINodeArray Annotations, + StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Scope, getCanonicalMDString(Context, Name), getCanonicalMDString(Context, LinkageName), File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - cast_or_null(TemplateParams), AlignInBits, + cast_or_null(TemplateParams), Flags, AlignInBits, Annotations.get(), Storage, ShouldCreate); } static DIGlobalVariable * @@ -2943,14 +2945,14 @@ class DIGlobalVariable : public DIVariable { MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, - uint32_t AlignInBits, Metadata *Annotations, StorageType Storage, - bool ShouldCreate = true); + DIFlags Flags, uint32_t AlignInBits, Metadata *Annotations, + StorageType Storage, bool ShouldCreate = true); TempDIGlobalVariable cloneImpl() const { return getTemporary(getContext(), getScope(), getName(), getLinkageName(), getFile(), getLine(), getType(), isLocalToUnit(), isDefinition(), getStaticDataMemberDeclaration(), - getTemplateParams(), getAlignInBits(), + getTemplateParams(), getFlags(), getAlignInBits(), getAnnotations()); } @@ -2960,22 +2962,26 @@ public: (DIScope * Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned Line, DIType *Type, bool IsLocalToUnit, bool IsDefinition, DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams, - uint32_t AlignInBits, DINodeArray Annotations), + DIFlags Flags, uint32_t AlignInBits, DINodeArray Annotations), (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, TemplateParams, AlignInBits, Annotations)) + StaticDataMemberDeclaration, TemplateParams, Flags, AlignInBits, + Annotations)) DEFINE_MDNODE_GET( DIGlobalVariable, (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, - uint32_t AlignInBits, Metadata *Annotations), + DIFlags Flags, uint32_t AlignInBits, Metadata *Annotations), (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, TemplateParams, AlignInBits, Annotations)) + StaticDataMemberDeclaration, TemplateParams, Flags, AlignInBits, + Annotations)) TempDIGlobalVariable clone() const { return cloneImpl(); } bool isLocalToUnit() const { return IsLocalToUnit; } bool isDefinition() const { return IsDefinition; } + DIFlags getFlags() const { return Flags; } + bool isArtificial() const { return getFlags() & FlagArtificial; } StringRef getDisplayName() const { return getStringOperand(4); } StringRef getLinkageName() const { return getStringOperand(5); } DIDerivedType *getStaticDataMemberDeclaration() const { diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp index 8ebdb65e88dc..845665b14809 100644 --- a/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -31,7 +31,9 @@ static cl::opt ClVectorLibrary( clEnumValN(TargetLibraryInfoImpl::MASSV, "MASSV", "IBM MASS vector library"), clEnumValN(TargetLibraryInfoImpl::SVML, "SVML", - "Intel SVML library"))); + "Intel SVML library"), + clEnumValN(TargetLibraryInfoImpl::PGMATH, "PGMATH", + "PGI math library"))); StringLiteral const TargetLibraryInfoImpl::StandardNames[LibFunc::NumLibFuncs] = { @@ -1884,6 +1886,456 @@ void TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib( addVectorizableFunctions(VecFuncs); break; } + + // NOTE: All routines listed here are not available on all the architectures. + // Based on the size of vector registers available and the size of data, the + // vector width should be chosen correctly. + case PGMATH: { + const VecDesc VecFuncs[] = { + {"__fd_sin_1", "__fd_sin_2", FIXED(2)}, + {"__fd_sin_1", "__fd_sin_4", FIXED(4)}, + {"__fd_sin_1", "__fd_sin_8", FIXED(8)}, + + {"__fs_sin_1", "__fs_sin_4", FIXED(4)}, + {"__fs_sin_1", "__fs_sin_8", FIXED(8)}, + {"__fs_sin_1", "__fs_sin_16", FIXED(16)}, + + {"__pd_sin_1", "__pd_sin_2", FIXED(2)}, + {"__pd_sin_1", "__pd_sin_4", FIXED(4)}, + {"__pd_sin_1", "__pd_sin_8", FIXED(8)}, + + {"__ps_sin_1", "__ps_sin_4", FIXED(4)}, + {"__ps_sin_1", "__ps_sin_8", FIXED(8)}, + {"__ps_sin_1", "__ps_sin_16", FIXED(16)}, + + {"__rd_sin_1", "__rd_sin_2", FIXED(2)}, + {"__rd_sin_1", "__rd_sin_4", FIXED(4)}, + {"__rd_sin_1", "__rd_sin_8", FIXED(8)}, + + {"__rs_sin_1", "__rs_sin_4", FIXED(4)}, + {"__rs_sin_1", "__rs_sin_8", FIXED(8)}, + {"__rs_sin_1", "__rs_sin_16", FIXED(16)}, + + {"__fd_cos_1", "__fd_cos_2", FIXED(2)}, + {"__fd_cos_1", "__fd_cos_4", FIXED(4)}, + {"__fd_cos_1", "__fd_cos_8", FIXED(8)}, + + {"__fs_cos_1", "__fs_cos_4", FIXED(4)}, + {"__fs_cos_1", "__fs_cos_8", FIXED(8)}, + {"__fs_cos_1", "__fs_cos_16", FIXED(16)}, + + {"__pd_cos_1", "__pd_cos_2", FIXED(2)}, + {"__pd_cos_1", "__pd_cos_4", FIXED(4)}, + {"__pd_cos_1", "__pd_cos_8", FIXED(8)}, + + {"__ps_cos_1", "__ps_cos_4", FIXED(4)}, + {"__ps_cos_1", "__ps_cos_8", FIXED(8)}, + {"__ps_cos_1", "__ps_cos_16", FIXED(16)}, + + {"__rd_cos_1", "__rd_cos_2", FIXED(2)}, + {"__rd_cos_1", "__rd_cos_4", FIXED(4)}, + {"__rd_cos_1", "__rd_cos_8", FIXED(8)}, + + {"__rs_cos_1", "__rs_cos_4", FIXED(4)}, + {"__rs_cos_1", "__rs_cos_8", FIXED(8)}, + {"__rs_cos_1", "__rs_cos_16", FIXED(16)}, + + {"__fd_sincos_1", "__fd_sincos_2", FIXED(2)}, + {"__fd_sincos_1", "__fd_sincos_4", FIXED(4)}, + {"__fd_sincos_1", "__fd_sincos_8", FIXED(8)}, + + {"__fs_sincos_1", "__fs_sincos_4", FIXED(4)}, + {"__fs_sincos_1", "__fs_sincos_8", FIXED(8)}, + {"__fs_sincos_1", "__fs_sincos_16", FIXED(16)}, + + {"__pd_sincos_1", "__pd_sincos_2", FIXED(2)}, + {"__pd_sincos_1", "__pd_sincos_4", FIXED(4)}, + {"__pd_sincos_1", "__pd_sincos_8", FIXED(8)}, + + {"__ps_sincos_1", "__ps_sincos_4", FIXED(4)}, + {"__ps_sincos_1", "__ps_sincos_8", FIXED(8)}, + {"__ps_sincos_1", "__ps_sincos_16", FIXED(16)}, + + {"__rd_sincos_1", "__rd_sincos_2", FIXED(2)}, + {"__rd_sincos_1", "__rd_sincos_4", FIXED(4)}, + {"__rd_sincos_1", "__rd_sincos_8", FIXED(8)}, + + {"__rs_sincos_1", "__rs_sincos_4", FIXED(4)}, + {"__rs_sincos_1", "__rs_sincos_8", FIXED(8)}, + {"__rs_sincos_1", "__rs_sincos_16", FIXED(16)}, + + {"__fd_tan_1", "__fd_tan_2", FIXED(2)}, + {"__fd_tan_1", "__fd_tan_4", FIXED(4)}, + {"__fd_tan_1", "__fd_tan_8", FIXED(8)}, + + {"__fs_tan_1", "__fs_tan_4", FIXED(4)}, + {"__fs_tan_1", "__fs_tan_8", FIXED(8)}, + {"__fs_tan_1", "__fs_tan_16", FIXED(16)}, + + {"__pd_tan_1", "__pd_tan_2", FIXED(2)}, + {"__pd_tan_1", "__pd_tan_4", FIXED(4)}, + {"__pd_tan_1", "__pd_tan_8", FIXED(8)}, + + {"__ps_tan_1", "__ps_tan_4", FIXED(4)}, + {"__ps_tan_1", "__ps_tan_8", FIXED(8)}, + {"__ps_tan_1", "__ps_tan_16", FIXED(16)}, + + {"__rd_tan_1", "__rd_tan_2", FIXED(2)}, + {"__rd_tan_1", "__rd_tan_4", FIXED(4)}, + {"__rd_tan_1", "__rd_tan_8", FIXED(8)}, + + {"__rs_tan_1", "__rs_tan_4", FIXED(4)}, + {"__rs_tan_1", "__rs_tan_8", FIXED(8)}, + {"__rs_tan_1", "__rs_tan_16", FIXED(16)}, + + {"__fd_sinh_1", "__fd_sinh_2", FIXED(2)}, + {"__fd_sinh_1", "__fd_sinh_4", FIXED(4)}, + {"__fd_sinh_1", "__fd_sinh_8", FIXED(8)}, + + {"__fs_sinh_1", "__fs_sinh_4", FIXED(4)}, + {"__fs_sinh_1", "__fs_sinh_8", FIXED(8)}, + {"__fs_sinh_1", "__fs_sinh_16", FIXED(16)}, + + {"__pd_sinh_1", "__pd_sinh_2", FIXED(2)}, + {"__pd_sinh_1", "__pd_sinh_4", FIXED(4)}, + {"__pd_sinh_1", "__pd_sinh_8", FIXED(8)}, + + {"__ps_sinh_1", "__ps_sinh_4", FIXED(4)}, + {"__ps_sinh_1", "__ps_sinh_8", FIXED(8)}, + {"__ps_sinh_1", "__ps_sinh_16", FIXED(16)}, + + {"__rd_sinh_1", "__rd_sinh_2", FIXED(2)}, + {"__rd_sinh_1", "__rd_sinh_4", FIXED(4)}, + {"__rd_sinh_1", "__rd_sinh_8", FIXED(8)}, + + {"__rs_sinh_1", "__rs_sinh_4", FIXED(4)}, + {"__rs_sinh_1", "__rs_sinh_8", FIXED(8)}, + {"__rs_sinh_1", "__rs_sinh_16", FIXED(16)}, + + {"__fd_cosh_1", "__fd_cosh_2", FIXED(2)}, + {"__fd_cosh_1", "__fd_cosh_4", FIXED(4)}, + {"__fd_cosh_1", "__fd_cosh_8", FIXED(8)}, + + {"__fs_cosh_1", "__fs_cosh_4", FIXED(4)}, + {"__fs_cosh_1", "__fs_cosh_8", FIXED(8)}, + {"__fs_cosh_1", "__fs_cosh_16", FIXED(16)}, + + {"__pd_cosh_1", "__pd_cosh_2", FIXED(2)}, + {"__pd_cosh_1", "__pd_cosh_4", FIXED(4)}, + {"__pd_cosh_1", "__pd_cosh_8", FIXED(8)}, + + {"__ps_cosh_1", "__ps_cosh_4", FIXED(4)}, + {"__ps_cosh_1", "__ps_cosh_8", FIXED(8)}, + {"__ps_cosh_1", "__ps_cosh_16", FIXED(16)}, + + {"__rd_cosh_1", "__rd_cosh_2", FIXED(2)}, + {"__rd_cosh_1", "__rd_cosh_4", FIXED(4)}, + {"__rd_cosh_1", "__rd_cosh_8", FIXED(8)}, + + {"__rs_cosh_1", "__rs_cosh_4", FIXED(4)}, + {"__rs_cosh_1", "__rs_cosh_8", FIXED(8)}, + {"__rs_cosh_1", "__rs_cosh_16", FIXED(16)}, + + {"__fd_tanh_1", "__fd_tanh_2", FIXED(2)}, + {"__fd_tanh_1", "__fd_tanh_4", FIXED(4)}, + {"__fd_tanh_1", "__fd_tanh_8", FIXED(8)}, + + {"__fs_tanh_1", "__fs_tanh_4", FIXED(4)}, + {"__fs_tanh_1", "__fs_tanh_8", FIXED(8)}, + {"__fs_tanh_1", "__fs_tanh_16", FIXED(16)}, + + {"__pd_tanh_1", "__pd_tanh_2", FIXED(2)}, + {"__pd_tanh_1", "__pd_tanh_4", FIXED(4)}, + {"__pd_tanh_1", "__pd_tanh_8", FIXED(8)}, + + {"__ps_tanh_1", "__ps_tanh_4", FIXED(4)}, + {"__ps_tanh_1", "__ps_tanh_8", FIXED(8)}, + {"__ps_tanh_1", "__ps_tanh_16", FIXED(16)}, + + {"__rd_tanh_1", "__rd_tanh_2", FIXED(2)}, + {"__rd_tanh_1", "__rd_tanh_4", FIXED(4)}, + {"__rd_tanh_1", "__rd_tanh_8", FIXED(8)}, + + {"__rs_tanh_1", "__rs_tanh_4", FIXED(4)}, + {"__rs_tanh_1", "__rs_tanh_8", FIXED(8)}, + {"__rs_tanh_1", "__rs_tanh_16", FIXED(16)}, + + {"__fd_asin_1", "__fd_asin_2", FIXED(2)}, + {"__fd_asin_1", "__fd_asin_4", FIXED(4)}, + {"__fd_asin_1", "__fd_asin_8", FIXED(8)}, + + {"__fs_asin_1", "__fs_asin_4", FIXED(4)}, + {"__fs_asin_1", "__fs_asin_8", FIXED(8)}, + {"__fs_asin_1", "__fs_asin_16", FIXED(16)}, + + {"__pd_asin_1", "__pd_asin_2", FIXED(2)}, + {"__pd_asin_1", "__pd_asin_4", FIXED(4)}, + {"__pd_asin_1", "__pd_asin_8", FIXED(8)}, + + {"__ps_asin_1", "__ps_asin_4", FIXED(4)}, + {"__ps_asin_1", "__ps_asin_8", FIXED(8)}, + {"__ps_asin_1", "__ps_asin_16", FIXED(16)}, + + {"__rd_asin_1", "__rd_asin_2", FIXED(2)}, + {"__rd_asin_1", "__rd_asin_4", FIXED(4)}, + {"__rd_asin_1", "__rd_asin_8", FIXED(8)}, + + {"__rs_asin_1", "__rs_asin_4", FIXED(4)}, + {"__rs_asin_1", "__rs_asin_8", FIXED(8)}, + {"__rs_asin_1", "__rs_asin_16", FIXED(16)}, + + {"__fd_acos_1", "__fd_acos_2", FIXED(2)}, + {"__fd_acos_1", "__fd_acos_4", FIXED(4)}, + {"__fd_acos_1", "__fd_acos_8", FIXED(8)}, + + {"__fs_acos_1", "__fs_acos_4", FIXED(4)}, + {"__fs_acos_1", "__fs_acos_8", FIXED(8)}, + {"__fs_acos_1", "__fs_acos_16", FIXED(16)}, + + {"__pd_acos_1", "__pd_acos_2", FIXED(2)}, + {"__pd_acos_1", "__pd_acos_4", FIXED(4)}, + {"__pd_acos_1", "__pd_acos_8", FIXED(8)}, + + {"__ps_acos_1", "__ps_acos_4", FIXED(4)}, + {"__ps_acos_1", "__ps_acos_8", FIXED(8)}, + {"__ps_acos_1", "__ps_acos_16", FIXED(16)}, + + {"__rd_acos_1", "__rd_acos_2", FIXED(2)}, + {"__rd_acos_1", "__rd_acos_4", FIXED(4)}, + {"__rd_acos_1", "__rd_acos_8", FIXED(8)}, + + {"__rs_acos_1", "__rs_acos_4", FIXED(4)}, + {"__rs_acos_1", "__rs_acos_8", FIXED(8)}, + {"__rs_acos_1", "__rs_acos_16", FIXED(16)}, + + {"__fd_atan_1", "__fd_atan_2", FIXED(2)}, + {"__fd_atan_1", "__fd_atan_4", FIXED(4)}, + {"__fd_atan_1", "__fd_atan_8", FIXED(8)}, + + {"__fs_atan_1", "__fs_atan_4", FIXED(4)}, + {"__fs_atan_1", "__fs_atan_8", FIXED(8)}, + {"__fs_atan_1", "__fs_atan_16", FIXED(16)}, + + {"__pd_atan_1", "__pd_atan_2", FIXED(2)}, + {"__pd_atan_1", "__pd_atan_4", FIXED(4)}, + {"__pd_atan_1", "__pd_atan_8", FIXED(8)}, + + {"__ps_atan_1", "__ps_atan_4", FIXED(4)}, + {"__ps_atan_1", "__ps_atan_8", FIXED(8)}, + {"__ps_atan_1", "__ps_atan_16", FIXED(16)}, + + {"__rd_atan_1", "__rd_atan_2", FIXED(2)}, + {"__rd_atan_1", "__rd_atan_4", FIXED(4)}, + {"__rd_atan_1", "__rd_atan_8", FIXED(8)}, + + {"__rs_atan_1", "__rs_atan_4", FIXED(4)}, + {"__rs_atan_1", "__rs_atan_8", FIXED(8)}, + {"__rs_atan_1", "__rs_atan_16", FIXED(16)}, + + {"__fd_atan2_1", "__fd_atan2_2", FIXED(2)}, + {"__fd_atan2_1", "__fd_atan2_4", FIXED(4)}, + {"__fd_atan2_1", "__fd_atan2_8", FIXED(8)}, + + {"__fs_atan2_1", "__fs_atan2_4", FIXED(4)}, + {"__fs_atan2_1", "__fs_atan2_8", FIXED(8)}, + {"__fs_atan2_1", "__fs_atan2_16", FIXED(16)}, + + {"__pd_atan2_1", "__pd_atan2_2", FIXED(2)}, + {"__pd_atan2_1", "__pd_atan2_4", FIXED(4)}, + {"__pd_atan2_1", "__pd_atan2_8", FIXED(8)}, + + {"__ps_atan2_1", "__ps_atan2_4", FIXED(4)}, + {"__ps_atan2_1", "__ps_atan2_8", FIXED(8)}, + {"__ps_atan2_1", "__ps_atan2_16", FIXED(16)}, + + {"__rd_atan2_1", "__rd_atan2_2", FIXED(2)}, + {"__rd_atan2_1", "__rd_atan2_4", FIXED(4)}, + {"__rd_atan2_1", "__rd_atan2_8", FIXED(8)}, + + {"__rs_atan2_1", "__rs_atan2_4", FIXED(4)}, + {"__rs_atan2_1", "__rs_atan2_8", FIXED(8)}, + {"__rs_atan2_1", "__rs_atan2_16", FIXED(16)}, + + {"__fd_pow_1", "__fd_pow_2", FIXED(2)}, + {"__fd_pow_1", "__fd_pow_4", FIXED(4)}, + {"__fd_pow_1", "__fd_pow_8", FIXED(8)}, + + {"__fs_pow_1", "__fs_pow_4", FIXED(4)}, + {"__fs_pow_1", "__fs_pow_8", FIXED(8)}, + {"__fs_pow_1", "__fs_pow_16", FIXED(16)}, + + {"__pd_pow_1", "__pd_pow_2", FIXED(2)}, + {"__pd_pow_1", "__pd_pow_4", FIXED(4)}, + {"__pd_pow_1", "__pd_pow_8", FIXED(8)}, + + {"__ps_pow_1", "__ps_pow_4", FIXED(4)}, + {"__ps_pow_1", "__ps_pow_8", FIXED(8)}, + {"__ps_pow_1", "__ps_pow_16", FIXED(16)}, + + {"__rd_pow_1", "__rd_pow_2", FIXED(2)}, + {"__rd_pow_1", "__rd_pow_4", FIXED(4)}, + {"__rd_pow_1", "__rd_pow_8", FIXED(8)}, + + {"__rs_pow_1", "__rs_pow_4", FIXED(4)}, + {"__rs_pow_1", "__rs_pow_8", FIXED(8)}, + {"__rs_pow_1", "__rs_pow_16", FIXED(16)}, + + {"__fs_powi_1", "__fs_powi_4", FIXED(4)}, + {"__fs_powi_1", "__fs_powi_8", FIXED(8)}, + {"__fs_powi_1", "__fs_powi_16", FIXED(16)}, + + {"__ps_powi_1", "__ps_powi_4", FIXED(4)}, + {"__ps_powi_1", "__ps_powi_8", FIXED(8)}, + {"__ps_powi_1", "__ps_powi_16", FIXED(16)}, + + {"__rs_powi_1", "__rs_powi_4", FIXED(4)}, + {"__rs_powi_1", "__rs_powi_8", FIXED(8)}, + {"__rs_powi_1", "__rs_powi_16", FIXED(16)}, + + {"__fd_powi1_1", "__fd_powi1_2", FIXED(2)}, + {"__fd_powi1_1", "__fd_powi1_4", FIXED(4)}, + {"__fd_powi1_1", "__fd_powi1_8", FIXED(8)}, + + {"__fs_powi1_1", "__fs_powi1_4", FIXED(4)}, + {"__fs_powi1_1", "__fs_powi1_8", FIXED(8)}, + {"__fs_powi1_1", "__fs_powi1_16", FIXED(16)}, + + {"__pd_powi1_1", "__pd_powi1_2", FIXED(2)}, + {"__pd_powi1_1", "__pd_powi1_4", FIXED(4)}, + {"__pd_powi1_1", "__pd_powi1_8", FIXED(8)}, + + {"__ps_powi1_1", "__ps_powi1_4", FIXED(4)}, + {"__ps_powi1_1", "__ps_powi1_8", FIXED(8)}, + {"__ps_powi1_1", "__ps_powi1_16", FIXED(16)}, + + {"__rd_powi1_1", "__rd_powi1_2", FIXED(2)}, + {"__rd_powi1_1", "__rd_powi1_4", FIXED(4)}, + {"__rd_powi1_1", "__rd_powi1_8", FIXED(8)}, + + {"__rs_powi1_1", "__rs_powi1_4", FIXED(4)}, + {"__rs_powi1_1", "__rs_powi1_8", FIXED(8)}, + {"__rs_powi1_1", "__rs_powi1_16", FIXED(16)}, + + {"__fd_powk_1", "__fd_powk_2", FIXED(2)}, + {"__fd_powk_1", "__fd_powk_4", FIXED(4)}, + {"__fd_powk_1", "__fd_powk_8", FIXED(8)}, + + {"__fs_powk_1", "__fs_powk_4", FIXED(4)}, + {"__fs_powk_1", "__fs_powk_8", FIXED(8)}, + {"__fs_powk_1", "__fs_powk_16", FIXED(16)}, + + {"__pd_powk_1", "__pd_powk_2", FIXED(2)}, + {"__pd_powk_1", "__pd_powk_4", FIXED(4)}, + {"__pd_powk_1", "__pd_powk_8", FIXED(8)}, + + {"__ps_powk_1", "__ps_powk_4", FIXED(4)}, + {"__ps_powk_1", "__ps_powk_8", FIXED(8)}, + {"__ps_powk_1", "__ps_powk_16", FIXED(16)}, + + {"__rd_powk_1", "__rd_powk_2", FIXED(2)}, + {"__rd_powk_1", "__rd_powk_4", FIXED(4)}, + {"__rd_powk_1", "__rd_powk_8", FIXED(8)}, + + {"__rs_powk_1", "__rs_powk_4", FIXED(4)}, + {"__rs_powk_1", "__rs_powk_8", FIXED(8)}, + {"__rs_powk_1", "__rs_powk_16", FIXED(16)}, + + {"__fd_powk1_1", "__fd_powk1_2", FIXED(2)}, + {"__fd_powk1_1", "__fd_powk1_4", FIXED(4)}, + {"__fd_powk1_1", "__fd_powk1_8", FIXED(8)}, + + {"__fs_powk1_1", "__fs_powk1_4", FIXED(4)}, + {"__fs_powk1_1", "__fs_powk1_8", FIXED(8)}, + {"__fs_powk1_1", "__fs_powk1_16", FIXED(16)}, + + {"__pd_powk1_1", "__pd_powk1_2", FIXED(2)}, + {"__pd_powk1_1", "__pd_powk1_4", FIXED(4)}, + {"__pd_powk1_1", "__pd_powk1_8", FIXED(8)}, + + {"__ps_powk1_1", "__ps_powk1_4", FIXED(4)}, + {"__ps_powk1_1", "__ps_powk1_8", FIXED(8)}, + {"__ps_powk1_1", "__ps_powk1_16", FIXED(16)}, + + {"__rd_powk1_1", "__rd_powk1_2", FIXED(2)}, + {"__rd_powk1_1", "__rd_powk1_4", FIXED(4)}, + {"__rd_powk1_1", "__rd_powk1_8", FIXED(8)}, + + {"__rs_powk1_1", "__rs_powk1_4", FIXED(4)}, + {"__rs_powk1_1", "__rs_powk1_8", FIXED(8)}, + {"__rs_powk1_1", "__rs_powk1_16", FIXED(16)}, + + {"__fd_log10_1", "__fd_log10_2", FIXED(2)}, + {"__fd_log10_1", "__fd_log10_4", FIXED(4)}, + {"__fd_log10_1", "__fd_log10_8", FIXED(8)}, + + {"__fs_log10_1", "__fs_log10_4", FIXED(4)}, + {"__fs_log10_1", "__fs_log10_8", FIXED(8)}, + {"__fs_log10_1", "__fs_log10_16", FIXED(16)}, + + {"__pd_log10_1", "__pd_log10_2", FIXED(2)}, + {"__pd_log10_1", "__pd_log10_4", FIXED(4)}, + {"__pd_log10_1", "__pd_log10_8", FIXED(8)}, + + {"__ps_log10_1", "__ps_log10_4", FIXED(4)}, + {"__ps_log10_1", "__ps_log10_8", FIXED(8)}, + {"__ps_log10_1", "__ps_log10_16", FIXED(16)}, + + {"__rd_log10_1", "__rd_log10_2", FIXED(2)}, + {"__rd_log10_1", "__rd_log10_4", FIXED(4)}, + {"__rd_log10_1", "__rd_log10_8", FIXED(8)}, + + {"__rs_log10_1", "__rs_log10_4", FIXED(4)}, + {"__rs_log10_1", "__rs_log10_8", FIXED(8)}, + {"__rs_log10_1", "__rs_log10_16", FIXED(16)}, + + {"__fd_log_1", "__fd_log_2", FIXED(2)}, + {"__fd_log_1", "__fd_log_4", FIXED(4)}, + {"__fd_log_1", "__fd_log_8", FIXED(8)}, + + {"__fs_log_1", "__fs_log_4", FIXED(4)}, + {"__fs_log_1", "__fs_log_8", FIXED(8)}, + {"__fs_log_1", "__fs_log_16", FIXED(16)}, + + {"__pd_log_1", "__pd_log_2", FIXED(2)}, + {"__pd_log_1", "__pd_log_4", FIXED(4)}, + {"__pd_log_1", "__pd_log_8", FIXED(8)}, + + {"__ps_log_1", "__ps_log_4", FIXED(4)}, + {"__ps_log_1", "__ps_log_8", FIXED(8)}, + {"__ps_log_1", "__ps_log_16", FIXED(16)}, + + {"__rd_log_1", "__rd_log_2", FIXED(2)}, + {"__rd_log_1", "__rd_log_4", FIXED(4)}, + {"__rd_log_1", "__rd_log_8", FIXED(8)}, + + {"__rs_log_1", "__rs_log_4", FIXED(4)}, + {"__rs_log_1", "__rs_log_8", FIXED(8)}, + {"__rs_log_1", "__rs_log_16", FIXED(16)}, + + {"__fs_exp_1", "__fs_exp_4", FIXED(4)}, + {"__fs_exp_1", "__fs_exp_8", FIXED(8)}, + {"__fs_exp_1", "__fs_exp_16", FIXED(16)}, + + {"__pd_exp_1", "__pd_exp_2", FIXED(2)}, + {"__pd_exp_1", "__pd_exp_4", FIXED(4)}, + {"__pd_exp_1", "__pd_exp_8", FIXED(8)}, + + {"__ps_exp_1", "__ps_exp_4", FIXED(4)}, + {"__ps_exp_1", "__ps_exp_8", FIXED(8)}, + {"__ps_exp_1", "__ps_exp_16", FIXED(16)}, + + {"__rd_exp_1", "__rd_exp_2", FIXED(2)}, + {"__rd_exp_1", "__rd_exp_4", FIXED(4)}, + {"__rd_exp_1", "__rd_exp_8", FIXED(8)}, + + {"__rs_exp_1", "__rs_exp_4", FIXED(4)}, + {"__rs_exp_1", "__rs_exp_8", FIXED(8)}, + {"__rs_exp_1", "__rs_exp_16", FIXED(16)} + }; + addVectorizableFunctions(VecFuncs); + break; + } + case NoLibrary: break; } diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index fd502eded0a0..95cd96f111bd 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -5068,6 +5068,22 @@ bool LLParser::parseDITemplateValueParameter(MDNode *&Result, bool IsDistinct) { /// isDefinition: true, templateParams: !3, /// declaration: !4, align: 8) bool LLParser::parseDIGlobalVariable(MDNode *&Result, bool IsDistinct) { +#ifdef ENABLE_CLASSIC_FLANG +#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ + OPTIONAL(name, MDStringField, (/* AllowEmpty */ true)); \ + OPTIONAL(scope, MDField, ); \ + OPTIONAL(linkageName, MDStringField, ); \ + OPTIONAL(file, MDField, ); \ + OPTIONAL(line, LineField, ); \ + OPTIONAL(type, MDField, ); \ + OPTIONAL(isLocal, MDBoolField, ); \ + OPTIONAL(isDefinition, MDBoolField, (true)); \ + OPTIONAL(templateParams, MDField, ); \ + OPTIONAL(declaration, MDField, ); \ + OPTIONAL(flags, DIFlagField, ); \ + OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ + OPTIONAL(annotations, MDField, ); +#else #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ OPTIONAL(name, MDStringField, (/* AllowEmpty */ false)); \ OPTIONAL(scope, MDField, ); \ @@ -5079,8 +5095,10 @@ bool LLParser::parseDIGlobalVariable(MDNode *&Result, bool IsDistinct) { OPTIONAL(isDefinition, MDBoolField, (true)); \ OPTIONAL(templateParams, MDField, ); \ OPTIONAL(declaration, MDField, ); \ + OPTIONAL(flags, DIFlagField, ); \ OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ OPTIONAL(annotations, MDField, ); +#endif PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -5088,8 +5106,8 @@ bool LLParser::parseDIGlobalVariable(MDNode *&Result, bool IsDistinct) { GET_OR_DISTINCT(DIGlobalVariable, (Context, scope.Val, name.Val, linkageName.Val, file.Val, line.Val, type.Val, isLocal.Val, isDefinition.Val, - declaration.Val, templateParams.Val, align.Val, - annotations.Val)); + declaration.Val, templateParams.Val, flags.Val, + align.Val, annotations.Val)); return false; } diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 13d53a35084d..c5729a3faf90 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1883,25 +1883,43 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_GLOBAL_VAR: { - if (Record.size() < 11 || Record.size() > 13) + if (Record.size() < 11 || Record.size() > 14) return error("Invalid record"); IsDistinct = Record[0] & 1; unsigned Version = Record[0] >> 1; - if (Version == 2) { + if (Version == 3) { + // Add support for DIFlags + Metadata *Annotations = nullptr; + if (Record.size() > 13) + Annotations = getMDOrNull(Record[13]); + + MetadataList.assignValue( + GET_OR_DISTINCT( + DIGlobalVariable, + (Context, getMDOrNull(Record[1]), getMDString(Record[2]), + getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], + getDITypeRefOrNull(Record[6]), Record[7], Record[8], + getMDOrNull(Record[9]), getMDOrNull(Record[10]), + static_cast(Record[11]), Record[12], + Annotations)), + NextMetadataNo); + + NextMetadataNo++; + } else if (Version == 2) { Metadata *Annotations = nullptr; if (Record.size() > 12) Annotations = getMDOrNull(Record[12]); MetadataList.assignValue( - GET_OR_DISTINCT(DIGlobalVariable, - (Context, getMDOrNull(Record[1]), - getMDString(Record[2]), getMDString(Record[3]), - getMDOrNull(Record[4]), Record[5], - getDITypeRefOrNull(Record[6]), Record[7], Record[8], - getMDOrNull(Record[9]), getMDOrNull(Record[10]), - Record[11], Annotations)), + GET_OR_DISTINCT( + DIGlobalVariable, + (Context, getMDOrNull(Record[1]), getMDString(Record[2]), + getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], + getDITypeRefOrNull(Record[6]), Record[7], Record[8], + getMDOrNull(Record[9]), getMDOrNull(Record[10]), + DINode::FlagZero, Record[11], Annotations)), NextMetadataNo); NextMetadataNo++; @@ -1914,7 +1932,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( (Context, getMDOrNull(Record[1]), getMDString(Record[2]), getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], getDITypeRefOrNull(Record[6]), Record[7], Record[8], - getMDOrNull(Record[10]), nullptr, Record[11], nullptr)), + getMDOrNull(Record[10]), nullptr, DINode::FlagZero, Record[11], + nullptr)), NextMetadataNo); NextMetadataNo++; @@ -1947,7 +1966,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( (Context, getMDOrNull(Record[1]), getMDString(Record[2]), getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], getDITypeRefOrNull(Record[6]), Record[7], Record[8], - getMDOrNull(Record[10]), nullptr, AlignInBits, nullptr)); + getMDOrNull(Record[10]), nullptr, DINode::FlagZero, AlignInBits, + nullptr)); DIGlobalVariableExpression *DGVE = nullptr; if (Attach || Expr) diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index d7e012fb6a9e..4a9c552ed7a2 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1980,7 +1980,7 @@ void ModuleBitcodeWriter::writeDITemplateValueParameter( void ModuleBitcodeWriter::writeDIGlobalVariable( const DIGlobalVariable *N, SmallVectorImpl &Record, unsigned Abbrev) { - const uint64_t Version = 2 << 1; + const uint64_t Version = 3 << 1; Record.push_back((uint64_t)N->isDistinct() | Version); Record.push_back(VE.getMetadataOrNullID(N->getScope())); Record.push_back(VE.getMetadataOrNullID(N->getRawName())); @@ -1992,6 +1992,7 @@ void ModuleBitcodeWriter::writeDIGlobalVariable( Record.push_back(N->isDefinition()); Record.push_back(VE.getMetadataOrNullID(N->getStaticDataMemberDeclaration())); Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams())); + Record.push_back(N->getFlags()); Record.push_back(N->getAlignInBits()); Record.push_back(VE.getMetadataOrNullID(N->getAnnotations().get())); diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h index d7ab2091967f..e2b99d523f27 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h +++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h @@ -112,6 +112,29 @@ class DbgValueLoc { SmallVector ValueLocEntries; bool IsVariadic; + /// Type of entry that this represents. + enum EntryType { + E_Location, + E_Integer, + E_ConstantFP, + E_ConstantInt, + E_TargetIndexLocation + }; + enum EntryType EntryKind; + + /// Either a constant, + union { + int64_t Int; + const ConstantFP *CFP; + const ConstantInt *CIP; + } Constant; + + union { + /// Or a location in the machine frame. + MachineLocation Loc; + /// Or a location from target specific location. + TargetIndexLocation TIL; + }; public: DbgValueLoc(const DIExpression *Expr, ArrayRef Locs) @@ -146,6 +169,37 @@ public: assert(((Expr && Expr->isValid()) || !Loc.isLocation()) && "DBG_VALUE with a machine location must have a valid expression."); } + DbgValueLoc(const DIExpression *Expr, int64_t i) + : Expression(Expr), EntryKind(E_Integer) { + Constant.Int = i; + } + DbgValueLoc(const DIExpression *Expr, const ConstantFP *CFP) + : Expression(Expr), EntryKind(E_ConstantFP) { + Constant.CFP = CFP; + } + DbgValueLoc(const DIExpression *Expr, const ConstantInt *CIP) + : Expression(Expr), EntryKind(E_ConstantInt) { + Constant.CIP = CIP; + } + DbgValueLoc(const DIExpression *Expr, MachineLocation Loc) + : Expression(Expr), EntryKind(E_Location), Loc(Loc) { + assert(cast(Expr)->isValid()); + } + DbgValueLoc(const DIExpression *Expr, TargetIndexLocation Loc) + : Expression(Expr), EntryKind(E_TargetIndexLocation), TIL(Loc) {} + + bool isLocation() const { return EntryKind == E_Location; } + bool isTargetIndexLocation() const { + return EntryKind == E_TargetIndexLocation; + } + bool isInt() const { return EntryKind == E_Integer; } + bool isConstantFP() const { return EntryKind == E_ConstantFP; } + bool isConstantInt() const { return EntryKind == E_ConstantInt; } + int64_t getInt() const { return Constant.Int; } + const ConstantFP *getConstantFP() const { return Constant.CFP; } + const ConstantInt *getConstantInt() const { return Constant.CIP; } + MachineLocation getLoc() const { return Loc; } + TargetIndexLocation getTargetIndexLocation() const { return TIL; } bool isFragment() const { return getExpression()->isFragment(); } bool isEntryVal() const { return getExpression()->isEntryValue(); } @@ -160,6 +214,15 @@ public: LLVM_DUMP_METHOD void dump() const { for (const DbgValueLocEntry &DV : ValueLocEntries) DV.dump(); +// if (isLocation()) { +// llvm::dbgs() << "Loc = { reg=" << Loc.getReg() << " "; +// if (Loc.isIndirect()) +// llvm::dbgs() << "+0"; +// llvm::dbgs() << "} "; +// } else if (isConstantInt()) +// Constant.CIP->dump(); +// else if (isConstantFP()) +// Constant.CFP->dump(); if (Expression) Expression->dump(); } @@ -227,6 +290,9 @@ public: DebugLocStream::ListBuilder &List, const DIBasicType *BT, DwarfCompileUnit &TheCU); + +// void finalize(const AsmPrinter &AP, DebugLocStream::ListBuilder &List, +// const DIStringType *ST, DwarfCompileUnit &TheCU); }; /// Compare two DbgValueLocEntries for equality. @@ -255,6 +321,29 @@ inline bool operator==(const DbgValueLoc &A, const DbgValueLoc &B) { A.Expression == B.Expression && A.IsVariadic == B.IsVariadic; } +//inline bool operator==(const DbgValueLoc &A, +// const DbgValueLoc &B) { +// if (A.EntryKind != B.EntryKind) +// return false; +// +// if (A.Expression != B.Expression) +// return false; +// +// switch (A.EntryKind) { +// case DbgValueLoc::E_Location: +// return A.Loc == B.Loc; +// case DbgValueLoc::E_TargetIndexLocation: +// return A.TIL == B.TIL; +// case DbgValueLoc::E_Integer: +// return A.Constant.Int == B.Constant.Int; +// case DbgValueLoc::E_ConstantFP: +// return A.Constant.CFP == B.Constant.CFP; +// case DbgValueLoc::E_ConstantInt: +// return A.Constant.CIP == B.Constant.CIP; +// } +// llvm_unreachable("unhandled EntryKind"); +//} + /// Compare two fragments based on their offset. inline bool operator<(const DbgValueLoc &A, const DbgValueLoc &B) { diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp index 8c6109880afc..2db86b2aa94a 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.cpp @@ -37,7 +37,10 @@ void DebugLocStream::finalizeEntry() { "Popped off more entries than are in the list"); } -DebugLocStream::ListBuilder::~ListBuilder() { +void DebugLocStream::ListBuilder::finalize() { + if (Finalized) + return; + Finalized = true; if (!Locs.finalizeList(Asm)) return; V.initializeDbgValue(&MI); diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h index 10019a4720e6..9dfce4e4b093 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h +++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h @@ -160,22 +160,25 @@ class DebugLocStream::ListBuilder { const MachineInstr &MI; size_t ListIndex; Optional TagOffset; + bool Finalized; public: ListBuilder(DebugLocStream &Locs, DwarfCompileUnit &CU, AsmPrinter &Asm, DbgVariable &V, const MachineInstr &MI) : Locs(Locs), Asm(Asm), V(V), MI(MI), ListIndex(Locs.startList(&CU)), - TagOffset(None) {} + TagOffset(None), Finalized(false) {} void setTagOffset(uint8_t TO) { TagOffset = TO; } + void finalize(); + /// Finalize the list. /// /// If the list is empty, delete it. Otherwise, finalize it by creating a /// temp symbol in \a Asm and setting up the \a DbgVariable. - ~ListBuilder(); + ~ListBuilder() { finalize(); } DebugLocStream &getLocs() { return Locs; } }; diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index b26960cdebb8..32781c1da0ee 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -184,6 +184,9 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE( else addGlobalName(GV->getName(), *VariableDIE, DeclContext); + if (GV->isArtificial()) + addFlag(*VariableDIE, dwarf::DW_AT_artificial); + addAnnotation(*VariableDIE, GV->getAnnotations()); if (uint32_t AlignInBytes = GV->getAlignInBytes()) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index 61412cde34c8..2e41e1e06272 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -146,6 +146,14 @@ public: std::vector ExprRefedBaseTypes; +private: + DenseMap> *globalVarMap; +public: + void setGlobalVarMap( + DenseMap> *p = nullptr) { + globalVarMap = p; + } + /// Get or create global variable DIE. DIE * getOrCreateGlobalVariableDIE(const DIGlobalVariable *GV, diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 54af14429907..18087d607148 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1215,11 +1215,17 @@ void DwarfDebug::beginModule(Module *M) { } DenseSet Processed; +#if 0 + CU.setGlobalVarMap(&GVMap); +#endif for (auto *GVE : CUNode->getGlobalVariables()) { DIGlobalVariable *GV = GVE->getVariable(); if (Processed.insert(GV).second) CU.getOrCreateGlobalVariableDIE(GV, sortGlobalExprs(GVMap[GV])); } +#if 0 + CU.setGlobalVarMap(); +#endif for (auto *Ty : CUNode->getEnumTypes()) CU.getOrCreateTypeDIE(cast(Ty)); @@ -1826,10 +1832,28 @@ DbgEntity *DwarfDebug::createConcreteEntity(DwarfCompileUnit &TheCU, return ConcreteEntities.back().get(); } +#if 0 +void DwarfDebug::populateDependentTypeMap() { + for (const auto &I : DbgValues) { + InlinedEntity IV = I.first; + if (I.second.empty()) + continue; + if (const DIVariable *DIV = dyn_cast(IV.first)) { + if (const DIStringType *ST = dyn_cast( + static_cast(DIV->getType()))) + if (const DIVariable *LV = ST->getStringLength()) + VariableInDependentType[LV] = ST; + } + } +} +#endif + // Find variables for each lexical scope. void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU, const DISubprogram *SP, DenseSet &Processed) { +// clearDependentTracking(); +// populateDependentTypeMap(); // Grab the variable info that was squirreled away in the MMI side-table. collectVariableInfoFromMFTable(TheCU, Processed); @@ -1848,6 +1872,11 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU, LexicalScope *Scope = nullptr; const DILocalVariable *LocalVar = cast(IV.first); +#if 0 + const DILocalVariable *LocalVar = dyn_cast(IV.first); + if (!LocalVar) + continue; +#endif if (const DILocation *IA = IV.second) Scope = LScopes.findInlinedScope(LocalVar->getScope(), IA); else @@ -1906,6 +1935,24 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU, // Finalize the entry by lowering it into a DWARF bytestream. for (auto &Entry : Entries) Entry.finalize(*Asm, List, BT, TheCU); +#if 0 + List.finalize(); + + if (VariableInDependentType.count(LocalVar)) { + const DIType *DT = VariableInDependentType[LocalVar]; + if (const DIStringType *ST = dyn_cast(DT)) { + unsigned Offset; + DbgVariable TVar = {LocalVar, IV.second}; + DebugLocStream::ListBuilder LB(DebugLocs, TheCU, *Asm, TVar, *MInsn); + for (auto &Entry : Entries) + Entry.finalize(*Asm, LB, ST, TheCU); + LB.finalize(); + Offset = TVar.getDebugLocListIndex(); + if (Offset != ~0u) + addStringTypeLoc(ST, Offset); + } + } +#endif } // For each InlinedEntity collected from DBG_LABEL instructions, convert to @@ -2677,6 +2724,35 @@ void DebugLocEntry::finalize(const AsmPrinter &AP, List.setTagOffset(*DwarfExpr.TagOffset); } +#if 0 +inline static DbgValueLoc mkDbgValueLoc(const DIExpression *expr, + DbgValueLoc &value) { + if (value.isInt()) + return DbgValueLoc(expr, value.getInt()); + if (value.isLocation()) + return DbgValueLoc(expr, value.getLoc()); + if (value.isConstantInt()) + return DbgValueLoc(expr, value.getConstantInt()); + assert(value.isConstantFP()); + return DbgValueLoc(expr, value.getConstantFP()); +} + +void DebugLocEntry::finalize(const AsmPrinter &AP, + DebugLocStream::ListBuilder &List, + const DIStringType *ST, + DwarfCompileUnit &TheCU) { + DebugLocStream::EntryBuilder Entry(List, Begin, End); + BufferByteStreamer Streamer = Entry.getStreamer(); + DebugLocDwarfExpression DwarfExpr(AP.getDwarfVersion(), Streamer, TheCU); + DbgValueLoc &Value = Values[0]; + assert(!Value.isFragment()); + assert(Values.size() == 1 && "only fragments may have >1 value"); + Value = mkDbgValueLoc(ST->getStringLengthExp(), Value); + DwarfDebug::emitDebugLocValue(AP, nullptr, Value, DwarfExpr); + DwarfExpr.finalize(); +} +#endif + void DwarfDebug::emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU) { // Emit the size. diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 31e4081b7141..b1bc16ee57a8 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -282,6 +282,8 @@ struct SymbolCU { DwarfCompileUnit *CU; }; +class DummyDwarfExpression; + /// The kind of accelerator tables we should emit. enum class AccelTableKind { Default, ///< Platform default. @@ -430,6 +432,8 @@ private: /// Map for tracking Fortran deferred CHARACTER lengths. DenseMap StringTypeLocMap; + DenseMap VariableInDependentType; + AddressPool AddrPool; /// Accelerator tables. @@ -624,6 +628,14 @@ private: /// Emit the reference to the section. void emitSectionReference(const DwarfCompileUnit &CU); +#if 0 + /// Populate dependent type variable map + void populateDependentTypeMap(); +#endif + + /// Clear dependent type tracking map + void clearDependentTracking() { VariableInDependentType.clear(); } + protected: /// Gather pre-function debug information. void beginFunctionImpl(const MachineFunction *MF) override; diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index a29040b8c2aa..fa84587ac7ec 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2254,6 +2254,7 @@ static void writeDIGlobalVariable(raw_ostream &Out, const DIGlobalVariable *N, Printer.printBool("isDefinition", N->isDefinition()); Printer.printMetadata("declaration", N->getRawStaticDataMemberDeclaration()); Printer.printMetadata("templateParams", N->getRawTemplateParams()); + Printer.printDIFlags("flags", N->getFlags()); Printer.printInt("align", N->getAlignInBits()); Printer.printMetadata("annotations", N->getRawAnnotations()); Out << ")"; diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index 34ffc9425281..41527399345c 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -737,14 +737,14 @@ DIGlobalVariableExpression *DIBuilder::createGlobalVariableExpression( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, unsigned LineNumber, DIType *Ty, bool IsLocalToUnit, bool isDefined, DIExpression *Expr, MDNode *Decl, MDTuple *TemplateParams, - uint32_t AlignInBits, DINodeArray Annotations) { + DINode::DIFlags Flags, uint32_t AlignInBits, DINodeArray Annotations) { checkGlobalVariableScope(Context); auto *GV = DIGlobalVariable::getDistinct( VMContext, cast_or_null(Context), Name, LinkageName, F, LineNumber, Ty, IsLocalToUnit, isDefined, - cast_or_null(Decl), TemplateParams, AlignInBits, - Annotations); + cast_or_null(Decl), TemplateParams, Flags, + AlignInBits, Annotations); if (!Expr) Expr = createExpression(); auto *N = DIGlobalVariableExpression::get(VMContext, GV, Expr); @@ -755,14 +755,14 @@ DIGlobalVariableExpression *DIBuilder::createGlobalVariableExpression( DIGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, unsigned LineNumber, DIType *Ty, bool IsLocalToUnit, MDNode *Decl, - MDTuple *TemplateParams, uint32_t AlignInBits) { + MDTuple *TemplateParams, DINode::DIFlags Flags, uint32_t AlignInBits) { checkGlobalVariableScope(Context); return DIGlobalVariable::getTemporary( VMContext, cast_or_null(Context), Name, LinkageName, F, LineNumber, Ty, IsLocalToUnit, false, - cast_or_null(Decl), TemplateParams, AlignInBits, - nullptr) + cast_or_null(Decl), TemplateParams, Flags, + AlignInBits, nullptr) .release(); } diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index fd4b4170c0a7..68dcde9ffdc6 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -1450,12 +1450,13 @@ LLVMMetadataRef LLVMDIBuilderCreateGlobalVariableExpression( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, const char *Linkage, size_t LinkLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit, - LLVMMetadataRef Expr, LLVMMetadataRef Decl, uint32_t AlignInBits) { + LLVMMetadataRef Expr, LLVMMetadataRef Decl, LLVMDIFlags Flags, + uint32_t AlignInBits) { return wrap(unwrap(Builder)->createGlobalVariableExpression( unwrapDI(Scope), {Name, NameLen}, {Linkage, LinkLen}, unwrapDI(File), LineNo, unwrapDI(Ty), LocalToUnit, true, unwrap(Expr), unwrapDI(Decl), - nullptr, AlignInBits)); + nullptr, map_from_llvmDIFlags(Flags), AlignInBits)); } LLVMMetadataRef LLVMDIGlobalVariableExpressionGetVariable(LLVMMetadataRef GVE) { @@ -1500,11 +1501,12 @@ LLVMMetadataRef LLVMDIBuilderCreateTempGlobalVariableFwdDecl( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, const char *Linkage, size_t LnkLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit, - LLVMMetadataRef Decl, uint32_t AlignInBits) { + LLVMMetadataRef Decl, LLVMDIFlags Flags, uint32_t AlignInBits) { return wrap(unwrap(Builder)->createTempGlobalVariableFwdDecl( unwrapDI(Scope), {Name, NameLen}, {Linkage, LnkLen}, unwrapDI(File), LineNo, unwrapDI(Ty), LocalToUnit, - unwrapDI(Decl), nullptr, AlignInBits)); + unwrapDI(Decl), nullptr, map_from_llvmDIFlags(Flags), + AlignInBits)); } LLVMValueRef diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 50799327c78a..185665303659 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -1129,15 +1129,16 @@ DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *StaticDataMemberDeclaration, - Metadata *TemplateParams, uint32_t AlignInBits, - Metadata *Annotations, StorageType Storage, - bool ShouldCreate) { + Metadata *TemplateParams, DIFlags Flags, + uint32_t AlignInBits, Metadata *Annotations, + StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); assert(isCanonical(LinkageName) && "Expected canonical MDString"); DEFINE_GETIMPL_LOOKUP( DIGlobalVariable, (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, TemplateParams, AlignInBits, Annotations)); + StaticDataMemberDeclaration, TemplateParams, Flags, AlignInBits, + Annotations)); Metadata *Ops[] = {Scope, Name, File, @@ -1148,7 +1149,8 @@ DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, TemplateParams, Annotations}; DEFINE_GETIMPL_STORE(DIGlobalVariable, - (Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops); + (Line, IsLocalToUnit, IsDefinition, Flags, AlignInBits), + Ops); } DILocalVariable * diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 47add940f603..f24761df9dfe 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -998,6 +998,7 @@ template <> struct MDNodeKeyImpl { bool IsDefinition; Metadata *StaticDataMemberDeclaration; Metadata *TemplateParams; + unsigned Flags; uint32_t AlignInBits; Metadata *Annotations; @@ -1005,20 +1006,21 @@ template <> struct MDNodeKeyImpl { Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, + unsigned Flags, uint32_t AlignInBits, Metadata *Annotations) : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File), Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition), StaticDataMemberDeclaration(StaticDataMemberDeclaration), - TemplateParams(TemplateParams), AlignInBits(AlignInBits), - Annotations(Annotations) {} + TemplateParams(TemplateParams), Flags(Flags), + AlignInBits(AlignInBits), Annotations(Annotations) {} MDNodeKeyImpl(const DIGlobalVariable *N) : Scope(N->getRawScope()), Name(N->getRawName()), LinkageName(N->getRawLinkageName()), File(N->getRawFile()), Line(N->getLine()), Type(N->getRawType()), IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()), StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()), - TemplateParams(N->getRawTemplateParams()), + TemplateParams(N->getRawTemplateParams()), Flags(N->getFlags()), AlignInBits(N->getAlignInBits()), Annotations(N->getRawAnnotations()) {} bool isKeyOf(const DIGlobalVariable *RHS) const { @@ -1030,6 +1032,7 @@ template <> struct MDNodeKeyImpl { StaticDataMemberDeclaration == RHS->getRawStaticDataMemberDeclaration() && TemplateParams == RHS->getRawTemplateParams() && + Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits() && Annotations == RHS->getRawAnnotations(); } @@ -1044,7 +1047,7 @@ template <> struct MDNodeKeyImpl { // TODO: make hashing work fine with such situations return hash_combine(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, /* AlignInBits, */ - StaticDataMemberDeclaration, Annotations); + StaticDataMemberDeclaration, Flags, Annotations); } }; diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp index 5b7aa304b987..2a45f5a87b6e 100644 --- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -951,8 +951,8 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfInstBase *Inc) { SP, CounterPtr->getName(), /*LinkageName=*/StringRef(), SP->getFile(), /*LineNo=*/0, DB.createUnspecifiedType("Profile Data Type"), CounterPtr->hasLocalLinkage(), /*IsDefined=*/true, /*Expr=*/nullptr, - /*Decl=*/nullptr, /*TemplateParams=*/nullptr, /*AlignInBits=*/0, - Annotations); + /*Decl=*/nullptr, /*TemplateParams=*/nullptr, + /*Flags=*/DINode::FlagZero, /*AlignInBits=*/0, Annotations); CounterPtr->addDebugInfo(DICounter); DB.finalize(); } else { diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 5fd4e45d80fb..28dce7f0857d 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -5574,8 +5574,10 @@ void LoopVectorizationCostModel::collectElementTypesForWidening() { if (ValuesToIgnore.count(&I)) continue; - // Only examine Loads, Stores and PHINodes. - if (!isa(I) && !isa(I) && !isa(I)) + // Examine Loads, Stores, PHINodes + // Also examine instructions which convert to a float/double + if (!isa(I) && !isa(I) && !isa(I) && + !isa(I) && !isa(I) && !isa(I)) continue; // Examine PHI nodes that are reduction variables. Update the type to diff --git a/llvm/test/Assembler/invalid-diglobalvariable-empty-name.ll b/llvm/test/Assembler/invalid-diglobalvariable-empty-name.ll index a4e69f3c8b75..d3c476a03198 100644 --- a/llvm/test/Assembler/invalid-diglobalvariable-empty-name.ll +++ b/llvm/test/Assembler/invalid-diglobalvariable-empty-name.ll @@ -1,4 +1,5 @@ ; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s +; UNSUPPORTED: classic_flang ; CHECK: :[[@LINE+1]]:30: error: 'name' cannot be empty !0 = !DIGlobalVariable(name: "") diff --git a/llvm/test/DebugInfo/Generic/fortran-subprogram-at.ll b/llvm/test/DebugInfo/Generic/fortran-subprogram-at.ll new file mode 100644 index 000000000000..988c388fe218 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/fortran-subprogram-at.ll @@ -0,0 +1,24 @@ +; Test for DIFlagPure, DIFlagElement and DIFlagRecursive. These three +; DIFlags are used to attach DW_AT_pure, DW_AT_element, and DW_AT_recursive +; attributes to DW_TAG_subprogram DIEs. + +; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s +; CHECK: !DISubprogram({{.*}}, spFlags: DISPFlagDefinition | DISPFlagPure | DISPFlagElemental | DISPFlagRecursive, + +!llvm.module.flags = !{!0, !1} +!llvm.dbg.cu = !{!2} + +define void @subprgm() !dbg !6 { +L: + ret void +} + +!0 = !{i32 2, !"Dwarf Version", i32 2} +!1 = !{i32 1, !"Debug Info Version", i32 3} +!2 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: "Flang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !4, globals: !4, imports: !4) +!3 = !DIFile(filename: "fortran-subprogram-at.f", directory: "/") +!4 = !{} +!5 = !DIBasicType(name: "real", size: 32, align: 32, encoding: DW_ATE_float) +!6 = distinct !DISubprogram(name: "subprgm", scope: !2, file: !3, line: 256, type: !7, scopeLine: 256, spFlags: DISPFlagDefinition | DISPFlagPure | DISPFlagElemental | DISPFlagRecursive, unit: !2) +!7 = !DISubroutineType(types: !8) +!8 = !{null, !5} diff --git a/llvm/test/DebugInfo/Generic/more-subprogram-attr.ll b/llvm/test/DebugInfo/Generic/more-subprogram-attr.ll new file mode 100644 index 000000000000..0533cf6b2367 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/more-subprogram-attr.ll @@ -0,0 +1,38 @@ +; REQUIRES: object-emission + +; RUN: %llc_dwarf -O0 -filetype=obj < %s > %t +; RUN: llvm-dwarfdump -v -debug-info %t | FileCheck %s + +; Make sure we're emitting DW_AT_{pure,elemental,recursive}. +; CHECK: DW_TAG_subprogram +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_AT_name {{.*}} "main" +; CHECK-NOT: {{DW_TAG|NULL}} +; CHECK: DW_AT_pure [DW_FORM_flag_present] (true) +; CHECK: DW_AT_elemental [DW_FORM_flag_present] (true) +; CHECK: DW_AT_recursive [DW_FORM_flag_present] (true) + +define dso_local i32 @main() !dbg !7 { +entry: + %retval = alloca i32, align 4 + store i32 0, i32* %retval, align 4 + ret i32 0, !dbg !12 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "x.c", directory: "/tmp") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang"} +!7 = distinct !DISubprogram(name: "main", scope: !8, file: !8, line: 1, type: !9, scopeLine: 2, spFlags: DISPFlagDefinition | DISPFlagPure | DISPFlagElemental | DISPFlagRecursive, unit: !0, retainedNodes: !2) +!8 = !DIFile(filename: "x.c", directory: "/tmp") +!9 = !DISubroutineType(types: !10) +!10 = !{!11} +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !DILocation(line: 3, column: 3, scope: !7) diff --git a/llvm/test/DebugInfo/X86/DICommonBlock.ll b/llvm/test/DebugInfo/X86/DICommonBlock.ll new file mode 100644 index 000000000000..6cfb7a90640d --- /dev/null +++ b/llvm/test/DebugInfo/X86/DICommonBlock.ll @@ -0,0 +1,36 @@ +; ModuleID = 'none.f90' +; RUN: llc %s -o %t -filetype=obj +; RUN: llvm-dwarfdump -debug-info %t | FileCheck %s +; CHECK: DW_TAG_common_block + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx" + +@common_a = common global [32 x i8] zeroinitializer, align 8, !dbg !13 + +define i32 @subr() !dbg !9 { + %1 = getelementptr inbounds [32 x i8], [32 x i8]* @common_a, i64 0, i32 8 + %2 = bitcast i8* %1 to i32* + %3 = load i32, i32* %2 + ret i32 %3 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7} +!llvm.ident = !{!8} + +!0 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !1, producer: "PGI Fortran", isOptimized: false, runtimeVersion: 2, emissionKind: FullDebug, retainedTypes: !14, globals: !2) +!1 = !DIFile(filename: "none.f90", directory: "/not/here/") +!2 = !{!13} +!3 = !{} +!4 = !DIGlobalVariable(name: "common /a/", scope: !5, file: !1, line: 4, isLocal: false, isDefinition: true, type: !12) +!5 = !DICommonBlock(scope: !9, declaration: !4, name: "a", file: !1, line: 4) +!6 = !{i32 2, !"Dwarf Version", i32 4} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{!"PGI Fortran"} +!9 = distinct !DISubprogram(name: "subrtn", scope: !0, file: !1, line: 1, type: !10, isLocal: false, isDefinition: true, unit: !0) +!10 = !DISubroutineType(types: !11) +!11 = !{!12, !12} +!12 = !DIBasicType(name: "int", size: 32) +!13 = !DIGlobalVariableExpression(var: !4, expr: !DIExpression()) +!14 = !{!12, !10} diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py index 75a38b4c5dad..f019626be854 100644 --- a/llvm/test/lit.cfg.py +++ b/llvm/test/lit.cfg.py @@ -487,3 +487,6 @@ if 'aix' in config.target_triple: # "OBJECT_MODE" to 'any' by default on AIX OS. if 'system-aix' in config.available_features: config.environment['OBJECT_MODE'] = 'any' + +if config.use_classic_flang: + config.available_features.add("classic_flang") diff --git a/llvm/test/lit.site.cfg.py.in b/llvm/test/lit.site.cfg.py.in index 09210e2e56d4..ca456defe14a 100644 --- a/llvm/test/lit.site.cfg.py.in +++ b/llvm/test/lit.site.cfg.py.in @@ -62,6 +62,7 @@ config.llvm_raevict_model_autogenerated = @LLVM_RAEVICT_MODEL_AUTOGENERATED@ config.expensive_checks = @LLVM_ENABLE_EXPENSIVE_CHECKS@ config.dxil_tests = @LLVM_INCLUDE_DXIL_TESTS@ config.have_llvm_driver = @LLVM_TOOL_LLVM_DRIVER_BUILD@ +config.use_classic_flang = @LLVM_ENABLE_CLASSIC_FLANG@ import lit.llvm lit.llvm.initialize(lit_config, config) diff --git a/llvm/tools/llvm-c-test/debuginfo.c b/llvm/tools/llvm-c-test/debuginfo.c index d33e40f5f4f3..984c5da49406 100644 --- a/llvm/tools/llvm-c-test/debuginfo.c +++ b/llvm/tools/llvm-c-test/debuginfo.c @@ -63,7 +63,7 @@ int llvm_test_dibuilder(void) { LLVMDIBuilderCreateConstantValueExpression(DIB, 0); LLVMDIBuilderCreateGlobalVariableExpression( DIB, Module, "globalClass", 11, "", 0, File, 1, ClassTy, true, - GlobalClassValueExpr, NULL, 0); + GlobalClassValueExpr, NULL, LLVMDIFlagZero, 0); LLVMMetadataRef Int64Ty = LLVMDIBuilderCreateBasicType(DIB, "Int64", 5, 64, 0, LLVMDIFlagZero); @@ -74,7 +74,7 @@ int llvm_test_dibuilder(void) { LLVMDIBuilderCreateConstantValueExpression(DIB, 0); LLVMDIBuilderCreateGlobalVariableExpression( DIB, Module, "global", 6, "", 0, File, 1, Int64TypeDef, true, - GlobalVarValueExpr, NULL, 0); + GlobalVarValueExpr, NULL, LLVMDIFlagZero, 0); LLVMMetadataRef NameSpace = LLVMDIBuilderCreateNameSpace(DIB, Module, "NameSpace", 9, false); diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp index 9dd49d04405f..baa33bae1d6d 100644 --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -2665,12 +2665,13 @@ TEST_F(DIGlobalVariableTest, get) { DIDerivedType *StaticDataMemberDeclaration = cast(getDerivedType()); + DINode::DIFlags Flags = static_cast(7); uint32_t AlignInBits = 8; auto *N = DIGlobalVariable::get( Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits, - nullptr); + IsDefinition, StaticDataMemberDeclaration, templateParams, Flags, + AlignInBits, nullptr); EXPECT_EQ(dwarf::DW_TAG_variable, N->getTag()); EXPECT_EQ(Scope, N->getScope()); @@ -2683,57 +2684,66 @@ TEST_F(DIGlobalVariableTest, get) { EXPECT_EQ(IsDefinition, N->isDefinition()); EXPECT_EQ(StaticDataMemberDeclaration, N->getStaticDataMemberDeclaration()); EXPECT_EQ(templateParams, N->getTemplateParams()); + EXPECT_EQ(Flags, N->getFlags()); EXPECT_EQ(AlignInBits, N->getAlignInBits()); EXPECT_EQ(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits, nullptr)); + templateParams, Flags, AlignInBits, + nullptr)); EXPECT_NE(N, DIGlobalVariable::get( Context, getSubprogram(), Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, templateParams, AlignInBits, - nullptr)); + StaticDataMemberDeclaration, templateParams, Flags, + AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, "other", LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits, nullptr)); + templateParams, Flags, AlignInBits, + nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, "other", File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits, nullptr)); + templateParams, Flags, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, getFile(), Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits, nullptr)); + templateParams, Flags, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line + 1, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits, nullptr)); + templateParams, Flags, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, getDerivedType(), IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits, nullptr)); + templateParams, Flags, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, !IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits, nullptr)); + templateParams, Flags, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, !IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits, nullptr)); + templateParams, Flags, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, cast(getDerivedType()), - templateParams, AlignInBits, nullptr)); + templateParams, Flags, AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, nullptr, + Flags, AlignInBits, nullptr)); + EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, + Line, Type, IsLocalToUnit, IsDefinition, + StaticDataMemberDeclaration, + templateParams, + static_cast(Flags + 1), AlignInBits, nullptr)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, (AlignInBits << 1), + templateParams, Flags, (AlignInBits << 1), nullptr)); TempDIGlobalVariable Temp = N->clone(); @@ -2756,16 +2766,17 @@ TEST_F(DIGlobalVariableExpressionTest, get) { auto *Expr2 = DIExpression::get(Context, {1, 2, 3}); DIDerivedType *StaticDataMemberDeclaration = cast(getDerivedType()); + DINode::DIFlags Flags = static_cast(7); uint32_t AlignInBits = 8; auto *Var = DIGlobalVariable::get( Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits, - nullptr); + IsDefinition, StaticDataMemberDeclaration, templateParams, Flags, + AlignInBits, nullptr); auto *Var2 = DIGlobalVariable::get( Context, Scope, "other", LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits, - nullptr); + IsDefinition, StaticDataMemberDeclaration, templateParams, Flags, + AlignInBits, nullptr); auto *N = DIGlobalVariableExpression::get(Context, Var, Expr); EXPECT_EQ(Var, N->getVariable()); -- Gitee From 1057c23fa40df599f74eedcd8f148dc8aa77a0fd Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Sun, 1 May 2022 21:43:45 -0400 Subject: [PATCH 03/32] [ClassicFlang][Driver] Coexist with LLVM Flang Make TableGen respect the ENABLE_CLASSIC_FLANG macro and better separate the driver options that are mutually exclusive. When the macro is defined, do not build LLVM Flang at all. --- clang/include/clang/Driver/CMakeLists.txt | 6 +- clang/include/clang/Driver/Options.td | 64 +++++++++++--------- clang/include/clang/Driver/ToolChain.h | 4 ++ clang/lib/Driver/CMakeLists.txt | 7 ++- clang/lib/Driver/ToolChain.cpp | 6 ++ clang/lib/Driver/ToolChains/Clang.cpp | 8 +-- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 16 ++--- clang/lib/Driver/ToolChains/CommonArgs.cpp | 10 ++- clang/lib/Driver/ToolChains/CommonArgs.h | 2 + clang/lib/Driver/ToolChains/Cuda.cpp | 2 + clang/lib/Driver/ToolChains/Cuda.h | 8 ++- clang/lib/Driver/ToolChains/Gnu.cpp | 2 + clang/lib/Driver/ToolChains/Linux.cpp | 2 + clang/lib/Driver/ToolChains/Linux.h | 2 + 14 files changed, 90 insertions(+), 49 deletions(-) diff --git a/clang/include/clang/Driver/CMakeLists.txt b/clang/include/clang/Driver/CMakeLists.txt index a9d988047920..8543ae37ca4c 100644 --- a/clang/include/clang/Driver/CMakeLists.txt +++ b/clang/include/clang/Driver/CMakeLists.txt @@ -1,3 +1,7 @@ set(LLVM_TARGET_DEFINITIONS Options.td) -tablegen(LLVM Options.inc -gen-opt-parser-defs) +if(LLVM_ENABLE_CLASSIC_FLANG) + tablegen(LLVM Options.inc -DENABLE_CLASSIC_FLANG -gen-opt-parser-defs) +else() + tablegen(LLVM Options.inc -gen-opt-parser-defs) +endif() add_public_tablegen_target(ClangDriverOptions) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 29b328429752..09508e82f4bb 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -533,7 +533,7 @@ class InternalDriverOpt : Group, Flags<[NoXarchOption, HelpHidden]>; def driver_mode : Joined<["--"], "driver-mode=">, Group, Flags<[CoreOption, NoXarchOption, HelpHidden]>, - HelpText<"Set the driver mode to either 'gcc', 'g++', 'cpp', 'cl', or 'fortran'">; + HelpText<"Set the driver mode to one of: 'gcc', 'g++', 'cpp', 'cl', or 'flang'">; def rsp_quoting : Joined<["--"], "rsp-quoting=">, Group, Flags<[CoreOption, NoXarchOption, HelpHidden]>, HelpText<"Set the rsp quoting to either 'posix', or 'windows'">; @@ -4790,12 +4790,6 @@ defm devirtualize : BooleanFFlag<"devirtualize">, Group, Group; -// gfortran options that we recognize in the driver and pass along when -// invoking GCC to compile Fortran code. -def flang_rt_Group : OptionGroup<"Flang runtime library Group">; -def pgi_fortran_Group : OptionGroup<"PGI Fortran compatibility Group">, - Flags<[HelpHidden]>; - // Generic gfortran options. def A_DASH : Joined<["-"], "A-">, Group; def static_libgfortran : Flag<["-"], "static-libgfortran">, Group; @@ -4817,8 +4811,6 @@ def fmax_stack_var_size_EQ : Joined<["-"], "fmax-stack-var-size=">, Group, Group; // "f" flags for gfortran. defm aggressive_function_elimination : BooleanFFlag<"aggressive-function-elimination">, Group; defm align_commons : BooleanFFlag<"align-commons">, Group; @@ -4830,19 +4822,13 @@ defm check_array_temporaries : BooleanFFlag<"check-array-temporaries">, Group, Group; defm d_lines_as_code : BooleanFFlag<"d-lines-as-code">, Group; defm d_lines_as_comments : BooleanFFlag<"d-lines-as-comments">, Group; -def default_integer_8_fno : Flag<["-"], "fno-default-integer-8">, Group; -def default_real_8_fno : Flag<["-"], "fno-default-real-8">, Group; defm dollar_ok : BooleanFFlag<"dollar-ok">, Group; defm dump_fortran_optimized : BooleanFFlag<"dump-fortran-optimized">, Group; defm dump_fortran_original : BooleanFFlag<"dump-fortran-original">, Group; defm dump_parse_tree : BooleanFFlag<"dump-parse-tree">, Group; defm external_blas : BooleanFFlag<"external-blas">, Group; defm f2c : BooleanFFlag<"f2c">, Group; -def fixed_form_off : Flag<["-"], "fno-fixed-form">, Group, - HelpText<"Disable fixed-form format for Fortran">; -def free_form_off : Flag<["-"], "fno-free-form">, Group, - HelpText<"Disable free-form format for Fortran">; -defm frontend_optimize : BooleanFFlag<"frontend-optimize">, Group; +defm frontend_optimize : BooleanFFlag<"frontend-optimize">, Group; defm init_local_zero : BooleanFFlag<"init-local-zero">, Group; defm integer_4_integer_8 : BooleanFFlag<"integer-4-integer-8">, Group; defm max_identifier_length : BooleanFFlag<"max-identifier-length">, Group; @@ -4894,9 +4880,9 @@ def Xflang : Separate<["-"], "Xflang">, let Flags = [FC1Option, FlangOption, FlangOnlyOption] in { -def cpp : Flag<["-"], "cpp">, Group, +def cpp : Flag<["-"], "cpp">, Group, HelpText<"Enable predefined and command line preprocessor macros">; -def nocpp : Flag<["-"], "nocpp">, Group, +def nocpp : Flag<["-"], "nocpp">, Group, HelpText<"Disable predefined and command line preprocessor macros">; def module_dir : JoinedOrSeparate<["-"], "module-dir">, MetaVarName<"">, HelpText<"Put MODULE files in ">, @@ -4904,34 +4890,48 @@ def module_dir : JoinedOrSeparate<["-"], "module-dir">, MetaVarName<"">, It is also added to the list of directories to be searched by an USE statement. The default is the current directory.}]>; +#ifdef ENABLE_CLASSIC_FLANG +// Define a group for Fortran source format options. +def fortran_format_Group : OptionGroup<"Fortran format Group">, Group; def ffixed_form : Flag<["-"], "ffixed-form">, Group, HelpText<"Process source files in fixed form">; -#ifdef ENABLE_CLASSIC_FLANG def fno_fixed_form : Flag<["-"], "fno-fixed-form">, Group, HelpText<"Disable fixed-form format for Fortran">; -#endif def ffree_form : Flag<["-"], "ffree-form">, Group, HelpText<"Process source files in free form">; -#ifdef ENABLE_CLASSIC_FLANG def fno_free_form : Flag<["-"], "fno-free-form">, Group, HelpText<"Disable free-form format for Fortran">; -#endif -def ffixed_line_length_EQ : Joined<["-"], "ffixed-line-length=">, Group, +def ffixed_line_length_VALUE : Joined<["-"], "ffixed-line-length-">, Group, + HelpText<"Set line length in fixed-form format Fortran, current supporting only 72 and 132 characters">; +#else +def ffixed_form : Flag<["-"], "ffixed-form">, Group, + HelpText<"Process source files in fixed form">; +def ffree_form : Flag<["-"], "ffree-form">, Group, + HelpText<"Process source files in free form">; +def ffixed_line_length_EQ : Joined<["-"], "ffixed-line-length=">, Group, HelpText<"Use as character line width in fixed mode">, DocBrief<[{Set column after which characters are ignored in typical fixed-form lines in the source file}]>; -def ffixed_line_length_VALUE : Joined<["-"], "ffixed-line-length-">, Group, - HelpText<"Set line length in fixed-form format Fortran, current supporting only 72 and 132 characters">; +def ffixed_line_length_VALUE : Joined<["-"], "ffixed-line-length-">, Group, Alias; +#endif + def fopenacc : Flag<["-"], "fopenacc">, Group, HelpText<"Enable OpenACC">; -def fdefault_double_8 : Flag<["-"],"fdefault-double-8">, Group, +def fdefault_double_8 : Flag<["-"],"fdefault-double-8">, Group, HelpText<"Set the default double precision kind to an 8 byte wide type">; -def fdefault_integer_8 : Flag<["-"],"fdefault-integer-8">, Group, +def fdefault_integer_8 : Flag<["-"],"fdefault-integer-8">, Group, HelpText<"Set the default integer kind to an 8 byte wide type">; -def fdefault_real_8 : Flag<["-"],"fdefault-real-8">, Group, +#ifdef ENABLE_CLASSIC_FLANG +def fno_default_integer_8 : Flag<["-"], "fno-default-integer-8">, Group; +#endif +def fdefault_real_8 : Flag<["-"],"fdefault-real-8">, Group, HelpText<"Set the default real kind to an 8 byte wide type">; +#ifdef ENABLE_CLASSIC_FLANG +def fno_default_real_8 : Flag<["-"], "fno-default-real-8">, Group; +#endif def flarge_sizes : Flag<["-"],"flarge-sizes">, Group, HelpText<"Use INTEGER(KIND=8) for the result type in size-related intrinsics">; + def falternative_parameter_statement : Flag<["-"], "falternative-parameter-statement">, Group, HelpText<"Enable the old style PARAMETER statement">; def fintrinsic_modules_path : Separate<["-"], "fintrinsic-modules-path">, Group, MetaVarName<"">, @@ -6948,6 +6948,13 @@ def enable_16bit_types : DXCFlag<"enable-16bit-types">, Alias HelpText<"Enable 16-bit types and disable min precision types." "Available in HLSL 2018 and shader model 6.2.">; +#ifdef ENABLE_CLASSIC_FLANG +// Classic Flang options that we recognize in the driver and pass along when +// invoking flang1/flang2 to compile Fortran code. +def flang_rt_Group : OptionGroup<"Flang runtime library Group">; +def pgi_fortran_Group : OptionGroup<"PGI Fortran compatibility Group">, + Flags<[HelpHidden]>; + // Classic Flang-specific options multiclass BooleanKFlag { def _on : Flag<["-"], "K"#name>; @@ -7080,3 +7087,4 @@ def Hq_EQ : Joined<["-"], "Hq,">, Group; def Mqq_EQ : Joined<["-"], "Mqq,">, Group; def Hqq_EQ : Joined<["-"], "Hqq,">, Group; def Wh_EQ : Joined<["-"], "Wh,">, Group; +#endif diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index 66cd1823033d..842e93b3a09c 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -623,6 +623,7 @@ public: AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const; +#ifdef ENABLE_CLASSIC_FLANG /// \brief Add the flang arguments for system include paths. /// /// This routine is responsible for adding the -stdinc argument to @@ -630,6 +631,7 @@ public: virtual void AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &Flang1Args) const { } +#endif /// Add options that need to be passed to cc1 for this target. virtual void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, @@ -728,10 +730,12 @@ public: virtual void AddHIPRuntimeLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const {} +#ifdef ENABLE_CLASSIC_FLANG /// AddFortranStdlibLibArgs - Add the system specific linker arguments to use /// for the given Fortran runtime library type. virtual void AddFortranStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; +#endif /// Return sanitizers which are available in this toolchain. virtual SanitizerMask getSupportedSanitizers() const; diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt index 24a795ba09ad..786bb895d5bb 100644 --- a/clang/lib/Driver/CMakeLists.txt +++ b/clang/lib/Driver/CMakeLists.txt @@ -13,7 +13,9 @@ if(WIN32) endif() if(LLVM_ENABLE_CLASSIC_FLANG) - set(CLASSIC_FLANG_FILES ToolChains/ClassicFlang.cpp) + set(TOOLCHAINS_FLANG_CPP ToolChains/ClassicFlang.cpp) +else() + set(TOOLCHAINS_FLANG_CPP ToolChains/Flang.cpp) endif() add_clang_library(clangDriver @@ -55,7 +57,7 @@ add_clang_library(clangDriver ToolChains/Cuda.cpp ToolChains/Darwin.cpp ToolChains/DragonFly.cpp - ToolChains/Flang.cpp + ${TOOLCHAINS_FLANG_CPP} ToolChains/FreeBSD.cpp ToolChains/Fuchsia.cpp ToolChains/Gnu.cpp @@ -90,7 +92,6 @@ add_clang_library(clangDriver ToolChains/ZOS.cpp Types.cpp XRayArgs.cpp - ${CLASSIC_FLANG_FILES} DEPENDS ClangDriverOptions diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 8626c338dda3..87f4e670daa2 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -299,9 +299,13 @@ Tool *ToolChain::getClang() const { } Tool *ToolChain::getFlang() const { +#ifndef ENABLE_CLASSIC_FLANG if (!Flang) Flang.reset(new tools::Flang(*this)); return Flang.get(); +#else + llvm_unreachable("Flang is not supported by this toolchain"); +#endif } Tool *ToolChain::buildAssembler() const { @@ -1049,6 +1053,7 @@ void ToolChain::AddCCKextLibArgs(const ArgList &Args, CmdArgs.push_back("-lcc_kext"); } +#ifdef ENABLE_CLASSIC_FLANG void ToolChain::AddFortranStdlibLibArgs(const ArgList &Args, ArgStringList &CmdArgs) const { bool staticFlangLibs = false; @@ -1087,6 +1092,7 @@ void ToolChain::AddFortranStdlibLibArgs(const ArgList &Args, // Allways link Fortran executables with Pthreads CmdArgs.push_back("-lpthread"); } +#endif bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args, std::string &Path) const { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 1f7b81a6f04b..a8fd2ae6bfcb 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5096,14 +5096,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } -#ifdef ENABLE_CLASSIC_FLANG +#ifndef ENABLE_CLASSIC_FLANG + Args.AddLastArg(CmdArgs, options::OPT_fveclib); +#else if (Args.getLastArg(options::OPT_fveclib)) Args.AddLastArg(CmdArgs, options::OPT_fveclib); else CmdArgs.push_back("-fveclib=PGMATH"); -#else - Args.AddLastArg(CmdArgs, options::OPT_fveclib); -#endif std::string PassRemarkVal(""), PassRemarkOpt(""); if (Args.getLastArg(options::OPT_Minfoall)) { @@ -5158,6 +5157,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-mllvm"); CmdArgs.push_back(Args.MakeArgString(PassRemarkOpt)); Args.ClaimAllArgs(options::OPT_Mneginfo_EQ); +#endif if (Args.hasFlag(options::OPT_fmerge_all_constants, options::OPT_fno_merge_all_constants, false)) diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index a68ec58e5e66..ba05861eab69 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -366,10 +366,10 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, // Handle -fdefault-real-8 (and its alias, -r8) and -fno-default-real-8 if (Arg *A = Args.getLastArg(options::OPT_r8, options::OPT_fdefault_real_8, - options::OPT_default_real_8_fno)) { + options::OPT_fno_default_real_8)) { const char * fl; // For -f version add -x flag, for -fno add -y - if (A->getOption().matches(options::OPT_default_real_8_fno)) { + if (A->getOption().matches(options::OPT_fno_default_real_8)) { fl = "-y"; } else { fl = "-x"; @@ -377,7 +377,7 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, for (Arg *A : Args.filtered(options::OPT_r8, options::OPT_fdefault_real_8, - options::OPT_default_real_8_fno)) { + options::OPT_fno_default_real_8)) { A->claim(); } @@ -392,10 +392,10 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, // Process and claim -i8/-fdefault-integer-8/-fno-default-integer-8 argument if (Arg *A = Args.getLastArg(options::OPT_i8, options::OPT_fdefault_integer_8, - options::OPT_default_integer_8_fno)) { + options::OPT_fno_default_integer_8)) { const char * fl; - if (A->getOption().matches(options::OPT_default_integer_8_fno)) { + if (A->getOption().matches(options::OPT_fno_default_integer_8)) { fl = "-y"; } else { fl = "-x"; @@ -403,7 +403,7 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, for (Arg *A : Args.filtered(options::OPT_i8, options::OPT_fdefault_integer_8, - options::OPT_default_integer_8_fno)) { + options::OPT_fno_default_integer_8)) { A->claim(); } @@ -727,14 +727,14 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, default: llvm_unreachable("missed a case"); case options::OPT_ffixed_form: - case options::OPT_free_form_off: + case options::OPT_fno_free_form: case options::OPT_Mfixed: case options::OPT_Mfree_off: case options::OPT_Mfreeform_off: UpperCmdArgs.push_back("-nofreeform"); break; case options::OPT_ffree_form: - case options::OPT_fixed_form_off: + case options::OPT_fno_fixed_form: case options::OPT_Mfree_on: case options::OPT_Mfreeform_on: UpperCmdArgs.push_back("-freeform"); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 84e9233a4aab..3c15cc014415 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -120,6 +120,7 @@ static void renderRemarksHotnessOptions(const ArgList &Args, Twine("--plugin-opt=opt-remarks-hotness-threshold=") + A->getValue())); } +#ifdef ENABLE_CLASSIC_FLANG /// \brief Determine if Fortran "main" object is needed static bool needFortranMain(const Driver &D, const ArgList &Args) { return (needFortranLibs(D, Args) @@ -136,6 +137,7 @@ bool tools::needFortranLibs(const Driver &D, const ArgList &Args) { return false; } +#endif void tools::addPathIfExists(const Driver &D, const Twine &Path, ToolChain::path_list &Paths) { @@ -232,7 +234,9 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, const ArgList &Args, ArgStringList &CmdArgs, const JobAction &JA) { const Driver &D = TC.getDriver(); +#ifdef ENABLE_CLASSIC_FLANG bool SeenFirstLinkerInput = false; +#endif // Add extra linker input arguments which are not treated as inputs // (constructed via -Xarch_). @@ -266,6 +270,7 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, if (II.isNothing()) continue; +#ifdef ENABLE_CLASSIC_FLANG // Add Fortan "main" before the first linker input if (!SeenFirstLinkerInput) { if (needFortranMain(D, Args)) { @@ -273,7 +278,7 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, } SeenFirstLinkerInput = true; } - +#endif // Otherwise, this is a linker input argument. const Arg &A = II.getInputArg(); @@ -299,7 +304,7 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, A.renderAsInput(Args, CmdArgs); } } - +#ifdef ENABLE_CLASSIC_FLANG if (!SeenFirstLinkerInput && needFortranMain(D, Args)) { CmdArgs.push_back("-lflangmain"); } @@ -308,6 +313,7 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, for (auto Arg : Args.filtered(options::OPT_no_fortran_main, options::OPT_Mnomain)) { Arg->claim(); } +#endif } void tools::addLinkerCompressDebugSectionsOption( diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index 82ad2f387f08..d012f4ff8112 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -20,7 +20,9 @@ namespace clang { namespace driver { namespace tools { +#ifdef ENABLE_CLASSIC_FLANG bool needFortranLibs(const Driver &D, const llvm::opt::ArgList &Args); +#endif void addPathIfExists(const Driver &D, const Twine &Path, ToolChain::path_list &Paths); diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp index 997b1e9ce7fc..4d7b6117809b 100644 --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -920,6 +920,7 @@ VersionTuple CudaToolChain::computeMSVCVersion(const Driver *D, return HostTC.computeMSVCVersion(D, Args); } +#ifdef ENABLE_CLASSIC_FLANG static void AddFlangSysIncludeArg(const ArgList &DriverArgs, ArgStringList &Flang1Args, ToolChain::path_list IncludePathList) { @@ -952,3 +953,4 @@ void CudaToolChain::AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverAr IncludePathList.push_back(P.c_str()); AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList); } +#endif diff --git a/clang/lib/Driver/ToolChains/Cuda.h b/clang/lib/Driver/ToolChains/Cuda.h index d860c7a433f6..04d2517ea2b3 100644 --- a/clang/lib/Driver/ToolChains/Cuda.h +++ b/clang/lib/Driver/ToolChains/Cuda.h @@ -184,6 +184,11 @@ public: llvm::opt::ArgStringList &CC1Args) const override; void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; +#ifdef ENABLE_CLASSIC_FLANG + void + AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &Flang1Args) const override; +#endif SanitizerMask getSupportedSanitizers() const override; @@ -198,9 +203,6 @@ public: const ToolChain &HostTC; CudaInstallationDetector CudaInstallation; - void - AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &Flang1Args) const override; protected: Tool *buildAssembler() const override; // ptxas Tool *buildLinker() const override; // fatbinary (ok, not really a linker) diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index 1c0800fdbc77..9d5707713210 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -567,6 +567,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, // The profile runtime also needs access to system libraries. getToolChain().addProfileRTLibs(Args, CmdArgs); +#ifdef ENABLE_CLASSIC_FLANG // Add Fortran runtime libraries if (needFortranLibs(D, Args)) { ToolChain.AddFortranStdlibLibArgs(Args, CmdArgs); @@ -576,6 +577,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, Arg->claim(); } } +#endif if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index 23838ee992b2..992c6bd8ea8d 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -566,6 +566,7 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const { return "/" + LibDir + "/" + Loader; } +#ifdef ENABLE_CLASSIC_FLANG /// Convert path list to Fortran frontend argument static void AddFlangSysIncludeArg(const ArgList &DriverArgs, ArgStringList &Flang1Args, @@ -753,6 +754,7 @@ void Linux::AddFlangSystemIncludeArgs(const ArgList &DriverArgs, AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList); } +#endif void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { diff --git a/clang/lib/Driver/ToolChains/Linux.h b/clang/lib/Driver/ToolChains/Linux.h index 58e8f0358305..59cf1498cd09 100644 --- a/clang/lib/Driver/ToolChains/Linux.h +++ b/clang/lib/Driver/ToolChains/Linux.h @@ -27,9 +27,11 @@ public: const llvm::Triple &TargetTriple, StringRef SysRoot) const override; +#ifdef ENABLE_CLASSIC_FLANG void AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &Flang1Args) const override; +#endif void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; -- Gitee From 63a98fe583c037ff53e09f4a527fbde4a2e0e5b3 Mon Sep 17 00:00:00 2001 From: Alok Kumar Sharma <60725621+alokkrsharma@users.noreply.github.com> Date: Sun, 20 Sep 2020 17:21:34 +0530 Subject: [PATCH 04/32] Support for DWARF 4/5 and fix of issues related to -gdwarf-X options (#92) * Support for -gdwarf-5 option in Flang driver. Summary: FLANG driver doesnt pass -gdwarf-4/5 to flang1 in form of xbits, while it passes for -gdwarf-2/3 -gdwarf-2 => -x 120 0x200 -gdwarf-3 => -x 120 0x4000 Due to this -gdwarf-5 is never honored and default option -gdwarf-4 is taken. # flang -gdwarf-5 test.f90 # llvm-dwarfdump a.out | grep version 0x00000000: Compile Unit: length = 0x0000008e version = 0x0004 Now 0x1000000/0x2000000 will be passed for -gdwarf-4/5 -gdwarf-4 => -x 120 0x1000000 -gdwarf-5 => -x 120 0x2000000 Testing: - GNU gdb fortran testsuite - check-llvm - check-debuginfo * Flang doenst choose correct dwarf version when multiple -g/-gdwarfN mentioned Summary: When multiple -g/-gdwarfN options are passed together at compile time, flang chooses the least one. Clang/gfortran etc choose the last one. -gdwarf-5 -gdwarf-3 => flang chooses 5 while clang/gfortran choose 3 -gdwarf-5 -g => flang choses the default while clang/gfortran choose 5 Testing: - check-llvm - check-debuginfo * Default dwarf version should be 4 for -g with flang Currently flang dumps dwarf version 2 for -g and 4 for absence of -g ------------------------- $ flang my.f90 $ llvm-dwarfdump a.out | grep version 0x00000000: Compile Unit: length = 0x0000003d version = 0x0004 abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x00000041) $ flang -g my.f90 $ llvm-dwarfdump a.out | grep version 0x00000000: Compile Unit: length = 0x00000047 version = 0x0002 abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x0000004b) ------------------------- It should be 4 for -g as it is the case with clang. --- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 42 +++++++++++--------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index ba05861eab69..f297989910c5 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -327,28 +327,34 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, LowerCmdArgs.push_back("0x8"); } - // -g should produce DWARFv2 - for (auto Arg : Args.filtered(options::OPT_g_Flag)) { - Arg->claim(); - CommonCmdArgs.push_back("-x"); - CommonCmdArgs.push_back("120"); - CommonCmdArgs.push_back("0x200"); - } + // Last argument of -g/-gdwarfX should be taken. + Arg *GArg = Args.getLastArg(options::OPT_g_Flag); + Arg *GDwarfArg = Args.getLastArg(options::OPT_gdwarf_2, + options::OPT_gdwarf_3, + options::OPT_gdwarf_4, + options::OPT_gdwarf_5); + + if (GArg || GDwarfArg) { + + for (auto Arg : Args.filtered(options::OPT_g_Flag, options::OPT_gdwarf_2, + options::OPT_gdwarf_3, options::OPT_gdwarf_4, + options::OPT_gdwarf_5)) { + Arg->claim(); + } - // -gdwarf-2 - for (auto Arg : Args.filtered(options::OPT_gdwarf_2)) { - Arg->claim(); CommonCmdArgs.push_back("-x"); CommonCmdArgs.push_back("120"); - CommonCmdArgs.push_back("0x200"); - } - // -gdwarf-3 - for (auto Arg : Args.filtered(options::OPT_gdwarf_3)) { - Arg->claim(); - CommonCmdArgs.push_back("-x"); - CommonCmdArgs.push_back("120"); - CommonCmdArgs.push_back("0x4000"); + if (!GDwarfArg) // -g without -gdwarf-X produces default (DWARFv4) + CommonCmdArgs.push_back("0x1000000"); + else if (GDwarfArg->getOption().matches(options::OPT_gdwarf_2)) // -gdwarf-2 + CommonCmdArgs.push_back("0x200"); + else if (GDwarfArg->getOption().matches(options::OPT_gdwarf_3)) // -gdwarf-3 + CommonCmdArgs.push_back("0x4000"); + else if (GDwarfArg->getOption().matches(options::OPT_gdwarf_4)) // -gdwarf-4 + CommonCmdArgs.push_back("0x1000000"); + else if (GDwarfArg->getOption().matches(options::OPT_gdwarf_5)) // -gdwarf-5 + CommonCmdArgs.push_back("0x2000000"); } // -Mipa has no effect -- Gitee From 6a03301a88ceb145059744e3d65eb37fb0af7ef2 Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Mon, 12 Oct 2020 14:19:48 -0400 Subject: [PATCH 05/32] Reduce downstream delta This commit is motivated by reducing the merge burden by shrinking the diff between llvm upstream and classic-flang-llvm-project. Outside of Flang, Fortran code is fed through the Compile phase, and the appropriate tooling is picked up through ToolChain::SelectTool. Classic Flang introduced a FortranFrontend, but these days this seems unnecessary. Fortran can go through the same machinery as everything else. * Use the Preprocess phase to preprocess Fortran code. This phase is always combined with the Compile phase. * Use the Compile phase to lower Fortran code to LLVM IR, and use the Backend phase to compile and optimize the IR. These phases are never combined. * Remove FortranFrontendJobClass. * Remove FortranFrontend tool (instead it's just the Flang tool, which in Classic Flang mode is Classic Flang). * Update tests which inspect the output of the Classic Flang tooling, and ensures that the driver does the right thing for various types of inputs. Based on a patch from Peter Waller . --- clang/include/clang/Driver/Action.h | 11 ---- clang/include/clang/Driver/Phases.h | 1 - clang/include/clang/Driver/ToolChain.h | 2 - clang/include/clang/Driver/Types.def | 8 +-- clang/lib/Driver/Action.cpp | 7 --- clang/lib/Driver/Driver.cpp | 50 ++++++++----------- clang/lib/Driver/Phases.cpp | 1 - clang/lib/Driver/ToolChain.cpp | 21 ++------ clang/lib/Driver/ToolChains/ClassicFlang.h | 2 +- .../flang/classic-flang-must-preprocess.F | 12 +++++ .../flang/classic-flang-must-preprocess.F95 | 12 +++++ clang/test/Driver/flang/classic-flang.f | 26 ++++++++++ clang/test/Driver/flang/classic-flang.f95 | 43 ++++++++++++++++ clang/test/Driver/flang/classic_flang.f95 | 28 ----------- clang/test/Driver/lit.local.cfg | 1 + 15 files changed, 123 insertions(+), 102 deletions(-) create mode 100644 clang/test/Driver/flang/classic-flang-must-preprocess.F create mode 100644 clang/test/Driver/flang/classic-flang-must-preprocess.F95 create mode 100644 clang/test/Driver/flang/classic-flang.f create mode 100644 clang/test/Driver/flang/classic-flang.f95 delete mode 100644 clang/test/Driver/flang/classic_flang.f95 diff --git a/clang/include/clang/Driver/Action.h b/clang/include/clang/Driver/Action.h index b1a91edb6158..684ccd358275 100644 --- a/clang/include/clang/Driver/Action.h +++ b/clang/include/clang/Driver/Action.h @@ -63,7 +63,6 @@ public: AnalyzeJobClass, MigrateJobClass, CompileJobClass, - FortranFrontendJobClass, BackendJobClass, AssembleJobClass, LinkJobClass, @@ -488,16 +487,6 @@ public: } }; -class FortranFrontendJobAction : public JobAction { - void anchor() override; -public: - FortranFrontendJobAction(Action *Input, types::ID OutputType); - - static bool classof(const Action *A) { - return A->getKind() == FortranFrontendJobClass; - } -}; - class CompileJobAction : public JobAction { void anchor() override; diff --git a/clang/include/clang/Driver/Phases.h b/clang/include/clang/Driver/Phases.h index f8cac9548d02..9003c5857351 100644 --- a/clang/include/clang/Driver/Phases.h +++ b/clang/include/clang/Driver/Phases.h @@ -17,7 +17,6 @@ namespace phases { enum ID { Preprocess, Precompile, - FortranFrontend, Compile, Backend, Assemble, diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index 842e93b3a09c..6f48088b3662 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -145,7 +145,6 @@ private: mutable std::unique_ptr Clang; mutable std::unique_ptr Flang; - mutable std::unique_ptr FortranFrontend; mutable std::unique_ptr Assemble; mutable std::unique_ptr Link; mutable std::unique_ptr StaticLibTool; @@ -157,7 +156,6 @@ private: Tool *getClang() const; Tool *getFlang() const; - Tool *getFortranFrontend() const; Tool *getAssemble() const; Tool *getLink() const; Tool *getStaticLibTool() const; diff --git a/clang/include/clang/Driver/Types.def b/clang/include/clang/Driver/Types.def index 7f91e348d875..8b5b3b9d6eb9 100644 --- a/clang/include/clang/Driver/Types.def +++ b/clang/include/clang/Driver/Types.def @@ -78,10 +78,10 @@ TYPE("ada", Ada, INVALID, nullptr, phases TYPE("assembler", PP_Asm, INVALID, "s", phases::Assemble, phases::Link) TYPE("assembler-with-cpp", Asm, PP_Asm, "S", phases::Preprocess, phases::Assemble, phases::Link) #ifdef ENABLE_CLASSIC_FLANG -TYPE("f77", PP_F_FixedForm, INVALID, "f", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link) -TYPE("f77-cpp-input", F_FixedForm, PP_F_FixedForm, "F", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link) -TYPE("f95", PP_F_FreeForm, INVALID, "f95", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link) -TYPE("f95-cpp-input", F_FreeForm, PP_F_FreeForm, "F95", phases::FortranFrontend, phases::Backend, phases::Assemble, phases::Link) +TYPE("f77", PP_F_FixedForm, INVALID, "f", phases::Compile, phases::Backend, phases::Assemble, phases::Link) +TYPE("f77-cpp-input", F_FixedForm, PP_F_FixedForm, "F", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link) +TYPE("f95", PP_F_FreeForm, INVALID, "f95", phases::Compile, phases::Backend, phases::Assemble, phases::Link) +TYPE("f95-cpp-input", F_FreeForm, PP_F_FreeForm, "F95", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link) #else TYPE("f95", PP_Fortran, INVALID, "i", phases::Compile, phases::Backend, phases::Assemble, phases::Link) TYPE("f95-cpp-input", Fortran, PP_Fortran, nullptr, phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link) diff --git a/clang/lib/Driver/Action.cpp b/clang/lib/Driver/Action.cpp index d77b525cd8b0..ead3a23da418 100644 --- a/clang/lib/Driver/Action.cpp +++ b/clang/lib/Driver/Action.cpp @@ -30,7 +30,6 @@ const char *Action::getClassName(ActionClass AC) { return "api-extractor"; case AnalyzeJobClass: return "analyzer"; case MigrateJobClass: return "migrator"; - case FortranFrontendJobClass: return "fortran-frontend"; case CompileJobClass: return "compiler"; case BackendJobClass: return "backend"; case AssembleJobClass: return "assembler"; @@ -364,12 +363,6 @@ void MigrateJobAction::anchor() {} MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType) : JobAction(MigrateJobClass, Input, OutputType) {} -void FortranFrontendJobAction::anchor() {} - -FortranFrontendJobAction::FortranFrontendJobAction(Action *Input, - types::ID OutputType) - : JobAction(FortranFrontendJobClass, Input, OutputType) {} - void CompileJobAction::anchor() {} CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index e5a4aa955f63..8fc5d09437f6 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -333,27 +333,15 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, // -{E,EP,P,M,MM} only run the preprocessor. if (CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) || -#ifdef ENABLE_CLASSIC_FLANG - (PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) || -#endif (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) || (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) || (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) || CCGenDiagnostics) { #ifdef ENABLE_CLASSIC_FLANG - // -fsyntax-only or -E stops Fortran compilation after FortranFrontend - if (IsFlangMode() && (DAL.getLastArg(options::OPT_E) || - DAL.getLastArg(options::OPT_fsyntax_only))) { - FinalPhase = phases::FortranFrontend; - - // if not Fortran, fsyntax_only implies 'Compile' is the FinalPhase - } else if (DAL.getLastArg(options::OPT_fsyntax_only)) { + if (IsFlangMode()) FinalPhase = phases::Compile; - - // everything else has 'Preprocess' as its FinalPhase - } else { + else FinalPhase = phases::Preprocess; - } #else FinalPhase = phases::Preprocess; #endif @@ -367,14 +355,9 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, options::OPT_fmodule_header_EQ))) { FinalPhase = phases::Precompile; -#ifdef ENABLE_CLASSIC_FLANG - // -{analyze,emit-ast} only run up to the compiler. - } else if ((PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) || -#else // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler. } else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) || (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) || -#endif (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) || (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) || (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) || @@ -3967,10 +3950,13 @@ void Driver::handleArguments(Compilation &C, DerivedArgList &Args, if (InputArg->isClaimed()) continue; - // Fortran input is preprocessed using the frontend. - if (InitialPhase == phases::FortranFrontend && +#ifdef ENABLE_CLASSIC_FLANG + // If the input is detected as already preprocessed (e.g. has the .f95 + // extension), and the user specifies -E, preprocess the file anyway. + if (IsFlangMode() && InitialPhase == phases::Compile && FinalPhase == phases::Preprocess) continue; +#endif // Claim here to avoid the more general unused warning. InputArg->claim(); @@ -4641,13 +4627,6 @@ Action *Driver::ConstructPhaseAction( ModName); return C.MakeAction(Input, OutputTy); } - case phases::FortranFrontend: { - if (Args.hasArg(options::OPT_fsyntax_only)) - return C.MakeAction(Input, - types::TY_Nothing); - return C.MakeAction(Input, - types::TY_LLVM_IR); - } case phases::Compile: { if (Args.hasArg(options::OPT_fsyntax_only)) return C.MakeAction(Input, types::TY_Nothing); @@ -4668,6 +4647,10 @@ Action *Driver::ConstructPhaseAction( return C.MakeAction(Input, types::TY_Nothing); if (Args.hasArg(options::OPT_extract_api)) return C.MakeAction(Input, types::TY_API_INFO); +#ifdef ENABLE_CLASSIC_FLANG + if (IsFlangMode()) + return C.MakeAction(Input, types::TY_LLVM_IR); +#endif return C.MakeAction(Input, types::TY_LLVM_BC); } case phases::Backend: { @@ -5096,6 +5079,10 @@ class ToolSelector final { if (!T->hasIntegratedBackend() && !(OutputIsLLVM && T->canEmitIR())) return nullptr; + // Classic Flang is not integrated with the backend. + if (C.getDriver().IsFlangMode() && !T->hasIntegratedAssembler()) + return nullptr; + if (T->canEmitIR() && ((SaveTemps && !InputIsBitcode) || EmbedBitcode)) return nullptr; @@ -6234,8 +6221,11 @@ bool Driver::ShouldUseFlangCompiler(const JobAction &JA) const { return false; // And say "no" if this is not a kind of action flang understands. - if (!isa(JA) && !isa(JA) && - !isa(JA)) + if (!isa(JA) && !isa(JA) +#ifndef ENABLE_CLASSIC_FLANG + && !isa(JA) +#endif + ) return false; return true; diff --git a/clang/lib/Driver/Phases.cpp b/clang/lib/Driver/Phases.cpp index f0216c5ab7c2..01598c59bd9e 100644 --- a/clang/lib/Driver/Phases.cpp +++ b/clang/lib/Driver/Phases.cpp @@ -16,7 +16,6 @@ const char *phases::getPhaseName(ID Id) { switch (Id) { case Preprocess: return "preprocessor"; case Precompile: return "precompiler"; - case FortranFrontend: return "fortran-frontend"; case Compile: return "compiler"; case Backend: return "backend"; case Assemble: return "assembler"; diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 87f4e670daa2..4dd7263bb30b 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -299,13 +299,13 @@ Tool *ToolChain::getClang() const { } Tool *ToolChain::getFlang() const { -#ifndef ENABLE_CLASSIC_FLANG if (!Flang) - Flang.reset(new tools::Flang(*this)); - return Flang.get(); +#ifdef ENABLE_CLASSIC_FLANG + Flang.reset(new tools::ClassicFlang(*this)); #else - llvm_unreachable("Flang is not supported by this toolchain"); + Flang.reset(new tools::Flang(*this)); #endif + return Flang.get(); } Tool *ToolChain::buildAssembler() const { @@ -326,16 +326,6 @@ Tool *ToolChain::getAssemble() const { return Assemble.get(); } -Tool *ToolChain::getFortranFrontend() const { -#ifdef ENABLE_CLASSIC_FLANG - if (!FortranFrontend) - FortranFrontend.reset(new tools::ClassicFlang(*this)); - return FortranFrontend.get(); -#else - llvm_unreachable("Fortran is not supported by this toolchain"); -#endif -} - Tool *ToolChain::getClangAs() const { if (!Assemble) Assemble.reset(new tools::ClangAs(*this)); @@ -427,9 +417,6 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const { return getOffloadPackager(); case Action::LinkerWrapperJobClass: return getLinkerWrapper(); - - case Action::FortranFrontendJobClass: - return getFortranFrontend(); } llvm_unreachable("Invalid tool kind."); diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.h b/clang/lib/Driver/ToolChains/ClassicFlang.h index 23ea1fe6b95d..5af119c2f79e 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.h +++ b/clang/lib/Driver/ToolChains/ClassicFlang.h @@ -33,7 +33,7 @@ public: bool hasGoodDiagnostics() const override { return true; } bool hasIntegratedAssembler() const override { return false; } - bool hasIntegratedCPP() const override { return false; } + bool hasIntegratedCPP() const override { return true; } void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, diff --git a/clang/test/Driver/flang/classic-flang-must-preprocess.F b/clang/test/Driver/flang/classic-flang-must-preprocess.F new file mode 100644 index 000000000000..d52c1cf8d3c0 --- /dev/null +++ b/clang/test/Driver/flang/classic-flang-must-preprocess.F @@ -0,0 +1,12 @@ +! REQUIRES: classic_flang + +! Check that the driver invokes flang1 correctly for fixed-form Fortran code +! which requires preprocessing. + +! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -c %s -### 2>&1 \ +! RUN: | FileCheck %s +! CHECK: "flang1" +! CHECK-SAME: "-preprocess" +! CHECK-SAME: "-nofreeform" +! CHECK-NEXT: "flang2" +! CHECK-NEXT: {{clang.* "-cc1"}} diff --git a/clang/test/Driver/flang/classic-flang-must-preprocess.F95 b/clang/test/Driver/flang/classic-flang-must-preprocess.F95 new file mode 100644 index 000000000000..7d452a535784 --- /dev/null +++ b/clang/test/Driver/flang/classic-flang-must-preprocess.F95 @@ -0,0 +1,12 @@ +! REQUIRES: classic_flang + +! Check that the driver invokes flang1 correctly for free-form Fortran code +! which requires preprocessing. + +! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -c %s -### 2>&1 \ +! RUN: | FileCheck %s +! CHECK: "flang1" +! CHECK-SAME: "-preprocess" +! CHECK-SAME: "-freeform" +! CHECK-NEXT: "flang2" +! CHECK-NEXT: {{clang.* "-cc1"}} diff --git a/clang/test/Driver/flang/classic-flang.f b/clang/test/Driver/flang/classic-flang.f new file mode 100644 index 000000000000..98f74d9626d7 --- /dev/null +++ b/clang/test/Driver/flang/classic-flang.f @@ -0,0 +1,26 @@ +! REQUIRES: classic_flang + +! Check that the driver invokes flang1 correctly for preprocessed fixed-form +! Fortran code. + +! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -c %s -### 2>&1 \ +! RUN: | FileCheck %s +! CHECK: "flang1" +! CHECK-NOT: "-preprocess" +! CHECK-SAME: "-nofreeform" +! CHECK-NEXT: "flang2" +! CHECK-NEXT: {{clang.* "-cc1"}} + +! Check that the driver invokes flang1 correctly when preprocessing is +! explicitly requested. + +! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -E %s -### 2>&1 \ +! RUN: | FileCheck --check-prefix=CHECK-PREPROCESS %s +! CHECK-PREPROCESS: "flang1" +! CHECK-PREPROCESS-SAME: "-preprocess" +! CHECK-PREPROCESS-SAME: "-es" +! CHECK-PREPROCESS-SAME: "-pp" +! CHECK-PREPROCESS-NOT: "flang1" +! CHECK-PREPROCESS-NOT: "flang2" +! CHECK-PREPROCESS-NOT: {{clang.* "-cc1"}} +! CHECK-PREPROCESS-NOT: {{clang.* "-cc1as"}} diff --git a/clang/test/Driver/flang/classic-flang.f95 b/clang/test/Driver/flang/classic-flang.f95 new file mode 100644 index 000000000000..0b92c799392a --- /dev/null +++ b/clang/test/Driver/flang/classic-flang.f95 @@ -0,0 +1,43 @@ +! REQUIRES: classic_flang + +! Check that the driver invokes flang1 correctly for preprocessed free-form +! Fortran code. Also check that the backend is invoked correctly. + +! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -c %s -### 2>&1 \ +! RUN: | FileCheck --check-prefix=CHECK-OBJECT %s +! CHECK-OBJECT: "flang1" +! CHECK-OBJECT-NOT: "-preprocess" +! CHECK-OBJECT-SAME: "-freeform" +! CHECK-OBJECT-NEXT: "flang2" +! CHECK-OBJECT-SAME: "-asm" [[LLFILE:.*.ll]] +! CHECK-OBJECT-NEXT: {{clang.* "-cc1"}} +! CHECK-OBJECT-SAME: "-o" "classic-flang.o" +! CHECK-OBJECT-SAME: "-x" "ir" +! CHECK-OBJECT-SAME: [[LLFILE]] + +! Check that the driver invokes flang1 correctly when preprocessing is +! explicitly requested. + +! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -E %s -### 2>&1 \ +! RUN: | FileCheck --check-prefix=CHECK-PREPROCESS %s +! CHECK-PREPROCESS: "flang1" +! CHECK-PREPROCESS-SAME: "-preprocess" +! CHECK-PREPROCESS-SAME: "-es" +! CHECK-PREPROCESS-SAME: "-pp" +! CHECK-PREPROCESS-NOT: "flang1" +! CHECK-PREPROCESS-NOT: "flang2" +! CHECK-PREPROCESS-NOT: {{clang.* "-cc1"}} +! CHECK-PREPROCESS-NOT: {{clang.* "-cc1as"}} + +! Check that the backend job (clang -cc1) is not combined into the compile job +! (flang2) even if -integrated-as is specified. + +! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -integrated-as -S %s -### 2>&1 \ +! RUN: | FileCheck --check-prefix=CHECK-ASM %s +! CHECK-ASM: "flang1" +! CHECK-ASM-NEXT: "flang2" +! CHECK-ASM-SAME: "-asm" [[LLFILE:.*.ll]] +! CHECK-ASM-NEXT: {{clang.* "-cc1"}} +! CHECK-ASM-SAME: "-o" "classic-flang.s" +! CHECK-ASM-SAME: "-x" "ir" +! CHECK-ASM-SAME: [[LLFILE]] diff --git a/clang/test/Driver/flang/classic_flang.f95 b/clang/test/Driver/flang/classic_flang.f95 deleted file mode 100644 index 5d3098786905..000000000000 --- a/clang/test/Driver/flang/classic_flang.f95 +++ /dev/null @@ -1,28 +0,0 @@ -! Check that the driver can invoke flang1 and flang2 to compile Fortran with -! --driver-mode=flang (default when the file extension is .f95). - -! REQUIRES: classic_flang - -! RUN: %clang -target x86_64-unknown-linux-gnu -integrated-as -c %s -### 2>&1 \ -! RUN: | FileCheck --check-prefix=CHECK-OBJECT %s -! CHECK-OBJECT: flang1 -! CHECK-OBJECT: flang2 -! CHECK-OBJECT-SAME: "-asm" [[LLFILE:.*.ll]] -! CHECK-OBJECT-NOT: cc1as -! CHECK-OBJECT: clang -! CHECK-OBJECT-SAME: -cc1 -! CHECK-OBJECT-SAME: "-o" "classic_flang.o" -! CHECK-OBJECT-SAME: "-x" "ir" -! CHECK-OBJECT-SAME: [[LLFILE]] - -! RUN: %clang -target x86_64-unknown-linux-gnu -integrated-as -S %s -### 2>&1 \ -! RUN: | FileCheck --check-prefix=CHECK-ASM %s -! CHECK-ASM: flang1 -! CHECK-ASM: flang2 -! CHECK-ASM-SAME: "-asm" [[LLFILE:.*.ll]] -! CHECK-ASM-NOT: cc1as -! CHECK-ASM: clang -! CHECK-ASM-SAME: -cc1 -! CHECK-ASM-SAME: "-o" "classic_flang.s" -! CHECK-ASM-SAME: "-x" "ir" -! CHECK-ASM-SAME: [[LLFILE]] diff --git a/clang/test/Driver/lit.local.cfg b/clang/test/Driver/lit.local.cfg index 671d9a4b1873..b701be566d5d 100644 --- a/clang/test/Driver/lit.local.cfg +++ b/clang/test/Driver/lit.local.cfg @@ -1,4 +1,5 @@ config.suffixes = ['.c', '.cpp', '.h', '.m', '.mm', '.S', '.s', '.f90', '.F90', '.f95', + '.F95', '.f', '.F', '.cu', '.rs', '.cl', '.clcpp', '.hip', '.hlsl'] config.substitutions = list(config.substitutions) config.substitutions.insert(0, -- Gitee From c62a120ec8b622bc5d80354c273242cd56a2d895 Mon Sep 17 00:00:00 2001 From: Kiran Chandramohan Date: Wed, 28 Oct 2020 17:08:22 +0000 Subject: [PATCH 06/32] [workflows] Set up GitHub actions for Classic Flang This commit squashes the following CI-related patches from the release_14x branch. commit 54a96d02d32f678633b3e05c4db490bfd8ec3745 Author: Kiran Chandramohan Date: Mon May 2 21:16:56 2022 -0400 [workflows] Stop using upstream actions and enable OpenMP build commit b921dd2acf4c0171ffa70c566306ba6ac1e99925 Author: michalpasztamobica Date: Fri Jun 4 13:55:52 2021 +0200 [workflows] Allow pre-compile jobs to be trigerred manually. commit 9f828fd21877085faeba914b65957945cca319e4 Author: michalpasztamobica Date: Fri Jun 4 22:09:44 2021 +0200 [workflows] Add build scripts and make CI use them. commit a976b9665c33f5b2902e79a1caaca8db8d5adc02 Author: Abraham Tovar Date: Wed Oct 13 11:40:30 2021 +0200 [workflows] LLVM release_13x CI changes commit 7a5ee225b6d5926649408e39a919d5a25cf0b759 Author: Abraham Tovar Date: Wed Nov 17 10:14:21 2021 +0000 [workflows] Removing CI test-base for release_100 commit a39a0c662d6f49a41cdfa5f23f9b5ea521bcd1e6 Author: pwisniewskimobica Date: Thu Jan 27 15:06:19 2022 +0100 [workflows] Use GCC 11 in CI builds commit 198a6b22ac62ed10e639d9e734059172a226454a Author: pwisniewskimobica Date: Thu Jan 13 10:11:43 2022 +0100 [workflows] Modify CI scripts to add more test variants commit 84ed34d208d84a30ba4ccae93c30444561d6180f Author: Bryan Chan Date: Sun Apr 24 19:13:25 2022 -0400 [workflows] support GitHub actions for release_14x branch commit dd852a697f1a86edc67184e8809ef9a12e965608 Author: Bryan Chan Date: Fri Jul 15 21:50:21 2022 -0400 [workflows] Fix CI for release_14x commit b52bcc04b83d00284f47086bc0843e2fbe489fed Author: Bryan Chan Date: Wed Jul 27 22:28:43 2022 -0400 [build] Stop caching AArch64 Docker image layers --- .github/workflows/clang-tests.yml | 6 +- .github/workflows/flang-tests.yml | 80 +++++++++ .github/workflows/libclang-abi-tests.yml | 166 ------------------ .github/workflows/libclc-tests.yml | 39 ---- .github/workflows/lld-tests.yml | 37 ---- .github/workflows/lldb-tests.yml | 40 ----- .github/workflows/llvm-project-tests.yml | 33 ++-- .github/workflows/llvm-tests.yml | 165 +---------------- .github/workflows/pre-compile_llvm.yml | 80 +++++++++ .github/workflows/repo-lockdown.yml | 19 -- build-llvm-project.sh | 94 ++++++++++ .../flang/classic-flang-must-preprocess.F | 4 +- .../flang/classic-flang-must-preprocess.F95 | 4 +- clang/test/Driver/flang/classic-flang.f | 10 +- clang/test/Driver/flang/classic-flang.f95 | 14 +- 15 files changed, 291 insertions(+), 500 deletions(-) create mode 100644 .github/workflows/flang-tests.yml delete mode 100644 .github/workflows/libclang-abi-tests.yml delete mode 100644 .github/workflows/libclc-tests.yml delete mode 100644 .github/workflows/lld-tests.yml delete mode 100644 .github/workflows/lldb-tests.yml create mode 100644 .github/workflows/pre-compile_llvm.yml delete mode 100644 .github/workflows/repo-lockdown.yml create mode 100755 build-llvm-project.sh diff --git a/.github/workflows/clang-tests.yml b/.github/workflows/clang-tests.yml index fb2d04b3b30c..f8d5fd8f4666 100644 --- a/.github/workflows/clang-tests.yml +++ b/.github/workflows/clang-tests.yml @@ -29,9 +29,9 @@ concurrency: jobs: check_clang: - if: github.repository_owner == 'llvm' - name: Test clang,lldb,libclc + if: github.repository_owner == 'flang-compiler' + name: Test clang uses: ./.github/workflows/llvm-project-tests.yml with: build_target: check-clang - projects: clang;lldb;libclc + projects: clang;openmp diff --git a/.github/workflows/flang-tests.yml b/.github/workflows/flang-tests.yml new file mode 100644 index 000000000000..410ba05290a7 --- /dev/null +++ b/.github/workflows/flang-tests.yml @@ -0,0 +1,80 @@ +name: Build and test Flang + +on: + pull_request: + branches: [ release_11x, release_12x, release_13x, release_14x ] + +jobs: + build: + runs-on: ubuntu-20.04 + env: + install_prefix: /usr/local + strategy: + matrix: + target: [X86] + cc: [clang] + cpp: [clang++] + version: [10, 11] + include: + - target: X86 + cc: gcc + cpp: g++ + version: 10 + + steps: + - uses: actions/checkout@v2 + + - if: matrix.cc == 'clang' + run: | + sudo add-apt-repository ppa:ubuntu-toolchain-r/ppa + sudo touch /etc/apt/sources.list.d/llvm.list + echo 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-11 main' | sudo tee -a /etc/apt/sources.list.d/llvm.list + echo 'deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-11 main' | sudo tee -a /etc/apt/sources.list.d/llvm.list + wget -q -O - http://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add - + sudo apt update + sudo apt install -f -y llvm-${{ matrix.version }} clang-${{ matrix.version}} + + - if: matrix.cc == 'gcc' && matrix.version == '10' + run: | + sudo add-apt-repository ppa:ubuntu-toolchain-r/ppa + sudo apt install gcc-10 g++-10 + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 10 + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 20 + sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 10 + sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 20 + + - name: ccache + uses: hendrikmuhs/ccache-action@v1 + with: + key: key-${{ matrix.cc }}-${{ matrix.version }} + + - name: Check tools + run: | + git --version + cmake --version + make --version + ${{ matrix.cc }}-${{ matrix.version }} --version + ${{ matrix.cpp }}-${{ matrix.version }} --version + + - name: Build and install llvm + run: ./build-llvm-project.sh -t ${{ matrix.target }} -p ${{ env.install_prefix }} -a /usr/bin/${{ matrix.cc }}-${{ matrix.version }} -b /usr/bin/${{ matrix.cpp }}-${{ matrix.version }} -n $(nproc) -c -i -s -v + + - name: Checkout flang + run: | + cd ../.. + git clone --depth 1 --single-branch --branch master https://github.com/flang-compiler/flang.git + + - name: Build and install libpgmath & flang + run: | + cd ../../flang + ./build-flang.sh -t ${{ matrix.target }} -p ${{ env.install_prefix }} -n $(nproc) -c -s + + - name: Copy llvm-lit + run: | + cd ../../flang + cp ../classic-flang-llvm-project/classic-flang-llvm-project/build/bin/llvm-lit build/bin/. + + - name: Test flang + run: | + cd ../../flang/build + make check-all diff --git a/.github/workflows/libclang-abi-tests.yml b/.github/workflows/libclang-abi-tests.yml deleted file mode 100644 index 8cc2f3a0fa3f..000000000000 --- a/.github/workflows/libclang-abi-tests.yml +++ /dev/null @@ -1,166 +0,0 @@ -name: libclang ABI Tests - -on: - workflow_dispatch: - push: - ignore-forks: true - branches: - - 'release/**' - paths: - - 'clang/**' - - '.github/workflows/libclang-abi-tests.yml' - pull_request: - ignore-forks: true - branches: - - 'release/**' - paths: - - 'clang/**' - - '.github/workflows/libclang-abi-tests.yml' - -concurrency: - # Skip intermediate builds: always. - # Cancel intermediate builds: only if it is a pull request build. - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} - - -jobs: - abi-dump-setup: - if: github.repository_owner == 'llvm' - runs-on: ubuntu-latest - outputs: - BASELINE_REF: ${{ steps.vars.outputs.BASELINE_REF }} - ABI_HEADERS: ${{ steps.vars.outputs.ABI_HEADERS }} - ABI_LIBS: ${{ steps.vars.outputs.ABI_LIBS }} - BASELINE_VERSION_MAJOR: ${{ steps.vars.outputs.BASELINE_VERSION_MAJOR }} - BASELINE_VERSION_MINOR: ${{ steps.vars.outputs.BASELINE_VERSION_MINOR }} - LLVM_VERSION_MAJOR: ${{ steps.version.outputs.LLVM_VERSION_MAJOR }} - LLVM_VERSION_MINOR: ${{ steps.version.outputs.LLVM_VERSION_MINOR }} - LLVM_VERSION_PATCH: ${{ steps.version.outputs.LLVM_VERSION_PATCH }} - steps: - - name: Checkout source - uses: actions/checkout@v3 - with: - fetch-depth: 250 - - - name: Get LLVM version - id: version - uses: llvm/actions/get-llvm-version@main - - - name: Setup Variables - id: vars - run: | - minor_version=0 - remote_repo='https://github.com/llvm/llvm-project' - if [ ${{ steps.version.outputs.LLVM_VERSION_MINOR }} -ne 0 -o ${{ steps.version.outputs.LLVM_VERSION_PATCH }} -eq 0 ]; then - major_version=$(( ${{ steps.version.outputs.LLVM_VERSION_MAJOR }} - 1)) - baseline_ref="llvmorg-$major_version.0.0" - - # If there is a minor release, we want to use that as the base line. - minor_ref=`git ls-remote --refs -t $remote_repo llvmorg-$major_version.[1-9].[0-9] | tail -n1 | grep -o 'llvmorg-.\+' || true` - if [ -n "$minor_ref" ]; then - baseline_ref=$minor_ref - else - # Check if we have a release candidate - rc_ref=`git ls-remote --refs -t $remote_repo llvmorg-$major_version.[1-9].[0-9]-rc* | tail -n1 | grep -o 'llvmorg-.\+' || true` - if [ -n "$rc_ref" ]; then - baseline_ref=$rc_ref - fi - fi - echo ::set-output name=BASELINE_VERSION_MAJOR::$major_version - echo ::set-output name=BASELINE_REF::$baseline_ref - echo ::set-output name=ABI_HEADERS::clang-c - echo ::set-output name=ABI_LIBS::libclang.so - else - echo ::set-output name=BASELINE_VERSION_MAJOR::${{ steps.version.outputs.LLVM_VERSION_MAJOR }} - echo ::set-output name=BASELINE_REF::llvmorg-${{ steps.version.outputs.LLVM_VERSION_MAJOR }}.0.0 - echo ::set-output name=ABI_HEADERS::. - echo ::set-output name=ABI_LIBS::libclang.so libclang-cpp.so - fi - - - abi-dump: - if: github.repository_owner == 'llvm' - needs: abi-dump-setup - runs-on: ubuntu-latest - strategy: - matrix: - name: - - build-baseline - - build-latest - include: - - name: build-baseline - llvm_version_major: ${{ needs.abi-dump-setup.outputs.BASELINE_VERSION_MAJOR }} - ref: ${{ needs.abi-dump-setup.outputs.BASELINE_REF }} - repo: llvm/llvm-project - - name: build-latest - llvm_version_major: ${{ needs.abi-dump-setup.outputs.LLVM_VERSION_MAJOR }} - ref: ${{ github.sha }} - repo: ${{ github.repository }} - steps: - - name: Install Ninja - uses: llvm/actions/install-ninja@main - - name: Install abi-compliance-checker - run: | - sudo apt-get install abi-dumper autoconf pkg-config - - name: Install universal-ctags - run: | - git clone https://github.com/universal-ctags/ctags.git - cd ctags - ./autogen.sh - ./configure - sudo make install - - name: Download source code - uses: llvm/actions/get-llvm-project-src@main - with: - ref: ${{ matrix.ref }} - repo: ${{ matrix.repo }} - - name: Configure - run: | - mkdir install - cmake -B build -S llvm -G Ninja -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_BUILD_TYPE=Debug -DLLVM_TARGETS_TO_BUILD="" -DLLVM_BUILD_LLVM_DYLIB=ON -DLLVM_LINK_LLVM_DYLIB=ON -DCMAKE_C_FLAGS_DEBUG="-g1 -Og" -DCMAKE_CXX_FLAGS_DEBUG="-g1 -Og" -DCMAKE_INSTALL_PREFIX=`pwd`/install llvm - - name: Build - run: ninja -C build/ ${{ needs.abi-dump-setup.outputs.ABI_LIBS }} install-clang-headers - - name: Dump ABI - run: | - parallel abi-dumper -lver ${{ matrix.ref }} -skip-cxx -public-headers ./install/include/${{ needs.abi-dump-setup.outputs.ABI_HEADERS }} -o {}-${{ matrix.ref }}.abi ./build/lib/{} ::: ${{ needs.abi-dump-setup.outputs.ABI_LIBS }} - for lib in ${{ needs.abi-dump-setup.outputs.ABI_LIBS }}; do - # Remove symbol versioning from dumps, so we can compare across major versions. - sed -i 's/LLVM_[0-9]\+/LLVM_NOVERSION/' $lib-${{ matrix.ref }}.abi - done - - name: Upload ABI file - uses: actions/upload-artifact@v2 - with: - name: ${{ matrix.name }} - path: "*${{ matrix.ref }}.abi" - - abi-compare: - if: github.repository_owner == 'llvm' - runs-on: ubuntu-latest - needs: - - abi-dump-setup - - abi-dump - steps: - - name: Download baseline - uses: actions/download-artifact@v1 - with: - name: build-baseline - - name: Download latest - uses: actions/download-artifact@v1 - with: - name: build-latest - - - name: Install abi-compliance-checker - run: sudo apt-get install abi-compliance-checker - - name: Compare ABI - run: | - for lib in ${{ needs.abi-dump-setup.outputs.ABI_LIBS }}; do - abi-compliance-checker -lib $lib -old build-baseline/$lib*.abi -new build-latest/$lib*.abi - done - - name: Upload ABI Comparison - if: always() - uses: actions/upload-artifact@v2 - with: - name: compat-report-${{ github.sha }} - path: compat_reports/ - diff --git a/.github/workflows/libclc-tests.yml b/.github/workflows/libclc-tests.yml deleted file mode 100644 index f4d11e253501..000000000000 --- a/.github/workflows/libclc-tests.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: libclc Tests - -on: - workflow_dispatch: - push: - ignore-forks: true - branches: - - 'release/**' - paths: - - 'libclc/**' - - '.github/workflows/libclc-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - - '!clang/**' - - '!llvm/**' - pull_request: - ignore-forks: true - branches: - - 'release/**' - paths: - - 'libclc/**' - - '.github/workflows/libclc-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - - '!clang/**' - - '!llvm/**' - -concurrency: - # Skip intermediate builds: always. - # Cancel intermediate builds: only if it is a pull request build. - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} - -jobs: - check_libclc: - if: github.repository_owner == 'llvm' - name: Test libclc - uses: ./.github/workflows/llvm-project-tests.yml - with: - build_target: '' - projects: clang;libclc diff --git a/.github/workflows/lld-tests.yml b/.github/workflows/lld-tests.yml deleted file mode 100644 index b071affb6725..000000000000 --- a/.github/workflows/lld-tests.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: LLD Tests - -on: - workflow_dispatch: - push: - ignore-forks: true - branches: - - 'release/**' - paths: - - 'lld/**' - - '.github/workflows/lld-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - - '!llvm/**' - pull_request: - ignore-forks: true - branches: - - 'release/**' - paths: - - 'lld/**' - - '.github/workflows/lld-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - - '!llvm/**' - -concurrency: - # Skip intermediate builds: always. - # Cancel intermediate builds: only if it is a pull request build. - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} - -jobs: - check_lld: - if: github.repository_owner == 'llvm' - name: Test lld - uses: ./.github/workflows/llvm-project-tests.yml - with: - build_target: check-lld - projects: lld diff --git a/.github/workflows/lldb-tests.yml b/.github/workflows/lldb-tests.yml deleted file mode 100644 index 20a46437ae02..000000000000 --- a/.github/workflows/lldb-tests.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: lldb Tests - -on: - workflow_dispatch: - push: - ignore-forks: true - branches: - - 'release/**' - paths: - - 'lldb/**' - - '.github/workflows/lldb-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - - '!clang/**' - - '!llvm/**' - pull_request: - ignore-forks: true - branches: - - 'release/**' - paths: - - 'lldb/**' - - '.github/workflows/lldb-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - - '!clang/**' - - '!llvm/**' - -concurrency: - # Skip intermediate builds: always. - # Cancel intermediate builds: only if it is a pull request build. - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} - - -jobs: - build_lldb: - if: github.repository_owner == 'llvm' - name: Build lldb - uses: ./.github/workflows/llvm-project-tests.yml - with: - build_target: '' - projects: clang;lldb diff --git a/.github/workflows/llvm-project-tests.yml b/.github/workflows/llvm-project-tests.yml index a32fe80ae11c..070211ea322a 100644 --- a/.github/workflows/llvm-project-tests.yml +++ b/.github/workflows/llvm-project-tests.yml @@ -29,14 +29,14 @@ jobs: lit-tests: name: Lit Tests runs-on: ${{ matrix.os }} + env: + install_prefix: /usr/local strategy: fail-fast: false matrix: + target: [X86] os: - ubuntu-latest - # Use windows-2019 due to: - # https://developercommunity.visualstudio.com/t/Prev-Issue---with-__assume-isnan-/1597317 - - windows-2019 # We're using a specific version of macOS due to: # https://github.com/actions/virtual-environments/issues/5900 - macOS-11 @@ -73,23 +73,20 @@ jobs: # enough cache space for all the tests to run at once and still # fit under the 10 GB limit. max-size: 500M - key: sccache-${{ matrix.os }} - variant: sccache - - name: Build and Test - uses: llvm/actions/build-test-llvm-project@main + key: ${{ matrix.os }} + - name: Test clang macOS + if: ${{ matrix.os == 'macOS-11'}} env: # Workaround for https://github.com/actions/virtual-environments/issues/5900. # This should be a no-op for non-mac OSes PKG_CONFIG_PATH: /usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig//12 - with: - cmake_args: '-GNinja -DLLVM_ENABLE_PROJECTS="${{ inputs.projects }}" -DCMAKE_BUILD_TYPE=Release -DLLDB_INCLUDE_TESTS=OFF -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache' - build_target: '${{ inputs.build_target }}' - - - name: Build and Test libclc - if: "!startsWith(matrix.os, 'windows') && contains(inputs.projects, 'libclc')" run: | - # Make sure all of LLVM libraries that llvm-config needs are built. - ninja -C build - cmake -G Ninja -S libclc -B libclc-build -DLLVM_CONFIG=`pwd`/build/bin/llvm-config -DLIBCLC_TARGETS_TO_BUILD="amdgcn--;amdgcn--amdhsa;r600--;nvptx--;nvptx64--;nvptx--nvidiacl;nvptx64--nvidiacl" - ninja -C libclc-build - ninja -C libclc-build test + ./build-llvm-project.sh -t X86 -e "clang" -p /usr/local -s -n $(sysctl -n hw.logicalcpu) -i -v + cd build + make check-all + - name: Test clang ubuntu + if: ${{ matrix.os == 'ubuntu-latest'}} + run: | + ./build-llvm-project.sh -t X86 -e "${{ inputs.projects }}" -p /usr/local -s -n $(nproc) -i -v + cd build + make check-all diff --git a/.github/workflows/llvm-tests.yml b/.github/workflows/llvm-tests.yml index 83091da4bbb4..7264c62ce134 100644 --- a/.github/workflows/llvm-tests.yml +++ b/.github/workflows/llvm-tests.yml @@ -28,168 +28,9 @@ concurrency: jobs: check_all: - if: github.repository_owner == 'llvm' - name: Test llvm,clang,libclc + if: github.repository_owner == 'flang-compiler' + name: Test llvm,clang uses: ./.github/workflows/llvm-project-tests.yml with: build_target: check-all - projects: clang;libclc - - # These need to be separate from the check_all job, becuase there is not enough disk - # space to build all these projects on Windows. - build_lldb: - if: github.repository_owner == 'llvm' - name: Build lldb - uses: ./.github/workflows/llvm-project-tests.yml - with: - build_target: '' - projects: clang;lldb - - check_lld: - if: github.repository_owner == 'llvm' - name: Test lld - uses: ./.github/workflows/llvm-project-tests.yml - with: - build_target: check-lld - projects: lld - - abi-dump-setup: - if: github.repository_owner == 'llvm' - runs-on: ubuntu-latest - outputs: - BASELINE_REF: ${{ steps.vars.outputs.BASELINE_REF }} - ABI_HEADERS: ${{ steps.vars.outputs.ABI_HEADERS }} - BASELINE_VERSION_MAJOR: ${{ steps.vars.outputs.BASELINE_VERSION_MAJOR }} - LLVM_VERSION_MAJOR: ${{ steps.version.outputs.LLVM_VERSION_MAJOR }} - LLVM_VERSION_MINOR: ${{ steps.version.outputs.LLVM_VERSION_MINOR }} - LLVM_VERSION_PATCH: ${{ steps.version.outputs.LLVM_VERSION_PATCH }} - steps: - - name: Checkout source - uses: actions/checkout@v3 - with: - fetch-depth: 250 - - - name: Get LLVM version - id: version - uses: llvm/actions/get-llvm-version@main - - - name: Setup Variables - id: vars - run: | - if [ ${{ steps.version.outputs.LLVM_VERSION_MINOR }} -ne 0 -o ${{ steps.version.outputs.LLVM_VERSION_PATCH }} -eq 0 ]; then - echo ::set-output name=BASELINE_VERSION_MAJOR::$(( ${{ steps.version.outputs.LLVM_VERSION_MAJOR }} - 1)) - echo ::set-output name=ABI_HEADERS::llvm-c - else - echo ::set-output name=BASELINE_VERSION_MAJOR::${{ steps.version.outputs.LLVM_VERSION_MAJOR }} - echo ::set-output name=ABI_HEADERS::. - fi - - abi-dump: - if: github.repository_owner == 'llvm' - needs: abi-dump-setup - runs-on: ubuntu-latest - strategy: - matrix: - name: - - build-baseline - - build-latest - include: - - name: build-baseline - llvm_version_major: ${{ needs.abi-dump-setup.outputs.BASELINE_VERSION_MAJOR }} - ref: llvmorg-${{ needs.abi-dump-setup.outputs.BASELINE_VERSION_MAJOR }}.0.0 - repo: llvm/llvm-project - - name: build-latest - llvm_version_major: ${{ needs.abi-dump-setup.outputs.LLVM_VERSION_MAJOR }} - ref: ${{ github.sha }} - repo: ${{ github.repository }} - steps: - - name: Install Ninja - uses: llvm/actions/install-ninja@main - - name: Install abi-compliance-checker - run: | - sudo apt-get install abi-dumper autoconf pkg-config - - name: Install universal-ctags - run: | - git clone https://github.com/universal-ctags/ctags.git - cd ctags - ./autogen.sh - ./configure - sudo make install - - name: Download source code - uses: llvm/actions/get-llvm-project-src@main - with: - ref: ${{ matrix.ref }} - repo: ${{ matrix.repo }} - - name: Configure - run: | - mkdir install - cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug -DLLVM_TARGETS_TO_BUILD="" -DLLVM_BUILD_LLVM_DYLIB=ON -DCMAKE_C_FLAGS_DEBUG="-g1 -Og" -DCMAKE_CXX_FLAGS_DEBUG="-g1 -Og" -DCMAKE_INSTALL_PREFIX=`pwd`/install llvm - - name: Build - # Need to run install-LLVM twice to ensure the symlink is installed (this is a bug). - run: | - ninja -C build install-LLVM - ninja -C build install-LLVM - ninja -C build install-llvm-headers - - name: Dump ABI - run: | - if [ "${{ needs.abi-dump-setup.outputs.ABI_HEADERS }}" = "llvm-c" ]; then - nm ./install/lib/libLLVM.so | awk "/T _LLVM/ || /T LLVM/ { print $3 }" | sort -u | sed -e "s/^_//g" | cut -d ' ' -f 3 > llvm.symbols - # Even though the -symbols-list option doesn't seem to filter out the symbols, I believe it speeds up processing, so I'm leaving it in. - export EXTRA_ARGS="-symbols-list llvm.symbols" - else - touch llvm.symbols - fi - abi-dumper $EXTRA_ARGS -lver ${{ matrix.ref }} -skip-cxx -public-headers ./install/include/${{ needs.abi-dump-setup.outputs.ABI_HEADERS }} -o ${{ matrix.ref }}.abi ./install/lib/libLLVM.so - # Remove symbol versioning from dumps, so we can compare across major versions. - sed -i 's/LLVM_${{ matrix.llvm_version_major }}/LLVM_NOVERSION/' ${{ matrix.ref }}.abi - - name: Upload ABI file - uses: actions/upload-artifact@v1 - with: - name: ${{ matrix.name }} - path: ${{ matrix.ref }}.abi - - - name: Upload symbol list file - if: matrix.name == 'build-baseline' - uses: actions/upload-artifact@v1 - with: - name: symbol-list - path: llvm.symbols - - abi-compare: - if: github.repository_owner == 'llvm' - runs-on: ubuntu-latest - needs: - - abi-dump-setup - - abi-dump - steps: - - name: Download baseline - uses: actions/download-artifact@v1 - with: - name: build-baseline - - name: Download latest - uses: actions/download-artifact@v1 - with: - name: build-latest - - name: Download symbol list - uses: actions/download-artifact@v1 - with: - name: symbol-list - - - name: Install abi-compliance-checker - run: sudo apt-get install abi-compliance-checker - - name: Compare ABI - run: | - if [ -s symbol-list/llvm.symbols ]; then - # This option doesn't seem to work with the ABI dumper, so passing it here. - export EXTRA_ARGS="-symbols-list symbol-list/llvm.symbols" - fi - # FIXME: Reading of gzip'd abi files on the GitHub runners stop - # working some time in March of 2021, likely due to a change in the - # runner's environment. - abi-compliance-checker $EXTRA_ARGS -l libLLVM.so -old build-baseline/*.abi -new build-latest/*.abi || test "${{ needs.abi-dump-setup.outputs.ABI_HEADERS }}" = "llvm-c" - - name: Upload ABI Comparison - if: always() - uses: actions/upload-artifact@v1 - with: - name: compat-report-${{ github.sha }} - path: compat_reports/ + projects: clang;openmp diff --git a/.github/workflows/pre-compile_llvm.yml b/.github/workflows/pre-compile_llvm.yml new file mode 100644 index 000000000000..7cb4b8ed72bd --- /dev/null +++ b/.github/workflows/pre-compile_llvm.yml @@ -0,0 +1,80 @@ +name: Pre-compile llvm + +on: + workflow_dispatch: + push: + branches: [ release_11x, release_12x, release_13x, release_14x ] + +jobs: + build: + runs-on: ubuntu-20.04 + strategy: + matrix: + target: [X86] + cc: [clang, gcc] + version: [10, 11] + + steps: + - if: matrix.cc == 'clang' + run: | + echo "cpp=clang++" >> $GITHUB_ENV + sudo add-apt-repository ppa:ubuntu-toolchain-r/ppa + sudo touch /etc/apt/sources.list.d/llvm.list + echo 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-11 main' | sudo tee -a /etc/apt/sources.list.d/llvm.list + echo 'deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-11 main' | sudo tee -a /etc/apt/sources.list.d/llvm.list + wget -q -O - http://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add - + sudo apt update + sudo apt install -f -y llvm-${{ matrix.version }} clang-${{ matrix.version}} + + - if: matrix.cc == 'gcc' && matrix.version == '10' + run: | + echo "cpp=g++" >> $GITHUB_ENV + sudo add-apt-repository ppa:ubuntu-toolchain-r/ppa + sudo apt install gcc-10 g++-10 + + - if: matrix.cc == 'gcc' && matrix.version == '11' + run: | + echo "cpp=g++" >> $GITHUB_ENV + sudo add-apt-repository ppa:ubuntu-toolchain-r/ppa + sudo apt install gcc-11 g++-11 + + - name: Check tools + run: | + git --version + cmake --version + make --version + ${{ matrix.cc }}-${{ matrix.version }} --version + ${{env.cpp}}-${{ matrix.version }} --version + + - name: Extract branch name + run: echo "::set-output name=branch::${GITHUB_REF#refs/heads/}" + id: extract_branch + + - name: Build llvm + run: | + # exit the llvm dir, so the path is the same on subsequent projects + cd ../.. + rm -rf classic-flang-llvm-project + # clone manually, because checkout does not allow exiting llvm dir + git clone --depth 1 --single-branch --branch ${{ steps.extract_branch.outputs.branch }} https://github.com/flang-compiler/classic-flang-llvm-project.git + cd classic-flang-llvm-project + # After build place the artifacts in classic-flang-llvm-project/classic-flang-llvm-project, so Upload can find them. + mkdir classic-flang-llvm-project + ./build-llvm-project.sh \ + -t ${{ matrix.target }} \ + -p /usr/local \ + -a /usr/bin/${{ matrix.cc }}-${{ matrix.version }} \ + -b /usr/bin/${{env.cpp}}-${{ matrix.version }} \ + -n $(nproc) \ + -v + # Archive the source + build directories for future installation + cd .. + tar -zcf llvm_build.tar.gz classic-flang-llvm-project + # Upload will only look in $GITHUB_WORKSPACE or its subdirs. + mv llvm_build.tar.gz classic-flang-llvm-project/classic-flang-llvm-project/. + + - name: Upload llvm + uses: actions/upload-artifact@v2 + with: + name: llvm_build_${{ matrix.target }}_${{ matrix.cc }}_${{ matrix.version }}_${{ steps.extract_branch.outputs.branch }} + path: llvm_build.tar.gz diff --git a/.github/workflows/repo-lockdown.yml b/.github/workflows/repo-lockdown.yml deleted file mode 100644 index f7b56907cbaf..000000000000 --- a/.github/workflows/repo-lockdown.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: 'Repo Lockdown' -on: - pull_request_target: - types: opened - -permissions: - pull-requests: write - -jobs: - action: - runs-on: ubuntu-latest - if: github.repository == 'llvm/llvm-project' - steps: - - uses: dessant/repo-lockdown@v2 - with: - process-only: 'prs' - pr-comment: > - This repository does not accept pull requests. - Please follow http://llvm.org/docs/Contributing.html#how-to-submit-a-patch for contribution to LLVM. diff --git a/build-llvm-project.sh b/build-llvm-project.sh new file mode 100755 index 000000000000..5e3368637d99 --- /dev/null +++ b/build-llvm-project.sh @@ -0,0 +1,94 @@ +#!/bin/bash + +# Initialize our own variables: +TARGET="X86" +BUILD_TYPE="Release" +INSTALL_PREFIX="/usr/local" +NPROC=1 +USE_CCACHE="0" +DO_INSTALL="0" +USE_SUDO="0" +C_COMPILER_PATH="/usr/bin/gcc" +CXX_COMPILER_PATH="/usr/bin/g++" +LLVM_ENABLE_PROJECTS="clang;openmp" +VERBOSE="" + +set -e # Exit script on first error. + +function print_usage { + echo "Usage: ./build-llvm-project.sh [options]"; + echo ""; + echo "Build and install classic-flang-llvm-project."; + echo "Run this script in a directory with project sources."; + echo "Example:"; + echo " $ git clone https://github.com/flang-compiler/classic-flang-llvm-project"; + echo " $ cd classic-flang-llvm-project"; + echo " $ .github/workflows/build-llvm-project.sh -t X86 -p /install/prefix/ \\"; + echo " $ -a /usr/bin/gcc-10 -b /usr/bin/g++-10 -i -s"; + echo ""; + echo "Options:"; + echo " -t Target to build for (X86, AArch64, PowerPC). Default: X86"; + echo " -d Set the CMake build type. Default: Release"; + echo " -p Install prefix. Default: /usr/local"; + echo " -n Number of parallel jobs. Default: 1"; + echo " -c Use ccache. Default: 0 - do not use ccache"; + echo " -i Install the build. Default 0 - just build, do not install"; + echo " -s Use sudo to install. Default: 0 - do not use sudo"; + echo " -a C compiler path. Default: /usr/bin/gcc"; + echo " -b C++ compiler path. Default: /usr/bin/g++"; + echo " -e List of the LLVM sub-projects to build. Default: clang;openmp"; + echo " -v Enable verbose output"; +} +while getopts "t:d:p:n:c?i?s?a:b:e:v" opt; do + case "$opt" in + t) TARGET=$OPTARG;; + d) BUILD_TYPE=$OPTARG;; + p) INSTALL_PREFIX=$OPTARG;; + n) NPROC=$OPTARG;; + c) USE_CCACHE="1";; + i) DO_INSTALL="1";; + s) USE_SUDO="1";; + a) C_COMPILER_PATH=$OPTARG;; + b) CXX_COMPILER_PATH=$OPTARG;; + e) LLVM_ENABLE_PROJECTS=$OPTARG;; + v) VERBOSE="1";; + ?) print_usage; exit 0;; + esac +done + +CMAKE_OPTIONS="-DCMAKE_INSTALL_PREFIX=$INSTALL_PREFIX \ + -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ + -DCMAKE_C_COMPILER=$C_COMPILER_PATH \ + -DCMAKE_CXX_COMPILER=$CXX_COMPILER_PATH \ + -DLLVM_TARGETS_TO_BUILD=$TARGET \ + -DLLVM_ENABLE_CLASSIC_FLANG=ON \ + -DFLANG_BUILD_NEW_DRIVER=OFF" +# Warning: the -DLLVM_ENABLE_PROJECTS option is specified with cmake +# to avoid issues with nested quotation marks + +if [ $USE_CCACHE == "1" ]; then + echo "Build using ccache" + CMAKE_OPTIONS="$CMAKE_OPTIONS \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache" +fi + +# Build and install +mkdir -p build && cd build +if [ -n "$VERBOSE" ]; then + set -x +fi +cmake $CMAKE_OPTIONS -DLLVM_ENABLE_PROJECTS=$LLVM_ENABLE_PROJECTS ../llvm +set +x +make -j$NPROC VERBOSE=$VERBOSE +if [ $DO_INSTALL == "1" ]; then + if [ $USE_SUDO == "1" ]; then + echo "Install with sudo" + sudo make install + else + echo "Install without sudo" + make install + fi +fi +cd .. + diff --git a/clang/test/Driver/flang/classic-flang-must-preprocess.F b/clang/test/Driver/flang/classic-flang-must-preprocess.F index d52c1cf8d3c0..cf2e4207a4a0 100644 --- a/clang/test/Driver/flang/classic-flang-must-preprocess.F +++ b/clang/test/Driver/flang/classic-flang-must-preprocess.F @@ -5,8 +5,8 @@ ! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -c %s -### 2>&1 \ ! RUN: | FileCheck %s -! CHECK: "flang1" +! CHECK: "{{.*}}flang1" ! CHECK-SAME: "-preprocess" ! CHECK-SAME: "-nofreeform" -! CHECK-NEXT: "flang2" +! CHECK-NEXT: "{{.*}}flang2" ! CHECK-NEXT: {{clang.* "-cc1"}} diff --git a/clang/test/Driver/flang/classic-flang-must-preprocess.F95 b/clang/test/Driver/flang/classic-flang-must-preprocess.F95 index 7d452a535784..85ec49fe3fab 100644 --- a/clang/test/Driver/flang/classic-flang-must-preprocess.F95 +++ b/clang/test/Driver/flang/classic-flang-must-preprocess.F95 @@ -5,8 +5,8 @@ ! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -c %s -### 2>&1 \ ! RUN: | FileCheck %s -! CHECK: "flang1" +! CHECK: "{{.*}}flang1" ! CHECK-SAME: "-preprocess" ! CHECK-SAME: "-freeform" -! CHECK-NEXT: "flang2" +! CHECK-NEXT: "{{.*}}flang2" ! CHECK-NEXT: {{clang.* "-cc1"}} diff --git a/clang/test/Driver/flang/classic-flang.f b/clang/test/Driver/flang/classic-flang.f index 98f74d9626d7..c680abc076ae 100644 --- a/clang/test/Driver/flang/classic-flang.f +++ b/clang/test/Driver/flang/classic-flang.f @@ -5,10 +5,10 @@ ! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -c %s -### 2>&1 \ ! RUN: | FileCheck %s -! CHECK: "flang1" +! CHECK: "{{.*}}flang1" ! CHECK-NOT: "-preprocess" ! CHECK-SAME: "-nofreeform" -! CHECK-NEXT: "flang2" +! CHECK-NEXT: "{{.*}}flang2" ! CHECK-NEXT: {{clang.* "-cc1"}} ! Check that the driver invokes flang1 correctly when preprocessing is @@ -16,11 +16,11 @@ ! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -E %s -### 2>&1 \ ! RUN: | FileCheck --check-prefix=CHECK-PREPROCESS %s -! CHECK-PREPROCESS: "flang1" +! CHECK-PREPROCESS: "{{.*}}flang1" ! CHECK-PREPROCESS-SAME: "-preprocess" ! CHECK-PREPROCESS-SAME: "-es" ! CHECK-PREPROCESS-SAME: "-pp" -! CHECK-PREPROCESS-NOT: "flang1" -! CHECK-PREPROCESS-NOT: "flang2" +! CHECK-PREPROCESS-NOT: "{{.*}}flang1" +! CHECK-PREPROCESS-NOT: "{{.*}}flang2" ! CHECK-PREPROCESS-NOT: {{clang.* "-cc1"}} ! CHECK-PREPROCESS-NOT: {{clang.* "-cc1as"}} diff --git a/clang/test/Driver/flang/classic-flang.f95 b/clang/test/Driver/flang/classic-flang.f95 index 0b92c799392a..6fce9c61713c 100644 --- a/clang/test/Driver/flang/classic-flang.f95 +++ b/clang/test/Driver/flang/classic-flang.f95 @@ -5,10 +5,10 @@ ! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -c %s -### 2>&1 \ ! RUN: | FileCheck --check-prefix=CHECK-OBJECT %s -! CHECK-OBJECT: "flang1" +! CHECK-OBJECT: "{{.*}}flang1" ! CHECK-OBJECT-NOT: "-preprocess" ! CHECK-OBJECT-SAME: "-freeform" -! CHECK-OBJECT-NEXT: "flang2" +! CHECK-OBJECT-NEXT: "{{.*}}flang2" ! CHECK-OBJECT-SAME: "-asm" [[LLFILE:.*.ll]] ! CHECK-OBJECT-NEXT: {{clang.* "-cc1"}} ! CHECK-OBJECT-SAME: "-o" "classic-flang.o" @@ -20,12 +20,12 @@ ! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -E %s -### 2>&1 \ ! RUN: | FileCheck --check-prefix=CHECK-PREPROCESS %s -! CHECK-PREPROCESS: "flang1" +! CHECK-PREPROCESS: "{{.*}}flang1" ! CHECK-PREPROCESS-SAME: "-preprocess" ! CHECK-PREPROCESS-SAME: "-es" ! CHECK-PREPROCESS-SAME: "-pp" -! CHECK-PREPROCESS-NOT: "flang1" -! CHECK-PREPROCESS-NOT: "flang2" +! CHECK-PREPROCESS-NOT: "{{.*}}flang1" +! CHECK-PREPROCESS-NOT: "{{.*}}flang2" ! CHECK-PREPROCESS-NOT: {{clang.* "-cc1"}} ! CHECK-PREPROCESS-NOT: {{clang.* "-cc1as"}} @@ -34,8 +34,8 @@ ! RUN: %clang --driver-mode=flang -target x86_64-unknown-linux-gnu -integrated-as -S %s -### 2>&1 \ ! RUN: | FileCheck --check-prefix=CHECK-ASM %s -! CHECK-ASM: "flang1" -! CHECK-ASM-NEXT: "flang2" +! CHECK-ASM: "{{.*}}flang1" +! CHECK-ASM-NEXT: "{{.*}}flang2" ! CHECK-ASM-SAME: "-asm" [[LLFILE:.*.ll]] ! CHECK-ASM-NEXT: {{clang.* "-cc1"}} ! CHECK-ASM-SAME: "-o" "classic-flang.s" -- Gitee From a65cb41bfafcec5586ca3ec52b4c124444b6d15c Mon Sep 17 00:00:00 2001 From: Sourabh Singh Tomar Date: Fri, 16 Apr 2021 12:29:12 +0530 Subject: [PATCH 07/32] [DebugInfo] Support of `-gpubnames` in Driver --- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index f297989910c5..162970e13832 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -355,6 +355,13 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, CommonCmdArgs.push_back("0x1000000"); else if (GDwarfArg->getOption().matches(options::OPT_gdwarf_5)) // -gdwarf-5 CommonCmdArgs.push_back("0x2000000"); + // Handle `-gpubnames` option separately. + for (auto Arg : Args.filtered(options::OPT_gpubnames)) { + Arg->claim(); + CommonCmdArgs.push_back("-x"); + CommonCmdArgs.push_back("120"); + CommonCmdArgs.push_back("0x40000000"); // -gpubnames + } } // -Mipa has no effect -- Gitee From 899526990ffa45e9a30ac08fa62eff6668b97365 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 6 Aug 2021 05:10:31 -0700 Subject: [PATCH 08/32] [Driver] Support macOS --- clang/lib/Driver/ToolChain.cpp | 4 +++- clang/lib/Driver/ToolChains/Darwin.cpp | 12 ++++++++++++ clang/lib/Driver/ToolChains/Gnu.cpp | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 4dd7263bb30b..86b778cce97a 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1074,7 +1074,9 @@ void ToolChain::AddFortranStdlibLibArgs(const ArgList &Args, CmdArgs.push_back("-Bdynamic"); CmdArgs.push_back("-lm"); - CmdArgs.push_back("-lrt"); + + if (!Triple.isOSDarwin()) + CmdArgs.push_back("-lrt"); // Allways link Fortran executables with Pthreads CmdArgs.push_back("-lpthread"); diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index bada811daadf..13ec8894c021 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -678,6 +678,18 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (getToolChain().ShouldLinkCXXStdlib(Args)) getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); +#ifdef ENABLE_CLASSIC_FLANG + // Add Fortran runtime libraries + if (needFortranLibs(getToolChain().getDriver(), Args)) { + getToolChain().AddFortranStdlibLibArgs(Args, CmdArgs); + } else { + // Claim "no Flang libraries" arguments if any + for (auto Arg : Args.filtered(options::OPT_noFlangLibs)) { + Arg->claim(); + } + } +#endif + bool NoStdOrDefaultLibs = Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs); bool ForceLinkBuiltins = Args.hasArg(options::OPT_fapple_link_rtlib); diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index 9d5707713210..69e34dfa3fed 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -572,7 +572,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (needFortranLibs(D, Args)) { ToolChain.AddFortranStdlibLibArgs(Args, CmdArgs); } else { - // Claim "no Flang libraries" arguments if any + // Claim "no Flang libraries" arguments if any for (auto Arg : Args.filtered(options::OPT_noFlangLibs)) { Arg->claim(); } -- Gitee From 3ed8c91ac0caee7444eadfd8220b162d306dddfa Mon Sep 17 00:00:00 2001 From: Itay Bookstein Date: Wed, 22 Sep 2021 16:56:52 +0300 Subject: [PATCH 09/32] [DebugInfo]: Remove dangerous dead function (-Wreturn-stack-address) Signed-off-by: Itay Bookstein --- llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h | 8 -------- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 6 ------ 2 files changed, 14 deletions(-) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index 2e41e1e06272..61412cde34c8 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -146,14 +146,6 @@ public: std::vector ExprRefedBaseTypes; -private: - DenseMap> *globalVarMap; -public: - void setGlobalVarMap( - DenseMap> *p = nullptr) { - globalVarMap = p; - } - /// Get or create global variable DIE. DIE * getOrCreateGlobalVariableDIE(const DIGlobalVariable *GV, diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 18087d607148..c8cbbf6eb464 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1215,17 +1215,11 @@ void DwarfDebug::beginModule(Module *M) { } DenseSet Processed; -#if 0 - CU.setGlobalVarMap(&GVMap); -#endif for (auto *GVE : CUNode->getGlobalVariables()) { DIGlobalVariable *GV = GVE->getVariable(); if (Processed.insert(GV).second) CU.getOrCreateGlobalVariableDIE(GV, sortGlobalExprs(GVMap[GV])); } -#if 0 - CU.setGlobalVarMap(); -#endif for (auto *Ty : CUNode->getEnumTypes()) CU.getOrCreateTypeDIE(cast(Ty)); -- Gitee From 2c1ca10c79b7bc9511e9404465e505976e190289 Mon Sep 17 00:00:00 2001 From: Itay Bookstein Date: Wed, 22 Sep 2021 17:12:19 +0300 Subject: [PATCH 10/32] [ClassicFlang][Driver] Fix warnings * -Wsuggest-override for ClassicFlangMacroBuilder::defineMacro * -Wrange-loop-construct when iterating over llvm::opt::Arg::getValues Signed-off-by: Itay Bookstein --- clang/lib/Driver/ToolChains/Clang.cpp | 4 ++-- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index a8fd2ae6bfcb..69aa3404f58c 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5109,7 +5109,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, PassRemarkVal = ".*"; Args.ClaimAllArgs(options::OPT_Minfoall); } else if (Arg *A = Args.getLastArg(options::OPT_Minfo_EQ)) { - for (const StringRef &val : A->getValues()) { + for (StringRef val : A->getValues()) { if (val.equals("all")) { PassRemarkVal = ".*"; break; @@ -5135,7 +5135,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, PassRemarkVal = ".*"; Args.ClaimAllArgs(options::OPT_Mneginfoall); } else if (Arg *A = Args.getLastArg(options::OPT_Mneginfo_EQ)) { - for (const StringRef &val : A->getValues()) { + for (StringRef val : A->getValues()) { if (val.equals("all")) { PassRemarkVal = ".*"; break; diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index 162970e13832..3bfbc410ffbf 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -50,7 +50,7 @@ class ClassicFlangMacroBuilder : public MacroBuilder { ClassicFlangMacroBuilder(ArgStringList &UpperCmdArgs, const ArgList &DriverArgs, llvm::raw_string_ostream &Output) : MacroBuilder(Output), CmdArgs(UpperCmdArgs), DriverArgs(DriverArgs) { } - virtual void defineMacro(const Twine &Name, const Twine &Value = "1") { + virtual void defineMacro(const Twine &Name, const Twine &Value = "1") override { CmdArgs.push_back("-def"); CmdArgs.push_back(DriverArgs.MakeArgString(Name + Twine('=') + Value)); } @@ -212,7 +212,7 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, // Contiguous pointer checks if (Arg *A = Args.getLastArg(options::OPT_fsanitize_EQ)) { - for (const StringRef &val : A->getValues()) { + for (StringRef val : A->getValues()) { if (val.equals("discontiguous") || val.equals("undefined") ) { // -x 54 0x40 -x 54 0x80 -x 54 0x200 UpperCmdArgs.push_back("-x"); -- Gitee From 3209fbd16ce937565f11f631b8bbfe17f3fd5036 Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Wed, 26 Jan 2022 17:30:32 +0000 Subject: [PATCH 11/32] [driver] Add -emit-flang-llvm option -emit-flang-llvm instructs flang to stop after flang2 and dump the LLVM IR. Can be useful for debugging and also would be a useful option for testing flang output more accurately. Signed-off-by: Richard Barton --- clang/include/clang/Driver/Options.td | 4 ++++ clang/lib/Driver/Driver.cpp | 3 +++ clang/lib/Driver/ToolChains/ClassicFlang.cpp | 7 +++++++ 3 files changed, 14 insertions(+) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 09508e82f4bb..e462b49ee683 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1103,6 +1103,10 @@ def d_Flag : Flag<["-"], "d">, Group; def d_Joined : Joined<["-"], "d">, Group; def emit_ast : Flag<["-"], "emit-ast">, Flags<[CoreOption]>, HelpText<"Emit Clang AST files for source inputs">; +#ifdef ENABLE_CLASSIC_FLANG +def emit_flang_llvm : Flag<["-"], "emit-flang-llvm">, + HelpText<"Emit Flang LLVM files for source inputs">; +#endif 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, diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 8fc5d09437f6..386919d1c436 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -359,6 +359,9 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, } else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) || (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) || (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) || +#ifdef ENABLE_CLASSIC_FLANG + (PhaseArg = DAL.getLastArg(options::OPT_emit_flang_llvm)) || +#endif (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) || (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) || (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) || diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index 3bfbc410ffbf..9c974a4df585 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -86,6 +86,13 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, llvm::sys::path::replace_extension(Stem, ""); } +#ifdef ENABLE_CLASSIC_FLANG + if (Args.hasArg(options::OPT_emit_flang_llvm)) { + // -emit-flang-llvm only supports asm output so claim -S to prevent warning + Args.ClaimAllArgs(options::OPT_S); + } +#endif + // Add input file name to the compilation line UpperCmdArgs.push_back(Input.getBaseInput()); -- Gitee From 5c4e4d3fc0531ae51857f80949641747a9190c62 Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Tue, 1 Feb 2022 08:21:08 +0000 Subject: [PATCH 12/32] [driver] Add regression test --- .../Driver/flang/classic-flang-emit-flang-llvm.f95 | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 clang/test/Driver/flang/classic-flang-emit-flang-llvm.f95 diff --git a/clang/test/Driver/flang/classic-flang-emit-flang-llvm.f95 b/clang/test/Driver/flang/classic-flang-emit-flang-llvm.f95 new file mode 100644 index 000000000000..225207c85db7 --- /dev/null +++ b/clang/test/Driver/flang/classic-flang-emit-flang-llvm.f95 @@ -0,0 +1,10 @@ +! REQUIRES: classic_flang + +! Check that the -emit-flang-llvm option dumps LLVM IR pre-optimisation + +! RUN: %clang --driver-mode=flang -emit-flang-llvm -S -o %t.ll %s -### 2>&1 \ +! RUN: | FileCheck %s +! CHECK-NOT: argument unused during compilation: '-S' +! CHECK: "{{.*}}flang1" +! CHECK-NEXT: "{{.*}}flang2" +! CHECK-NOT: "{{.*}}clang{{.*}}" "-cc1" -- Gitee From 24cf74745276502a0eb498c3768ddfd9ed4e5493 Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Mon, 15 Nov 2021 09:47:24 +0000 Subject: [PATCH 13/32] [driver] Add infrastructure for testing the flang-driver in lit Add %flang as a tool substitution available in lit tests. This apes the way %clang is defined and adds a $FLANG override in a similar vein. To avoid this being dead code, add a single test to check the flang driver is reporting the correct phases when running under various phase control options. Signed-off-by: Richard Barton --- clang/test/Driver/fortran-phases.f90 | 102 +++++++++++++++++++++++++++ llvm/utils/lit/lit/TestingConfig.py | 1 + llvm/utils/lit/lit/llvm/config.py | 10 +++ 3 files changed, 113 insertions(+) create mode 100644 clang/test/Driver/fortran-phases.f90 diff --git a/clang/test/Driver/fortran-phases.f90 b/clang/test/Driver/fortran-phases.f90 new file mode 100644 index 000000000000..5a79bb26bcde --- /dev/null +++ b/clang/test/Driver/fortran-phases.f90 @@ -0,0 +1,102 @@ +! Test to see that the correct phases are run for the commandline input + +! REQUIRES: classic_flang + +! RUN: %flang -ccc-print-phases 2>&1 %s | FileCheck %s --check-prefix=LINK-NOPP +! RUN: %flang -ccc-print-phases -c 2>&1 %s | FileCheck %s --check-prefix=CONLY-NOPP +! RUN: %flang -ccc-print-phases -S 2>&1 %s | FileCheck %s --check-prefix=AONLY-NOPP +! RUN: %flang -ccc-print-phases -c -emit-llvm 2>&1 %s | FileCheck %s --check-prefix=LLONLY-NOPP +! RUN: %flang -ccc-print-phases -S -emit-llvm 2>&1 %s | FileCheck %s --check-prefix=LLONLY-NOPP +! RUN: %flang -ccc-print-phases -fsyntax-only 2>&1 %s | FileCheck %s --check-prefix=SONLY-NOPP +! RUN: %flang -ccc-print-phases -E 2>&1 %s | FileCheck %s --check-prefix=PPONLY-NOPP + +! RUN: %flang -ccc-print-phases 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=LINK +! RUN: %flang -ccc-print-phases 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=LINK +! RUN: %flang -ccc-print-phases -c 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=CONLY +! RUN: %flang -ccc-print-phases -S 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=AONLY +! RUN: %flang -ccc-print-phases -c -emit-llvm 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=LLONLY +! RUN: %flang -ccc-print-phases -S -emit-llvm 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=LLONLY +! RUN: %flang -ccc-print-phases -fsyntax-only 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=SONLY +! RUN: %flang -ccc-print-phases -E 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=PPONLY + +! LINK-NOPP: 0: input, {{.*}}, f95 +! LINK-NOPP: 1: compiler, {0}, ir +! LINK-NOPP: 2: backend, {1}, assembler +! LINK-NOPP: 3: assembler, {2}, object +! LINK-NOPP: 4: linker, {3}, image + +! CONLY-NOPP: 0: input, {{.*}}, f95 +! CONLY-NOPP: 1: compiler, {0}, ir +! CONLY-NOPP: 2: backend, {1}, assembler +! CONLY-NOPP: 3: assembler, {2}, object +! CONLY-NOPP-NOT: 4: linker, {3}, image + +! AONLY-NOPP: 0: input, {{.*}}, f95 +! AONLY-NOPP: 1: compiler, {0}, ir +! AONLY-NOPP: 2: backend, {1}, assembler +! AONLY-NOPP-NOT: 3: assembler, {2}, object +! AONLY-NOPP-NOT: 4: linker, {3}, image + +! LLONLY-NOPP: 0: input, {{.*}}, f95 +! LLONLY-NOPP: 1: compiler, {0}, ir +! LLONLY-NOPP-NOT: 2: backend, {1}, assembler +! LLONLY-NOPP-NOT: 3: assembler, {2}, object +! LLONLY-NOPP-NOT: 4: linker, {3}, image + +! SONLY-NOPP: 0: input, {{.*}}, f95 +! SONLY-NOPP-NOT: 1: compiler, {0}, ir +! SONLY-NOPP-NOT: 2: backend, {1}, assembler +! SONLY-NOPP-NOT: 3: assembler, {2}, object +! SONLY-NOPP-NOT: 4: linker, {3}, image + +! PPONLY-NOPP: 0: input, {{.*}}, f95 +! PPONLY-NOPP: 1: compiler, {0}, ir +! PPONLY-NOPP-NOT: 2: backend, {1}, assembler +! PPONLY-NOPP-NOT: 3: assembler, {2}, object +! PPONLY-NOPP-NOT: 4: linker, {3}, image + +! LINK: 0: input, {{.*}}, f95-cpp-input +! LINK: 1: preprocessor, {0}, f95 +! LINK: 2: compiler, {1}, ir +! LINK: 3: backend, {2}, assembler +! LINK: 4: assembler, {3}, object +! LINK: 5: linker, {4}, image + +! CONLY: 0: input, {{.*}}, f95-cpp-input +! CONLY: 1: preprocessor, {0}, f95 +! CONLY: 2: compiler, {1}, ir +! CONLY: 3: backend, {2}, assembler +! CONLY: 4: assembler, {3}, object +! CONLY-NOT: 5: linker, {4}, image + +! AONLY: 0: input, {{.*}}, f95-cpp-input +! AONLY: 1: preprocessor, {0}, f95 +! AONLY: 2: compiler, {1}, ir +! AONLY: 3: backend, {2}, assembler +! AONLY-NOT: 4: assembler, {3}, object +! AONLY-NOT: 5: linker, {4}, image + +! LLONLY: 0: input, {{.*}}, f95-cpp-input +! LLONLY: 1: preprocessor, {0}, f95 +! LLONLY: 2: compiler, {1}, ir +! LLONLY-NOT: 3: backend, {2}, assembler +! LLONLY-NOT: 4: assembler, {3}, object +! LLONLY-NOT: 5: linker, {4}, image + +! SONLY: 0: input, {{.*}}, f95-cpp-input +! SONLY: 1: preprocessor, {0}, f95 +! SONLY-NOT: 2: compiler, {1}, ir +! SONLY-NOT: 3: backend, {2}, assembler +! SONLY-NOT: 4: assembler, {3}, object +! SONLY-NOT: 5: linker, {4}, image + +! PPONLY: 0: input, {{.*}}, f95-cpp-input +! PPONLY: 1: preprocessor, {0}, f95 +! PPONLY: 2: compiler, {1}, ir +! PPONLY-NOT: 3: backend, {2}, assembler +! PPONLY-NOT: 4: assembler, {3}, object +! PPONLY-NOT: 5: linker, {4}, image + +program hello + write(*, *) "Hello" +end program hello diff --git a/llvm/utils/lit/lit/TestingConfig.py b/llvm/utils/lit/lit/TestingConfig.py index 55e2a764d8fa..a69a2ee0b8fc 100644 --- a/llvm/utils/lit/lit/TestingConfig.py +++ b/llvm/utils/lit/lit/TestingConfig.py @@ -27,6 +27,7 @@ class TestingConfig(object): 'SYSTEMROOT', 'TERM', 'CLANG', + 'FLANG', 'LLDB', 'LD_PRELOAD', 'LLVM_SYMBOLIZER_PATH', diff --git a/llvm/utils/lit/lit/llvm/config.py b/llvm/utils/lit/lit/llvm/config.py index 7dae83733f31..b16e035b77ea 100644 --- a/llvm/utils/lit/lit/llvm/config.py +++ b/llvm/utils/lit/lit/llvm/config.py @@ -457,6 +457,8 @@ class LLVMConfig(object): just-built or optionally an installed clang, and add a set of standard substitutions useful to any test suite that makes use of clang. + Also sets up use of flang + """ # Clear some environment variables that might affect Clang. # @@ -544,6 +546,14 @@ class LLVMConfig(object): self.config.substitutions.append( ('%resource_dir', builtin_include_dir)) + self.config.flang = self.use_llvm_tool( + 'flang', search_env='FLANG', required=required) + if self.config.flang: + tool_substitutions = [ + ToolSubst('%flang', command=self.config.flang) + ] + self.add_tool_substitutions(tool_substitutions) + self.config.substitutions.append( ('%itanium_abi_triple', self.make_itanium_abi_triple(self.config.target_triple))) -- Gitee From 8b62cbd5d17b5d5928f6468ca986bf1bed685ff7 Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Mon, 25 Apr 2022 15:18:45 -0400 Subject: [PATCH 14/32] [LoopVectorize] Revert Classic Flang patch causing AArch64 test failure This patch partially reverts the following commit from an early version of Classic Flang LLVM: https://github.com/flang-compiler/llvm/commit/68669092a5ad1fd29f62346dc30973f86cfacbfe When the LoopVectorize.cpp change in that commit is ported to LLVM 14, it causes a failure in the following test: llvm/test/Transforms/LoopVectorize/AArch64/smallest-and-widest-types.ll Reverting the change allows all tests to run cleanly. --- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 28dce7f0857d..5fd4e45d80fb 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -5574,10 +5574,8 @@ void LoopVectorizationCostModel::collectElementTypesForWidening() { if (ValuesToIgnore.count(&I)) continue; - // Examine Loads, Stores, PHINodes - // Also examine instructions which convert to a float/double - if (!isa(I) && !isa(I) && !isa(I) && - !isa(I) && !isa(I) && !isa(I)) + // Only examine Loads, Stores and PHINodes. + if (!isa(I) && !isa(I) && !isa(I)) continue; // Examine PHI nodes that are reduction variables. Update the type to -- Gitee From 788473f69b0d79bd2c52de8c7b3effdf5aa72e1a Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Fri, 12 Nov 2021 17:10:05 +0000 Subject: [PATCH 15/32] [driver] Pass LLVM target_features to flang Pass LLVM target features (-mattr strings) to flang to embed in generated .ll files. For normal compilation this won't make much difference as the attributes are passed to clang after flang2 and can be applied there but this is crucial to enable LTO with flang as clang will not apply the attributes when building the flang2 output. libLTO will need to read these out of the object files to apply them. Signed-off-by: Richard Barton --- clang/lib/Driver/ToolChains/Clang.cpp | 79 +---------------- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 32 +++++-- clang/lib/Driver/ToolChains/CommonArgs.cpp | 90 +++++++++++++++++++- clang/lib/Driver/ToolChains/CommonArgs.h | 7 ++ clang/test/Driver/emit-flang-attrs.f90 | 11 +++ 5 files changed, 133 insertions(+), 86 deletions(-) create mode 100644 clang/test/Driver/emit-flang-attrs.f90 diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 69aa3404f58c..929b4d909c0f 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -10,7 +10,6 @@ #include "AMDGPU.h" #include "Arch/AArch64.h" #include "Arch/ARM.h" -#include "Arch/CSKY.h" #include "Arch/M68k.h" #include "Arch/Mips.h" #include "Arch/PPC.h" @@ -21,7 +20,6 @@ #include "Arch/X86.h" #include "CommonArgs.h" #include "Hexagon.h" -#include "MSP430.h" #include "PS4CPU.h" #include "clang/Basic/CLWarnings.h" #include "clang/Basic/CharInfo.h" @@ -291,87 +289,12 @@ static void ParseMPreferVectorWidth(const Driver &D, const ArgList &Args, } } -static void getWebAssemblyTargetFeatures(const ArgList &Args, - std::vector &Features) { - handleTargetFeaturesGroup(Args, Features, options::OPT_m_wasm_Features_Group); -} - static void getTargetFeatures(const Driver &D, const llvm::Triple &Triple, const ArgList &Args, ArgStringList &CmdArgs, bool ForAS, bool IsAux = false) { std::vector Features; - switch (Triple.getArch()) { - default: - break; - case llvm::Triple::mips: - case llvm::Triple::mipsel: - case llvm::Triple::mips64: - case llvm::Triple::mips64el: - mips::getMIPSTargetFeatures(D, Triple, Args, Features); - break; - case llvm::Triple::arm: - case llvm::Triple::armeb: - case llvm::Triple::thumb: - case llvm::Triple::thumbeb: - arm::getARMTargetFeatures(D, Triple, Args, Features, ForAS); - break; - - case llvm::Triple::ppc: - case llvm::Triple::ppcle: - case llvm::Triple::ppc64: - case llvm::Triple::ppc64le: - ppc::getPPCTargetFeatures(D, Triple, Args, Features); - break; - case llvm::Triple::riscv32: - case llvm::Triple::riscv64: - riscv::getRISCVTargetFeatures(D, Triple, Args, Features); - break; - case llvm::Triple::systemz: - systemz::getSystemZTargetFeatures(D, Args, Features); - break; - case llvm::Triple::aarch64: - case llvm::Triple::aarch64_32: - case llvm::Triple::aarch64_be: - aarch64::getAArch64TargetFeatures(D, Triple, Args, Features, ForAS); - break; - case llvm::Triple::x86: - case llvm::Triple::x86_64: - x86::getX86TargetFeatures(D, Triple, Args, Features); - break; - case llvm::Triple::hexagon: - hexagon::getHexagonTargetFeatures(D, Args, Features); - break; - case llvm::Triple::wasm32: - case llvm::Triple::wasm64: - getWebAssemblyTargetFeatures(Args, Features); - break; - case llvm::Triple::sparc: - case llvm::Triple::sparcel: - case llvm::Triple::sparcv9: - sparc::getSparcTargetFeatures(D, Args, Features); - break; - case llvm::Triple::r600: - case llvm::Triple::amdgcn: - amdgpu::getAMDGPUTargetFeatures(D, Triple, Args, Features); - break; - case llvm::Triple::nvptx: - case llvm::Triple::nvptx64: - NVPTX::getNVPTXTargetFeatures(D, Triple, Args, Features); - break; - case llvm::Triple::m68k: - m68k::getM68kTargetFeatures(D, Triple, Args, Features); - break; - case llvm::Triple::msp430: - msp430::getMSP430TargetFeatures(D, Args, Features); - break; - case llvm::Triple::ve: - ve::getVETargetFeatures(D, Args, Features); - break; - case llvm::Triple::csky: - csky::getCSKYTargetFeatures(D, Triple, Args, CmdArgs, Features); - break; - } + getTargetFeatureList(D, Triple, Args, CmdArgs, ForAS, Features); for (auto Feature : unifyTargetFeatures(Features)) { CmdArgs.push_back(IsAux ? "-aux-target-feature" : "-target-feature"); diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index 9c974a4df585..697357acec9f 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -59,6 +59,8 @@ class ClassicFlangMacroBuilder : public MacroBuilder { void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { + const Driver &D = getToolChain().getDriver(); + const llvm::Triple &Triple = getToolChain().getEffectiveTriple(); ArgStringList CommonCmdArgs; ArgStringList UpperCmdArgs; ArgStringList LowerCmdArgs; @@ -373,13 +375,13 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, // -Mipa has no effect if (Arg *A = Args.getLastArg(options::OPT_Mipa)) { - getToolChain().getDriver().Diag(diag::warn_drv_clang_unsupported) + D.Diag(diag::warn_drv_clang_unsupported) << A->getAsString(Args); } // -Minline has no effect if (Arg *A = Args.getLastArg(options::OPT_Minline_on)) { - getToolChain().getDriver().Diag(diag::warn_drv_clang_unsupported) + D.Diag(diag::warn_drv_clang_unsupported) << A->getAsString(Args); } @@ -653,14 +655,14 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, // Use clang's predefined macros DiagnosticsEngine DE(new DiagnosticIDs(), new DiagnosticOptions, new IgnoringDiagConsumer()); std::shared_ptr TO = std::make_shared(); - TO->Triple = getToolChain().getEffectiveTriple().getTriple(); + TO->Triple = Triple.getTriple(); std::shared_ptr TI(clang::TargetInfo::CreateTargetInfo(DE, TO)); std::string PredefineBuffer; llvm::raw_string_ostream Predefines(PredefineBuffer); ClassicFlangMacroBuilder Builder(UpperCmdArgs, Args, Predefines); LangOptions LO; - VersionTuple VT = getToolChain().computeMSVCVersion(&getToolChain().getDriver(), Args); + VersionTuple VT = getToolChain().computeMSVCVersion(&D, Args); if (!VT.empty()) { // Set the MSCompatibility version. Subminor version has 5 decimal digits. // Minor and major versions have 2 decimal digits each. @@ -690,7 +692,7 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, DefineTypeSize("__LONG_MAX__", TargetInfo::SignedLong, *TI, Builder); // Add additional predefined macros - switch (getToolChain().getEffectiveTriple().getArch()) { + switch (Triple.getArch()) { case llvm::Triple::aarch64: UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__ARM_ARCH__=8"); break; @@ -784,7 +786,7 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, Arg->claim(); UpperCmdArgs.push_back("-extend"); } else { - getToolChain().getDriver().Diag(diag::err_drv_unsupported_fixed_line_length) + D.Diag(diag::err_drv_unsupported_fixed_line_length) << Arg->getAsString(Args); } } @@ -828,7 +830,7 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, } else if (Value == "95") { // Enable Fortran 2003 semantics UpperCmdArgs.push_back("-y"); // Unset XBIT } else { - getToolChain().getDriver().Diag(diag::err_drv_invalid_allocatable_mode) + D.Diag(diag::err_drv_invalid_allocatable_mode) << A->getAsString(Args); } } else { // No argument passed @@ -978,6 +980,22 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, // Remove "noinline" attriblute LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("183"); LowerCmdArgs.push_back("0x10"); + // Add target features + std::vector Features; + std::string FeatureList = ""; + getTargetFeatureList(D, Triple, Args, UpperCmdArgs, false, Features); + if (!Features.empty()) { + for (unsigned I = 0, N = Features.size(); I < N; ++I) { + StringRef Name = Features[I]; + FeatureList += Name.str(); + if (I < (N - 1)) + FeatureList += ','; + } + + LowerCmdArgs.push_back("-target_features"); + LowerCmdArgs.push_back(Args.MakeArgString(FeatureList)); + } + // Set a -x flag for second part of Fortran frontend for (Arg *A : Args.filtered(options::OPT_Mx_EQ)) { A->claim(); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 3c15cc014415..723a4f7ca95d 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -9,15 +9,19 @@ #include "CommonArgs.h" #include "Arch/AArch64.h" #include "Arch/ARM.h" +#include "Arch/CSKY.h" #include "Arch/M68k.h" #include "Arch/Mips.h" #include "Arch/PPC.h" +#include "Arch/RISCV.h" #include "Arch/Sparc.h" #include "Arch/SystemZ.h" #include "Arch/VE.h" #include "Arch/X86.h" -#include "HIPAMD.h" +#include "AMDGPU.h" #include "Hexagon.h" +#include "HIPAMD.h" +#include "MSP430.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/ObjCRuntime.h" @@ -230,6 +234,90 @@ void tools::addDirectoryList(const ArgList &Args, ArgStringList &CmdArgs, } } +static void getWebAssemblyTargetFeatures(const ArgList &Args, + std::vector &Features) { + handleTargetFeaturesGroup(Args, Features, options::OPT_m_wasm_Features_Group); +} + +void tools::getTargetFeatureList(const Driver &D, + const llvm::Triple &Triple, + const ArgList &Args, ArgStringList &CmdArgs, + bool ForAS, + std::vector &Features) { + switch (Triple.getArch()) { + default: + break; + case llvm::Triple::mips: + case llvm::Triple::mipsel: + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + mips::getMIPSTargetFeatures(D, Triple, Args, Features); + break; + + case llvm::Triple::arm: + case llvm::Triple::armeb: + case llvm::Triple::thumb: + case llvm::Triple::thumbeb: + arm::getARMTargetFeatures(D, Triple, Args, Features, ForAS); + break; + + case llvm::Triple::ppc: + case llvm::Triple::ppcle: + case llvm::Triple::ppc64: + case llvm::Triple::ppc64le: + ppc::getPPCTargetFeatures(D, Triple, Args, Features); + break; + case llvm::Triple::riscv32: + case llvm::Triple::riscv64: + riscv::getRISCVTargetFeatures(D, Triple, Args, Features); + break; + case llvm::Triple::systemz: + systemz::getSystemZTargetFeatures(D, Args, Features); + break; + case llvm::Triple::aarch64: + case llvm::Triple::aarch64_32: + case llvm::Triple::aarch64_be: + aarch64::getAArch64TargetFeatures(D, Triple, Args, Features, ForAS); + break; + case llvm::Triple::x86: + case llvm::Triple::x86_64: + x86::getX86TargetFeatures(D, Triple, Args, Features); + break; + case llvm::Triple::hexagon: + hexagon::getHexagonTargetFeatures(D, Args, Features); + break; + case llvm::Triple::wasm32: + case llvm::Triple::wasm64: + getWebAssemblyTargetFeatures(Args, Features); + break; + case llvm::Triple::sparc: + case llvm::Triple::sparcel: + case llvm::Triple::sparcv9: + sparc::getSparcTargetFeatures(D, Args, Features); + break; + case llvm::Triple::r600: + case llvm::Triple::amdgcn: + amdgpu::getAMDGPUTargetFeatures(D, Triple, Args, Features); + break; + case llvm::Triple::nvptx: + case llvm::Triple::nvptx64: + NVPTX::getNVPTXTargetFeatures(D, Triple, Args, Features); + break; + case llvm::Triple::m68k: + m68k::getM68kTargetFeatures(D, Triple, Args, Features); + break; + case llvm::Triple::msp430: + msp430::getMSP430TargetFeatures(D, Args, Features); + break; + case llvm::Triple::ve: + ve::getVETargetFeatures(D, Args, Features); + break; + case llvm::Triple::csky: + csky::getCSKYTargetFeatures(D, Triple, Args, CmdArgs, Features); + break; + } +} + void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, const ArgList &Args, ArgStringList &CmdArgs, const JobAction &JA) { diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index d012f4ff8112..436d3f8f5a87 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -14,6 +14,7 @@ #include "clang/Driver/Multilib.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" +#include "llvm/Option/ArgList.h" #include "llvm/Support/CodeGen.h" namespace clang { @@ -27,6 +28,12 @@ bool needFortranLibs(const Driver &D, const llvm::opt::ArgList &Args); void addPathIfExists(const Driver &D, const Twine &Path, ToolChain::path_list &Paths); +void getTargetFeatureList(const Driver &D, + const llvm::Triple &Triple, + const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs, + bool ForAS, std::vector &Features); + void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const JobAction &JA); diff --git a/clang/test/Driver/emit-flang-attrs.f90 b/clang/test/Driver/emit-flang-attrs.f90 new file mode 100644 index 000000000000..91331ac227fa --- /dev/null +++ b/clang/test/Driver/emit-flang-attrs.f90 @@ -0,0 +1,11 @@ +// REQUIRES: aarch64-registered-target +// REQUIRES: classic_flang +// RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a -c %s 2>&1 | FileCheck --check-prefix=CHECK-ATTRS-NEON %s +// RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve -c %s 2>&1 | FileCheck --check-prefix=CHECK-ATTRS-SVE %s +// RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+nosve -c %s 2>&1 | FileCheck --check-prefix=CHECK-ATTRS-NOSVE %s +// CHECK-ATTRS-NEON: "{{.*}}flang2" +// CHECK-ATTRS-NEON-SAME: "-target_features" "+neon,+v8a +// CHECK-ATTRS-SVE: "{{.*}}flang2" +// CHECK-ATTRS-SVE-SAME: "-target_features" "+neon,+v8a,+sve +// CHECK-ATTRS-NOSVE: "{{.*}}flang2" +// CHECK-ATTRS-NOSVE-SAME: "-target_features" "+neon,+v8a,-sve -- Gitee From b9ff830dc0b880047580244b3f40a82cd89c707a Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Thu, 18 Nov 2021 11:16:20 +0000 Subject: [PATCH 16/32] [flang-driver] Uniquify the target_features string Use existing clang support for uniquifying target feature lists to pass a unique list through to flang. --- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 7 +++---- clang/test/Driver/emit-flang-attrs.f90 | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index 697357acec9f..03989f75b0c9 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -985,11 +985,10 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, std::string FeatureList = ""; getTargetFeatureList(D, Triple, Args, UpperCmdArgs, false, Features); if (!Features.empty()) { - for (unsigned I = 0, N = Features.size(); I < N; ++I) { - StringRef Name = Features[I]; - FeatureList += Name.str(); - if (I < (N - 1)) + for (auto Feature : unifyTargetFeatures(Features)) { + if (!FeatureList.empty()) FeatureList += ','; + FeatureList += Feature; } LowerCmdArgs.push_back("-target_features"); diff --git a/clang/test/Driver/emit-flang-attrs.f90 b/clang/test/Driver/emit-flang-attrs.f90 index 91331ac227fa..d9a2ea954f80 100644 --- a/clang/test/Driver/emit-flang-attrs.f90 +++ b/clang/test/Driver/emit-flang-attrs.f90 @@ -3,6 +3,7 @@ // RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a -c %s 2>&1 | FileCheck --check-prefix=CHECK-ATTRS-NEON %s // RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve -c %s 2>&1 | FileCheck --check-prefix=CHECK-ATTRS-SVE %s // RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+nosve -c %s 2>&1 | FileCheck --check-prefix=CHECK-ATTRS-NOSVE %s +// RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve+nosve -c %s 2>&1 | FileCheck --check-prefix=CHECK-ATTRS-NOSVE %s // CHECK-ATTRS-NEON: "{{.*}}flang2" // CHECK-ATTRS-NEON-SAME: "-target_features" "+neon,+v8a // CHECK-ATTRS-SVE: "{{.*}}flang2" -- Gitee From b5984b0ed0f81043a0ae5e7d50cff34e57a271eb Mon Sep 17 00:00:00 2001 From: Paul Osmialowski Date: Fri, 21 Jan 2022 10:00:58 +0000 Subject: [PATCH 17/32] [driver] Pass msve-vector-bits to flang as vscale range Signed-off-by: Paul Osmialowski --- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 34 ++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index 03989f75b0c9..80ed2d5d4383 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -995,6 +995,40 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, LowerCmdArgs.push_back(Args.MakeArgString(FeatureList)); } + // Add vscale range + unsigned vscaleMin = 1U; + unsigned vscaleMax = 16U; + bool hasVscaleRange = false; + if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) { + StringRef Val = A->getValue(); + + if (Val.equals("scalable")) + hasVscaleRange = true; + else { + unsigned bits = (std::stoul(Val.str()) >> 7U); + + if ((bits < vscaleMin) || (bits > vscaleMax)) { + D.Diag(diag::warn_drv_clang_unsupported) << A->getAsString(Args); + hasVscaleRange = false; + } else { + vscaleMin = vscaleMax = bits; + hasVscaleRange = true; + } + } + } + for (auto Feature : unifyTargetFeatures(Features)) { + if (Feature.startswith("+sve")) { + hasVscaleRange = true; + break; + } + } + if (hasVscaleRange) { + LowerCmdArgs.push_back("-vscale_range_min"); + LowerCmdArgs.push_back(Args.MakeArgString(std::to_string(vscaleMin))); + LowerCmdArgs.push_back("-vscale_range_max"); + LowerCmdArgs.push_back(Args.MakeArgString(std::to_string(vscaleMax))); + } + // Set a -x flag for second part of Fortran frontend for (Arg *A : Args.filtered(options::OPT_Mx_EQ)) { A->claim(); -- Gitee From a19b215da13f2b08bc32fad91ca9cda6c0232d0f Mon Sep 17 00:00:00 2001 From: pwisniewskimobica Date: Thu, 13 Jan 2022 10:11:43 +0100 Subject: [PATCH 18/32] [Driver][Test] Add more variants to test/Driver/emit-flang-attrs.f90 --- clang/test/Driver/emit-flang-attrs.f90 | 70 +++++++++++++++++++++----- 1 file changed, 58 insertions(+), 12 deletions(-) diff --git a/clang/test/Driver/emit-flang-attrs.f90 b/clang/test/Driver/emit-flang-attrs.f90 index d9a2ea954f80..df23a8aa6e87 100644 --- a/clang/test/Driver/emit-flang-attrs.f90 +++ b/clang/test/Driver/emit-flang-attrs.f90 @@ -1,12 +1,58 @@ -// REQUIRES: aarch64-registered-target -// REQUIRES: classic_flang -// RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a -c %s 2>&1 | FileCheck --check-prefix=CHECK-ATTRS-NEON %s -// RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve -c %s 2>&1 | FileCheck --check-prefix=CHECK-ATTRS-SVE %s -// RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+nosve -c %s 2>&1 | FileCheck --check-prefix=CHECK-ATTRS-NOSVE %s -// RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve+nosve -c %s 2>&1 | FileCheck --check-prefix=CHECK-ATTRS-NOSVE %s -// CHECK-ATTRS-NEON: "{{.*}}flang2" -// CHECK-ATTRS-NEON-SAME: "-target_features" "+neon,+v8a -// CHECK-ATTRS-SVE: "{{.*}}flang2" -// CHECK-ATTRS-SVE-SAME: "-target_features" "+neon,+v8a,+sve -// CHECK-ATTRS-NOSVE: "{{.*}}flang2" -// CHECK-ATTRS-NOSVE-SAME: "-target_features" "+neon,+v8a,-sve +! REQUIRES: aarch64-registered-target +! REQUIRES: classic_flang +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a -c %s 2>&1 | FileCheck --check-prefix=CHECK-ATTRS-NEON %s +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve -c %s 2>&1 | FileCheck --check-prefix=CHECK-ATTRS-SVE %s +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+nosve -c %s 2>&1 | FileCheck --check-prefix=CHECK-ATTRS-NOSVE %s +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve+nosve -c %s 2>&1 | FileCheck --check-prefix=CHECK-ATTRS-NOSVE %s +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2+nosve2 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-REVERT +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-aes -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-AES +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-sm4 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-SM4 +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-sha3 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-SHA3 +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-bitperm+nosve2-bitperm -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-BITPERM-REVERT +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-IMPLY +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+nosve+sve2 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-CONFLICT-REV +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve+sve2 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE-SVE2 +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-bitperm -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-BITPERM +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+nosve+sve2-aes -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE-SUBFEATURE-CONFLICT-REV +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-sm4+nosve2 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-SUBFEATURE-CONFLICT +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-bitperm+nosve2-aes -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-SUBFEATURE-MIX +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-sm4+nosve2-sm4 -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-SM4-REVERT +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-sha3+nosve2-sha3 %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-SHA3-REVERT +! RUN: %flang -### -target aarch64-linux-gnu -march=armv8-a+sve2-aes+nosve2-aes %s 2>&1 | FileCheck %s --check-prefix=CHECK-SVE2-AES-REVERT + +! CHECK-ATTRS-NEON: "{{.*}}flang2" +! CHECK-ATTRS-NEON-SAME: "-target_features" "+neon,+v8a" +! CHECK-ATTRS-SVE: "{{.*}}flang2" +! CHECK-ATTRS-SVE-SAME: "-target_features" "+neon,+v8a,+sve" +! CHECK-ATTRS-NOSVE: "{{.*}}flang2" +! CHECK-ATTRS-NOSVE-SAME: "-target_features" "+neon,+v8a,-sve,-sve2,-sve2-bitperm,-sve2-sha3,-sve2-aes,-sve2-sm4" +! CHECK-SVE2-REVERT: "{{.*}}flang2" +! CHECK-SVE2-REVERT-SAME: "-target_features" "+neon,+v8a,+sve,-sve2,-sve2-bitperm,-sve2-sha3,-sve2-aes,-sve2-sm4" +! CHECK-SVE2-AES: "{{.*}}flang2" +! CHECK-SVE2-AES-SAME: "-target_features" "+neon,+v8a,+sve2-aes,+sve,+sve2" +! CHECK-SVE2-SM4: "{{.*}}flang2" +! CHECK-SVE2-SM4-SAME: "-target_features" "+neon,+v8a,+sve2-sm4,+sve,+sve2" +! CHECK-SVE2-SHA3: "{{.*}}flang2" +! CHECK-SVE2-SHA3-SAME: "-target_features" "+neon,+v8a,+sve2-sha3,+sve,+sve2" +! CHECK-SVE2-BITPERM-REVERT: "{{.*}}flang2" +! CHECK-SVE2-BITPERM-REVERT-SAME: "-target_features" "+neon,+v8a,+sve,+sve2,-sve2-bitperm" +! CHECK-SVE2-IMPLY: "{{.*}}flang2" +! CHECK-SVE2-IMPLY-SAME: "-target_features" "+neon,+v8a,+sve2,+sve" +! CHECK-SVE2-CONFLICT-REV: "{{.*}}flang2" +! CHECK-SVE2-CONFLICT-REV-SAME: "-target_features" "+neon,+v8a,-sve2-bitperm,-sve2-sha3,-sve2-aes,-sve2-sm4,+sve2,+sve" +! CHECK-SVE-SVE2: "{{.*}}flang2" +! CHECK-SVE-SVE2-SAME: "-target_features" "+neon,+v8a,+sve2,+sve" +! CHECK-SVE2-BITPERM: "{{.*}}flang2" +! CHECK-SVE2-BITPERM-SAME: "-target_features" "+neon,+v8a,+sve2-bitperm,+sve,+sve2" +! CHECK-SVE-SUBFEATURE-CONFLICT-REV: "{{.*}}flang2" +! CHECK-SVE-SUBFEATURE-CONFLICT-REV-SAME: "-target_features" "+neon,+v8a,-sve2-bitperm,-sve2-sha3,-sve2-sm4,+sve2-aes,+sve,+sve2" +! CHECK-SVE2-SUBFEATURE-CONFLICT: "{{.*}}flang2" +! CHECK-SVE2-SUBFEATURE-CONFLICT-SAME: "-target_features" "+neon,+v8a,+sve,-sve2,-sve2-bitperm,-sve2-sha3,-sve2-aes,-sve2-sm4" +! CHECK-SVE2-SUBFEATURE-MIX: "{{.*}}flang2" +! CHECK-SVE2-SUBFEATURE-MIX-SAME: "-target_features" "+neon,+v8a,+sve2-bitperm,+sve,+sve2,-sve2-aes" +! CHECK-SVE2-SM4-REVERT: "{{.*}}flang2" +! CHECK-SVE2-SM4-REVERT-SAME: "-target_features" "+neon,+v8a,+sve,+sve2,-sve2-sm4" +! CHECK-SVE2-SHA3-REVERT: "{{.*}}flang2" +! CHECK-SVE2-SHA3-REVERT-SAME: "-target_features" "+neon,+v8a,+sve,+sve2,-sve2-sha3" +! CHECK-SVE2-AES-REVERT: "{{.*}}flang2" +! CHECK-SVE2-AES-REVERT-SAME: "-target_features" "+neon,+v8a,+sve,+sve2,-sve2-aes" -- Gitee From 7cecac307ad362cb6c0d8f44c3f13725b51ee5ca Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Tue, 22 Mar 2022 09:26:00 +0000 Subject: [PATCH 19/32] Fix classic flang version screen Version screen has been erroneously reporting as flang-new since LLVM 12 --- clang/lib/Driver/Driver.cpp | 4 ++++ clang/test/Driver/flang/classic-flang-version.f | 3 +++ 2 files changed, 7 insertions(+) create mode 100644 clang/test/Driver/flang/classic-flang-version.f diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 386919d1c436..925be5216af3 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1820,7 +1820,11 @@ void Driver::PrintHelp(bool ShowHidden) const { void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const { if (IsFlangMode()) { +#ifdef ENABLE_CLASSIC_FLANG + OS << getClangToolFullVersion("flang") << '\n'; +#else OS << getClangToolFullVersion("flang-new") << '\n'; +#endif } else { // FIXME: The following handlers should use a callback mechanism, we don't // know what the client would like to do. diff --git a/clang/test/Driver/flang/classic-flang-version.f b/clang/test/Driver/flang/classic-flang-version.f new file mode 100644 index 000000000000..c2082d3af8b7 --- /dev/null +++ b/clang/test/Driver/flang/classic-flang-version.f @@ -0,0 +1,3 @@ +! REQUIRES: classic-flang +! RUN: %flang --version | FileCheck %s +! CHECK: flang version {{.*}} ({{.*}}flang-compiler/classic-flang-llvm-project.git {{.*}}) -- Gitee From 6371c8a131270eb19f8c56a833dfe5af1bf7e1f1 Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Fri, 18 Mar 2022 16:47:15 +0000 Subject: [PATCH 20/32] Canonicalize some ENABLE_CLASSIC_FLANG These CMake variables are used to set python variables in the lit config. As such, they need to bet set with a valid CMake boolean value that is also a valid python boolean value (1, True, etc.) and not one that is not (ON, NO, etc.) to work. This is fragile. Call the LLVM cmake helper function on these two downstream CMake --- clang/test/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt index 5b604b2a3eeb..3f48aba1d6f4 100644 --- a/clang/test/CMakeLists.txt +++ b/clang/test/CMakeLists.txt @@ -10,6 +10,7 @@ llvm_canonicalize_cmake_booleans( CLANG_PLUGIN_SUPPORT CLANG_SPAWN_CC1 ENABLE_BACKTRACES + LLVM_ENABLE_CLASSIC_FLANG LLVM_ENABLE_ZLIB LLVM_ENABLE_PER_TARGET_RUNTIME_DIR LLVM_ENABLE_THREADS -- Gitee From 7e93773f9948838b25e38af71231aaf0c79ed8fe Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Fri, 18 Mar 2022 16:44:23 +0000 Subject: [PATCH 21/32] [NFC] Add missing ENABLE_CLASSIC_FLANG guard. Signed-off-by: Richard Barton --- clang/lib/Driver/Driver.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 925be5216af3..f71e7894be96 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -5086,9 +5086,11 @@ class ToolSelector final { if (!T->hasIntegratedBackend() && !(OutputIsLLVM && T->canEmitIR())) return nullptr; +#ifdef ENABLE_CLASSIC_FLANG // Classic Flang is not integrated with the backend. if (C.getDriver().IsFlangMode() && !T->hasIntegratedAssembler()) return nullptr; +#endif if (T->canEmitIR() && ((SaveTemps && !InputIsBitcode) || EmbedBitcode)) return nullptr; -- Gitee From d4816e5612e4fe6ccde17f2cca9e4f46a1fcb0ee Mon Sep 17 00:00:00 2001 From: Richard Barton Date: Tue, 3 May 2022 17:38:49 +0100 Subject: [PATCH 22/32] Fix flang driver preprocessor issue Fix a bug where flang -E -save-temps input.F90 would preprocess the input file twice. Add a new test for preprocessor behaviour that would expose the bug and updated fortran-phases test for new behaviour. Also added -emit-flang-llvm to that test for completeness. Signed-off-by: Richard Barton --- clang/lib/Driver/Driver.cpp | 23 +++--- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 4 +- clang/test/Driver/fortran-phases.f90 | 73 ++++++++++++-------- clang/test/Driver/fortran-preprocessor.f90 | 47 +++++++++++++ 4 files changed, 109 insertions(+), 38 deletions(-) create mode 100644 clang/test/Driver/fortran-preprocessor.f90 diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index f71e7894be96..5e239fd8fdec 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -337,14 +337,7 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) || (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P)) || CCGenDiagnostics) { -#ifdef ENABLE_CLASSIC_FLANG - if (IsFlangMode()) - FinalPhase = phases::Compile; - else - FinalPhase = phases::Preprocess; -#else FinalPhase = phases::Preprocess; -#endif // --precompile only runs up to precompilation. // Options that cause the output of C++20 compiled module interfaces or @@ -2497,7 +2490,11 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, if (memcmp(Value, "-", 2) == 0) { if (IsFlangMode()) { #ifdef ENABLE_CLASSIC_FLANG - Ty = types::TY_C; + // If running with -E, treat as needing preprocessing + if (!Args.hasArgNoClaim(options::OPT_E)) + Ty = types::TY_PP_F_FreeForm; + else + Ty = types::TY_F_FreeForm; #else Ty = types::TY_Fortran; #endif @@ -2522,6 +2519,16 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, // idea of what .s is. if (const char *Ext = strrchr(Value, '.')) Ty = TC.LookupTypeForExtension(Ext + 1); +#ifdef ENABLE_CLASSIC_FLANG + // If called with -E, treat the inputs as needing preprocessing + // regardless of extension + if (IsFlangMode() && Args.hasArgNoClaim(options::OPT_E)) { + if (Ty == types::TY_PP_F_FreeForm) + Ty = types::TY_F_FreeForm; + else if (Ty == types::TY_PP_F_FixedForm) + Ty = types::TY_F_FixedForm; + } +#endif if (Ty == types::TY_INVALID) { if (IsCLMode() && (Args.hasArgNoClaim(options::OPT_E) || CCGenDiagnostics)) diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index 80ed2d5d4383..2fe317a3d003 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -79,8 +79,8 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, // Check file type sanity assert(types::isAcceptedByFlang(InputType) && "Can only accept Fortran"); - if (Args.hasArg(options::OPT_fsyntax_only)) { - // For -fsyntax-only produce temp files only + if (Args.hasArg(options::OPT_fsyntax_only, options::OPT_E)) { + // For -fsyntax-only and -E produce temp files only Stem = C.getDriver().GetTemporaryPath("", ""); } else { OutFile = Output.getFilename(); diff --git a/clang/test/Driver/fortran-phases.f90 b/clang/test/Driver/fortran-phases.f90 index 5a79bb26bcde..57d5f2c92b78 100644 --- a/clang/test/Driver/fortran-phases.f90 +++ b/clang/test/Driver/fortran-phases.f90 @@ -7,6 +7,7 @@ ! RUN: %flang -ccc-print-phases -S 2>&1 %s | FileCheck %s --check-prefix=AONLY-NOPP ! RUN: %flang -ccc-print-phases -c -emit-llvm 2>&1 %s | FileCheck %s --check-prefix=LLONLY-NOPP ! RUN: %flang -ccc-print-phases -S -emit-llvm 2>&1 %s | FileCheck %s --check-prefix=LLONLY-NOPP +! RUN: %flang -ccc-print-phases -emit-flang-llvm 2>&1 %s | FileCheck %s --check-prefix=FLLONLY-NOPP ! RUN: %flang -ccc-print-phases -fsyntax-only 2>&1 %s | FileCheck %s --check-prefix=SONLY-NOPP ! RUN: %flang -ccc-print-phases -E 2>&1 %s | FileCheck %s --check-prefix=PPONLY-NOPP @@ -16,6 +17,7 @@ ! RUN: %flang -ccc-print-phases -S 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=AONLY ! RUN: %flang -ccc-print-phases -c -emit-llvm 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=LLONLY ! RUN: %flang -ccc-print-phases -S -emit-llvm 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=LLONLY +! RUN: %flang -ccc-print-phases -emit-flang-llvm 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=FLLONLY ! RUN: %flang -ccc-print-phases -fsyntax-only 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=SONLY ! RUN: %flang -ccc-print-phases -E 2>&1 -x f95-cpp-input %s | FileCheck %s --check-prefix=PPONLY @@ -29,31 +31,39 @@ ! CONLY-NOPP: 1: compiler, {0}, ir ! CONLY-NOPP: 2: backend, {1}, assembler ! CONLY-NOPP: 3: assembler, {2}, object -! CONLY-NOPP-NOT: 4: linker, {3}, image +! CONLY-NOPP-NOT: {{.*}}: linker, {{{.*}}}, image ! AONLY-NOPP: 0: input, {{.*}}, f95 ! AONLY-NOPP: 1: compiler, {0}, ir ! AONLY-NOPP: 2: backend, {1}, assembler -! AONLY-NOPP-NOT: 3: assembler, {2}, object -! AONLY-NOPP-NOT: 4: linker, {3}, image +! AONLY-NOPP-NOT: {{.*}}: assembler, {{{.*}}}, object +! AONLY-NOPP-NOT: {{.*}}: linker, {{{.*}}}, image ! LLONLY-NOPP: 0: input, {{.*}}, f95 ! LLONLY-NOPP: 1: compiler, {0}, ir -! LLONLY-NOPP-NOT: 2: backend, {1}, assembler -! LLONLY-NOPP-NOT: 3: assembler, {2}, object -! LLONLY-NOPP-NOT: 4: linker, {3}, image +! LLONLY-NOPP-NOT: {{.*}}: backend, {{{.*}}}, assembler +! LLONLY-NOPP-NOT: {{.*}}: assembler, {{{.*}}}, object +! LLONLY-NOPP-NOT: {{.*}}: linker, {{{.*}}}, image + +! FLLONLY-NOPP: 0: input, {{.*}}, f95 +! FLLONLY-NOPP: 1: compiler, {0}, ir +! FLLONLY-NOPP-NOT: {{.*}}: backend, {{{.*}}}, assembler +! FLLONLY-NOPP-NOT: {{.*}}: assembler, {{{.*}}}, object +! FLLONLY-NOPP-NOT: {{.*}}: linker, {{{.*}}}, image ! SONLY-NOPP: 0: input, {{.*}}, f95 -! SONLY-NOPP-NOT: 1: compiler, {0}, ir -! SONLY-NOPP-NOT: 2: backend, {1}, assembler -! SONLY-NOPP-NOT: 3: assembler, {2}, object -! SONLY-NOPP-NOT: 4: linker, {3}, image +! SONLY-NOPP-NOT: {{.*}}: compiler, {{{.*}}}, ir +! SONLY-NOPP-NOT: {{.*}}: backend, {{{.*}}}, assembler +! SONLY-NOPP-NOT: {{.*}}: assembler, {{{.*}}}, object +! SONLY-NOPP-NOT: {{.*}}: linker, {{{.*}}}, image +! flang always preprocesses with -E regardless of file extension ! PPONLY-NOPP: 0: input, {{.*}}, f95 -! PPONLY-NOPP: 1: compiler, {0}, ir -! PPONLY-NOPP-NOT: 2: backend, {1}, assembler -! PPONLY-NOPP-NOT: 3: assembler, {2}, object -! PPONLY-NOPP-NOT: 4: linker, {3}, image +! PPONLY-NOPP: 1: preprocessor, {0}, f95 +! PPONLY-NOPP-NOT: {{.*}}: compiler, {{{.*}}}, ir +! PPONLY-NOPP-NOT: {{.*}}: backend, {{{.*}}}, assembler +! PPONLY-NOPP-NOT: {{.*}}: assembler, {{{.*}}}, object +! PPONLY-NOPP-NOT: {{.*}}: linker, {{{.*}}}, image ! LINK: 0: input, {{.*}}, f95-cpp-input ! LINK: 1: preprocessor, {0}, f95 @@ -67,35 +77,42 @@ ! CONLY: 2: compiler, {1}, ir ! CONLY: 3: backend, {2}, assembler ! CONLY: 4: assembler, {3}, object -! CONLY-NOT: 5: linker, {4}, image +! CONLY-NOT: {{.*}}: linker, {{{.*}}}, image ! AONLY: 0: input, {{.*}}, f95-cpp-input ! AONLY: 1: preprocessor, {0}, f95 ! AONLY: 2: compiler, {1}, ir ! AONLY: 3: backend, {2}, assembler -! AONLY-NOT: 4: assembler, {3}, object -! AONLY-NOT: 5: linker, {4}, image +! AONLY-NOT: {{.*}}: assembler, {{{.*}}}, object +! AONLY-NOT: {{.*}}: linker, {{{.*}}}, image ! LLONLY: 0: input, {{.*}}, f95-cpp-input ! LLONLY: 1: preprocessor, {0}, f95 ! LLONLY: 2: compiler, {1}, ir -! LLONLY-NOT: 3: backend, {2}, assembler -! LLONLY-NOT: 4: assembler, {3}, object -! LLONLY-NOT: 5: linker, {4}, image +! LLONLY-NOT: {{.*}}: backend, {{{.*}}}, assembler +! LLONLY-NOT: {{.*}}: assembler, {{{.*}}}, object +! LLONLY-NOT: {{.*}}: linker, {{{.*}}}, image + +! FLLONLY: 0: input, {{.*}}, f95-cpp-input +! FLLONLY: 1: preprocessor, {0}, f95 +! FLLONLY: 2: compiler, {1}, ir +! FLLONLY-NOT: {{.*}}: backend, {{{.*}}}, assembler +! FLLONLY-NOT: {{.*}}: assembler, {{{.*}}}, object +! FLLONLY-NOT: {{.*}}: linker, {{{.*}}}, image ! SONLY: 0: input, {{.*}}, f95-cpp-input ! SONLY: 1: preprocessor, {0}, f95 -! SONLY-NOT: 2: compiler, {1}, ir -! SONLY-NOT: 3: backend, {2}, assembler -! SONLY-NOT: 4: assembler, {3}, object -! SONLY-NOT: 5: linker, {4}, image +! SONLY-NOT: {{.*}}: compiler, {{{.*}}}, ir +! SONLY-NOT: {{.*}}: backend, {{{.*}}}, assembler +! SONLY-NOT: {{.*}}: assembler, {{{.*}}}, object +! SONLY-NOT: {{.*}}: linker, {{{.*}}}, image ! PPONLY: 0: input, {{.*}}, f95-cpp-input ! PPONLY: 1: preprocessor, {0}, f95 -! PPONLY: 2: compiler, {1}, ir -! PPONLY-NOT: 3: backend, {2}, assembler -! PPONLY-NOT: 4: assembler, {3}, object -! PPONLY-NOT: 5: linker, {4}, image +! PPONLY-NOT: {{.*}}: compiler, {{{.*}}}, ir +! PPONLY-NOT: {{.*}}: backend, {{{.*}}}, assembler +! PPONLY-NOT: {{.*}}: assembler, {{{.*}}}, object +! PPONLY-NOT: {{.*}}: linker, {{{.*}}}, image program hello write(*, *) "Hello" diff --git a/clang/test/Driver/fortran-preprocessor.f90 b/clang/test/Driver/fortran-preprocessor.f90 new file mode 100644 index 000000000000..99f4186ba83c --- /dev/null +++ b/clang/test/Driver/fortran-preprocessor.f90 @@ -0,0 +1,47 @@ +! REQUIRES: classic_flang + +! -cpp should preprocess as it goes, regardless of input file extension +! RUN: %flang -cpp -c -DHELLO="hello all" -### %s 2>&1 | FileCheck %s --check-prefixes=ALL,CPP,PP +! RUN: %flang -cpp -c -DHELLO="hello all" -### -c f95-cpp-input %s 2>&1 | FileCheck %s --check-prefixes=ALL,CPP,PP +! -E should preprocess then stop, regardless of input file extension +! RUN: %flang -E -DHELLO="hello all" -### %s 2>&1 | FileCheck %s --check-prefixes=ALL,E,PPONLY +! RUN: %flang -E -DHELLO="hello all" -### -x f95-cpp-input %s 2>&1 | FileCheck %s --check-prefixes=ALL,E,PPONLY +! -cpp and -E are redundant +! RUN: %flang -E -cpp -DHELLO="hello all" -### %s 2>&1 | FileCheck %s --check-prefixes=ALL,E,PPONLY + +! Don't link when given linker input +! RUN: %flang -E -cpp -Wl,-rpath=blah -### %s 2>&1 | FileCheck %s --check-prefixes=ALL,E,PPONLY + +! Explicitly test this nonsence case causing a bug with LLVM 13/14 +! RUN: %flang -E -traditional-cpp -DHELLO="hello all" -x f95-cpp-input -### %s 2>&1 | FileCheck %s --check-prefixes=ALL,E,PPONLY + +! Test -save-temps does not break things (same codepath as -traditional-cpp bug above) +! RUN: %flang -E -DHELLO="hello all" -save-temps -### %s 2>&1 | FileCheck %s --check-prefixes=ALL,E,PPONLY +! RUN: %flang -E -DHELLO="hello all" -save-temps -### -c f95-cpp-input %s 2>&1 | FileCheck %s --check-prefixes=ALL,E,PPONLY +! RUN: %flang -cpp -c -DHELLO="hello all" -save-temps -### %s 2>&1 | FileCheck %s --check-prefixes=ALL,CPP +! RUN: %flang -cpp -c -DHELLO="hello all" -save-temps -### -c f95-cpp-input %s 2>&1 | FileCheck %s --check-prefixes=ALL,CPP + +! Test for the correct cmdline flags +! Consume up to flang1 line +! ALL-LABEL: "{{.*}}flang1" +! CPP-NOT: "-es" +! CPP: "-preprocess" +! CPP-NOT: "-es" + +! E-DAG: "-es" +! E-DAG: "-preprocess" + +! flang1 should only be called once! +! ALL-NOT: "{{.*}}flang1" + +! CPP should continue to build object +! PP: "{{.*}}flang2" +! PPONLY-NOT: "{{.*}}flang2" + +! These commands should never call a linker! +! ALL-NOT: "{{.*}}ld" + +program hello + write(*, *) HELLO +end program hello + -- Gitee From 65bb33ece65baa21edceebad6de7cadf52c74075 Mon Sep 17 00:00:00 2001 From: Paul Osmialowski Date: Fri, 15 Jul 2022 09:17:08 +0100 Subject: [PATCH 23/32] classic flang: enable IEEE by default (and sort Lower/Common inconsistency out) Signed-off-by: Paul Osmialowski --- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index 2fe317a3d003..e69c019feff2 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -66,7 +66,7 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, ArgStringList LowerCmdArgs; SmallString<256> Stem; std::string OutFile; - bool NeedIEEE = false; + bool NeedIEEE = true; bool NeedFastMath = false; bool NeedRelaxedMath = false; @@ -555,7 +555,7 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("216"); LowerCmdArgs.push_back("1"); - // Lower: -ieee 0 + // Common: -ieee 0 CommonCmdArgs.push_back("-ieee"); CommonCmdArgs.push_back("0"); } else if (NeedIEEE) { @@ -583,7 +583,7 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, LowerCmdArgs.push_back("-y"); LowerCmdArgs.push_back("216"); LowerCmdArgs.push_back("1"); - // Lower: -ieee 1 + // Common: -ieee 1 CommonCmdArgs.push_back("-ieee"); CommonCmdArgs.push_back("1"); } else if (NeedRelaxedMath) { @@ -595,11 +595,11 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, LowerCmdArgs.push_back("-y"); LowerCmdArgs.push_back("216"); LowerCmdArgs.push_back("1"); - // Lower: -ieee 0 + // Common: -ieee 0 CommonCmdArgs.push_back("-ieee"); CommonCmdArgs.push_back("0"); } else { - // Lower: -ieee 0 + // Common: -ieee 0 CommonCmdArgs.push_back("-ieee"); CommonCmdArgs.push_back("0"); } -- Gitee From 02994dc3679805cc08f873989c826fd425216bc4 Mon Sep 17 00:00:00 2001 From: Kiran Chandramohan Date: Tue, 8 May 2018 17:49:59 +0100 Subject: [PATCH 24/32] Changes to flang's fp-contract behaviour 1) All fma and contraction behvaviour follows from the -ffp-contract= flag setting. 2) At optimization level 0, -ffp-contract=fast flag will not be honoured. 3) At all other levels, -ffp-contract=fast will be the default behaviour and the flag is honoured. --- clang/lib/Driver/ToolChains/ClassicFlang.cpp | 75 +++++++++++++------ .../flang/classic-flang-fp-contract.f95 | 27 +++++++ 2 files changed, 80 insertions(+), 22 deletions(-) create mode 100644 clang/test/Driver/flang/classic-flang-fp-contract.f95 diff --git a/clang/lib/Driver/ToolChains/ClassicFlang.cpp b/clang/lib/Driver/ToolChains/ClassicFlang.cpp index e69c019feff2..e14bda862c99 100644 --- a/clang/lib/Driver/ToolChains/ClassicFlang.cpp +++ b/clang/lib/Driver/ToolChains/ClassicFlang.cpp @@ -464,28 +464,6 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, } } - // Enable FMA - for (Arg *A: Args.filtered(options::OPT_Mfma_on, options::OPT_fma)) { - A->claim(); - LowerCmdArgs.push_back("-x"); - LowerCmdArgs.push_back("172"); - LowerCmdArgs.push_back("0x40000000"); - LowerCmdArgs.push_back("-x"); - LowerCmdArgs.push_back("179"); - LowerCmdArgs.push_back("1"); - } - - // Disable FMA - for (Arg *A: Args.filtered(options::OPT_Mfma_off, options::OPT_nofma)) { - A->claim(); - LowerCmdArgs.push_back("-x"); - LowerCmdArgs.push_back("171"); - LowerCmdArgs.push_back("0x40000000"); - LowerCmdArgs.push_back("-x"); - LowerCmdArgs.push_back("178"); - LowerCmdArgs.push_back("1"); - } - // For -fPIC set -x 62 8 for second part of Fortran frontend for (Arg *A: Args.filtered(options::OPT_fPIC)) { A->claim(); @@ -550,6 +528,59 @@ void ClassicFlang::ConstructJob(Compilation &C, const JobAction &JA, A->claim(); } + // fp-contract=fast is the default + bool EnableFPContraction = true; + if (Arg *A = Args.getLastArg(options::OPT_ffp_contract, + options::OPT_Mfma_on, + options::OPT_fma, + options::OPT_Mfma_off, + options::OPT_nofma)) { + auto Opt = A->getOption(); + if (Opt.matches(options::OPT_ffp_contract)) { + StringRef Val = A->getValue(); + if ((Val == "fast") || (Val == "on")) { + EnableFPContraction = true; + } else if (Val == "off") { + EnableFPContraction = false; + } else { + D.Diag(diag::err_drv_unsupported_option_argument) + << A->getOption().getName() << Val; + } + } else if(Opt.matches(options::OPT_Mfma_on) || + Opt.matches(options::OPT_fma)) { + EnableFPContraction = true; + } else { + EnableFPContraction = false; + } + } + + if(OptLevel == 0) + EnableFPContraction = false; + + // Emit contract math instructions. + // Step 1 : Generate fma instructions in flang (can override with fma flag) + // Step 2 : Propagate fma contract information to LLVM to further + // exploit contraction opportunities + if (EnableFPContraction) { + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("172"); + LowerCmdArgs.push_back("0x40000000"); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("179"); + LowerCmdArgs.push_back("1"); + // Step 2 + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("216"); + LowerCmdArgs.push_back("0x1000"); + } else { + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("171"); + LowerCmdArgs.push_back("0x40000000"); + LowerCmdArgs.push_back("-x"); + LowerCmdArgs.push_back("178"); + LowerCmdArgs.push_back("1"); + } + if (NeedFastMath) { // Lower: -x 216 1 LowerCmdArgs.push_back("-x"); diff --git a/clang/test/Driver/flang/classic-flang-fp-contract.f95 b/clang/test/Driver/flang/classic-flang-fp-contract.f95 new file mode 100644 index 000000000000..b181065d1cac --- /dev/null +++ b/clang/test/Driver/flang/classic-flang-fp-contract.f95 @@ -0,0 +1,27 @@ +! REQUIRES: classic_flang + +! RUN: %flang -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT-ABSENCE +! RUN: %flang -O1 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -O2 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -O3 -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -Ofast -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -ffp-contract=fast -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT-ABSENCE +! RUN: %flang -O1 -ffp-contract=fast -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -O2 -ffp-contract=fast -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -O3 -ffp-contract=fast -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -Ofast -ffp-contract=fast -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -ffp-contract=on -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT-ABSENCE +! RUN: %flang -O1 -ffp-contract=on -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -O2 -ffp-contract=on -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -O3 -ffp-contract=on -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -Ofast -ffp-contract=on -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT +! RUN: %flang -ffp-contract=off -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT-ABSENCE +! RUN: %flang -O1 -ffp-contract=off -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT-ABSENCE +! RUN: %flang -O2 -ffp-contract=off -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT-ABSENCE +! RUN: %flang -O3 -ffp-contract=off -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT-ABSENCE +! RUN: %flang -Ofast -ffp-contract=off -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FLANG2-FP-CONTRACT-ABSENCE + +! CHECK-FLANG2-FP-CONTRACT: "{{.*}}flang2" +! CHECK-FLANG2-FP-CONTRACT-SAME: "-x" "172" "0x40000000" "-x" "179" "1" "-x" "216" "0x1000" +! CHECK-FLANG2-FP-CONTRACT-ABSENCE: "{{.*}}flang2" +! CHECK-FLANG2-FP-CONTRACT-ABSENCE-SAME: "-x" "171" "0x40000000" "-x" "178" "1" -- Gitee From 24eadf92b56874049326b0416072a13dfe45acf3 Mon Sep 17 00:00:00 2001 From: Peixin-Qiao Date: Mon, 8 Aug 2022 15:03:08 +0800 Subject: [PATCH 25/32] [Driver] Remove the "-lompstub" in the driver In some workloads, users get "-lompstub" by running "flang -v" and link it explicitly, which may cause failure when compiling programs with OpenMP (flang -fopenmp test.f90 -lompstub). There is no runtime call in ompstub.c generated when "-fopenmp" is not added to compile the program. When "-fopenmp" is added to compile the program, the runtime in llvm/openmp(libomp.so) will be used. If users use some runtime library routines such as "omp_get_thread_num" and compiles it without the option "-fopenmp", both gfortran and ifort report errors of "undefined reference to ...". After remove "-lompstub" in the driver, classic-flang reports the error, too. So, it's safe to remove the "-lompstub" in the driver. --- clang/lib/Driver/ToolChain.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 86b778cce97a..56ff77367570 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1068,8 +1068,6 @@ void ToolChain::AddFortranStdlibLibArgs(const ArgList &Args, CmdArgs.push_back("-lpgmath"); if (useOpenMP) CmdArgs.push_back("-lomp"); - else - CmdArgs.push_back("-lompstub"); if (staticFlangLibs) CmdArgs.push_back("-Bdynamic"); -- Gitee From 314de75efe6d181f9666471961e1a02e7c16dfda Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Sat, 10 Sep 2022 19:41:06 -0400 Subject: [PATCH 26/32] [Driver] Pass Classic Flang libraries to the linker correctly In LLVM 15, the Fortran and OpenMP runtime libraries are added to the linker command line using common methods (addFortranRuntime* and addOpenMPRuntime*). This commit adds Classic Flang awareness to addFortranRuntime*, so that Classic Flang doesn't attempt to link with LLVM Flang libraries. Re-using the same methods as Clang and LLVM Flang also helps reduce downstream delta. A Classic Flang test is added to ensure that the linker command is constructed correctly. --- clang/lib/Driver/ToolChain.cpp | 32 ++++----------- clang/lib/Driver/ToolChains/CommonArgs.cpp | 18 ++++++++- clang/lib/Driver/ToolChains/CommonArgs.h | 3 ++ clang/lib/Driver/ToolChains/Darwin.cpp | 16 ++------ clang/lib/Driver/ToolChains/Gnu.cpp | 16 ++------ clang/lib/Driver/ToolChains/MSVC.cpp | 4 ++ clang/lib/Driver/ToolChains/MinGW.cpp | 4 ++ clang/test/Driver/flang/classic-flang.f95 | 46 ++++++++++++++++++++++ 8 files changed, 90 insertions(+), 49 deletions(-) diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 56ff77367570..420d7d0cbd9b 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1042,42 +1042,26 @@ void ToolChain::AddCCKextLibArgs(const ArgList &Args, #ifdef ENABLE_CLASSIC_FLANG void ToolChain::AddFortranStdlibLibArgs(const ArgList &Args, - ArgStringList &CmdArgs) const { - bool staticFlangLibs = false; - bool useOpenMP = false; - + ArgStringList &CmdArgs) const { + bool StaticFlangLibs = false; if (Args.hasArg(options::OPT_staticFlangLibs)) { - for (auto *A: Args.filtered(options::OPT_staticFlangLibs)) { - A->claim(); - staticFlangLibs = true; - } - } - - Arg *A = Args.getLastArg(options::OPT_mp, options::OPT_nomp, - options::OPT_fopenmp, options::OPT_fno_openmp); - if (A && - (A->getOption().matches(options::OPT_mp) || - A->getOption().matches(options::OPT_fopenmp))) { - useOpenMP = true; + StaticFlangLibs = true; + Args.ClaimAllArgs(options::OPT_staticFlangLibs); } - if (staticFlangLibs) + if (StaticFlangLibs && !Args.hasArg(options::OPT_static)) CmdArgs.push_back("-Bstatic"); CmdArgs.push_back("-lflang"); CmdArgs.push_back("-lflangrti"); CmdArgs.push_back("-lpgmath"); - if (useOpenMP) - CmdArgs.push_back("-lomp"); - if (staticFlangLibs) + if (StaticFlangLibs && !Args.hasArg(options::OPT_static)) CmdArgs.push_back("-Bdynamic"); - CmdArgs.push_back("-lm"); + // Always link Fortran executables with pthreads. + CmdArgs.push_back("-lpthread"); if (!Triple.isOSDarwin()) CmdArgs.push_back("-lrt"); - - // Allways link Fortran executables with Pthreads - CmdArgs.push_back("-lpthread"); } #endif diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 723a4f7ca95d..b03a6b0405f6 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -822,7 +822,11 @@ bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC, const ArgList &Args, bool ForceStaticHostRuntime, bool IsOffloadingHost, bool GompNeedsRT) { if (!Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ, - options::OPT_fno_openmp, false)) + options::OPT_fno_openmp, false) +#ifdef ENABLE_CLASSIC_FLANG + && !Args.hasFlag(options::OPT_mp, options::OPT_nomp, false) +#endif + ) return false; Driver::OpenMPRuntimeKind RTKind = TC.getDriver().getOpenMPRuntime(Args); @@ -871,7 +875,16 @@ bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC, } void tools::addFortranRuntimeLibs(const ToolChain &TC, +#ifdef ENABLE_CLASSIC_FLANG + const llvm::opt::ArgList &Args, +#endif llvm::opt::ArgStringList &CmdArgs) { +#ifdef ENABLE_CLASSIC_FLANG + if (needFortranLibs(TC.getDriver(), Args)) + TC.AddFortranStdlibLibArgs(Args, CmdArgs); + else + Args.ClaimAllArgs(options::OPT_noFlangLibs); +#else if (TC.getTriple().isKnownWindowsMSVCEnvironment()) { CmdArgs.push_back("Fortran_main.lib"); CmdArgs.push_back("FortranRuntime.lib"); @@ -881,16 +894,19 @@ void tools::addFortranRuntimeLibs(const ToolChain &TC, CmdArgs.push_back("-lFortranRuntime"); CmdArgs.push_back("-lFortranDecimal"); } +#endif } void tools::addFortranRuntimeLibraryPath(const ToolChain &TC, const llvm::opt::ArgList &Args, ArgStringList &CmdArgs) { +#ifndef ENABLE_CLASSIC_FLANG // NOTE: Generating executables by Flang is considered an "experimental" // feature and hence this is guarded with a command line option. // TODO: Make this work unconditionally once Flang is mature enough. if (!Args.hasArg(options::OPT_flang_experimental_exec)) return; +#endif // Default to the /../lib directory. This works fine on the // platforms that we have tested so far. We will probably have to re-fine diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index 436d3f8f5a87..8ec7d7c7abc8 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -133,6 +133,9 @@ bool addOpenMPRuntime(llvm::opt::ArgStringList &CmdArgs, const ToolChain &TC, /// Adds Fortran runtime libraries to \p CmdArgs. void addFortranRuntimeLibs(const ToolChain &TC, +#ifdef ENABLE_CLASSIC_FLANG + const llvm::opt::ArgList &Args, +#endif llvm::opt::ArgStringList &CmdArgs); /// Adds the path for the Fortran runtime libraries to \p CmdArgs. diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 13ec8894c021..ab442c3c0583 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -639,7 +639,11 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, // to generate executables. if (getToolChain().getDriver().IsFlangMode()) { addFortranRuntimeLibraryPath(getToolChain(), Args, CmdArgs); +#ifdef ENABLE_CLASSIC_FLANG + addFortranRuntimeLibs(getToolChain(), Args, CmdArgs); +#else addFortranRuntimeLibs(getToolChain(), CmdArgs); +#endif } if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) @@ -678,18 +682,6 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (getToolChain().ShouldLinkCXXStdlib(Args)) getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); -#ifdef ENABLE_CLASSIC_FLANG - // Add Fortran runtime libraries - if (needFortranLibs(getToolChain().getDriver(), Args)) { - getToolChain().AddFortranStdlibLibArgs(Args, CmdArgs); - } else { - // Claim "no Flang libraries" arguments if any - for (auto Arg : Args.filtered(options::OPT_noFlangLibs)) { - Arg->claim(); - } - } -#endif - bool NoStdOrDefaultLibs = Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs); bool ForceLinkBuiltins = Args.hasArg(options::OPT_fapple_link_rtlib); diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index 69e34dfa3fed..484b6e1ad9a2 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -567,18 +567,6 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, // The profile runtime also needs access to system libraries. getToolChain().addProfileRTLibs(Args, CmdArgs); -#ifdef ENABLE_CLASSIC_FLANG - // Add Fortran runtime libraries - if (needFortranLibs(D, Args)) { - ToolChain.AddFortranStdlibLibArgs(Args, CmdArgs); - } else { - // Claim "no Flang libraries" arguments if any - for (auto Arg : Args.filtered(options::OPT_noFlangLibs)) { - Arg->claim(); - } - } -#endif - if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, options::OPT_r)) { @@ -610,7 +598,11 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, // AddRuntTimeLibs). if (D.IsFlangMode()) { addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs); +#ifdef ENABLE_CLASSIC_FLANG + addFortranRuntimeLibs(ToolChain, Args, CmdArgs); +#else addFortranRuntimeLibs(ToolChain, CmdArgs); +#endif CmdArgs.push_back("-lm"); } diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index 14ebe38ee191..3441428793b0 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -132,7 +132,11 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (C.getDriver().IsFlangMode()) { addFortranRuntimeLibraryPath(TC, Args, CmdArgs); +#ifdef ENABLE_CLASSIC_FLANG + addFortranRuntimeLibs(TC, Args, CmdArgs); +#else addFortranRuntimeLibs(TC, CmdArgs); +#endif // Inform the MSVC linker that we're generating a console application, i.e. // one with `main` as the "user-defined" entry point. The `main` function is diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp index ae7c4c56bf9e..83a1980c5208 100644 --- a/clang/lib/Driver/ToolChains/MinGW.cpp +++ b/clang/lib/Driver/ToolChains/MinGW.cpp @@ -220,7 +220,11 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (C.getDriver().IsFlangMode()) { addFortranRuntimeLibraryPath(TC, Args, CmdArgs); +#ifdef ENABLE_CLASSIC_FLANG + addFortranRuntimeLibs(TC, Args, CmdArgs); +#else addFortranRuntimeLibs(TC, CmdArgs); +#endif } // TODO: Add profile stuff here diff --git a/clang/test/Driver/flang/classic-flang.f95 b/clang/test/Driver/flang/classic-flang.f95 index 6fce9c61713c..bc51c6e0c380 100644 --- a/clang/test/Driver/flang/classic-flang.f95 +++ b/clang/test/Driver/flang/classic-flang.f95 @@ -41,3 +41,49 @@ ! CHECK-ASM-SAME: "-o" "classic-flang.s" ! CHECK-ASM-SAME: "-x" "ir" ! CHECK-ASM-SAME: [[LLFILE]] + +! Check that the linker job is given the correct libraries and library paths. + +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -mp \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-DYNAMIC-FLANG,CHECK-DYNAMIC-OMP %s +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -mp -nomp \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-DYNAMIC-FLANG,CHECK-NO-OMP %s +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -fopenmp \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-DYNAMIC-FLANG,CHECK-DYNAMIC-OMP %s +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -fopenmp -fno-openmp \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-DYNAMIC-FLANG,CHECK-NO-OMP %s +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -fopenmp -static-openmp \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-DYNAMIC-FLANG,CHECK-STATIC-OMP %s +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -fopenmp -static-flang-libs \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-STATIC-FLANG,CHECK-DYNAMIC-OMP %s +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -static-flang-libs \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD,CHECK-STATIC-FLANG,CHECK-NO-OMP %s + +! CHECK-LD: "{{.*}}ld" +! CHECK-LD-NOT: "-static" +! CHECK-LD: "{{[^"]*}}classic-flang-{{[^ ]*}}.o" "-lflangmain" "-lfoo" "-L{{[^ ]*}}/basic_linux_tree/usr/lib" +! CHECK-DYNAMIC-FLANG-NOT: "-Bstatic" +! CHECK-DYNAMIC-FLANG: "-lflang" "-lflangrti" "-lpgmath" "-lpthread" "-lrt" "-lm" +! CHECK-DYNAMIC-FLANG-NOT: "-Bdynamic" +! CHECK-STATIC-FLANG: "-Bstatic" "-lflang" "-lflangrti" "-lpgmath" "-Bdynamic" "-lpthread" "-lrt" "-lm" +! CHECK-DYNAMIC-OMP-NOT: "-Bstatic" +! CHECK-DYNAMIC-OMP: "-lomp" "-rpath" "{{[^ ]*}}/basic_linux_tree/usr/lib" +! CHECK-DYNAMIC-OMP-NOT: "-Bdynamic" +! CHECK-STATIC-OMP: "-Bstatic" "-lomp" "-Bdynamic" "-rpath" "{{[^ ]*}}/basic_linux_tree/usr/lib" +! CHECK-NO-OMP-NOT: "-lomp" + +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -static -static-flang-libs \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD-STATIC,CHECK-NO-OMP %s +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -static -fopenmp \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD-STATIC,CHECK-STATIC-BOTH %s +! RUN: %flang -target x86_64-linux-gnu -ccc-install-dir %S/../Inputs/basic_linux_tree/usr/bin -static -fopenmp -static-openmp \ +! RUN: %s -lfoo -### 2>&1 | FileCheck --check-prefixes=CHECK-LD-STATIC,CHECK-STATIC-BOTH %s +! CHECK-LD-STATIC: "{{.*}}ld" +! CHECK-LD-STATIC: "-static" "-o" "a.out" +! CHECK-LD-STATIC: "{{[^"]*}}classic-flang-{{[^ ]*}}.o" "-lflangmain" "-lfoo" "-L{{[^ ]*}}/basic_linux_tree/usr/lib" +! CHECK-LD-STATIC-NOT: "-Bstatic" +! CHECK-LD-STATIC: "-lflang" "-lflangrti" "-lpgmath" "-lpthread" "-lrt" "-lm" +! CHECK-LD-STATIC-NOT: "-Bdynamic" +! CHECK-STATIC-BOTH-NOT: "-Bstatic" +! CHECK-STATIC-BOTH: "-lomp" +! CHECK-STATIC-BOTH-NOT: "-Bdynamic" -- Gitee From 98d0da05fd46261d9f8bec4f964f08edc4b0ef0f Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Wed, 7 Sep 2022 15:48:40 -0400 Subject: [PATCH 27/32] [workflows] Allow GitHub actions in the classic-flang-llvm-project fork LLVM 15 added 'ignore-forks: true' to the GitHub action triggers, which prevents the actions from running in the classic-flang-llvm-project repo. This patch undoes the setting. --- .github/workflows/clang-tests.yml | 2 -- .github/workflows/llvm-tests.yml | 2 -- 2 files changed, 4 deletions(-) diff --git a/.github/workflows/clang-tests.yml b/.github/workflows/clang-tests.yml index f8d5fd8f4666..1af3b41ba087 100644 --- a/.github/workflows/clang-tests.yml +++ b/.github/workflows/clang-tests.yml @@ -3,7 +3,6 @@ name: Clang Tests on: workflow_dispatch: push: - ignore-forks: true branches: - 'release/**' paths: @@ -12,7 +11,6 @@ on: - '.github/workflows/llvm-project-tests.yml' - '!llvm/**' pull_request: - ignore-forks: true branches: - 'release/**' paths: diff --git a/.github/workflows/llvm-tests.yml b/.github/workflows/llvm-tests.yml index 7264c62ce134..fbff885122f2 100644 --- a/.github/workflows/llvm-tests.yml +++ b/.github/workflows/llvm-tests.yml @@ -3,7 +3,6 @@ name: LLVM Tests on: workflow_dispatch: push: - ignore-forks: true branches: - 'release/**' paths: @@ -11,7 +10,6 @@ on: - '.github/workflows/llvm-tests.yml' - '.github/workflows/llvm-project-tests.yml' pull_request: - ignore-forks: true branches: - 'release/**' paths: -- Gitee From 0bbd6ea0014cb41e49e3a3e679636dfd08ecb845 Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Fri, 9 Sep 2022 08:44:33 -0400 Subject: [PATCH 28/32] [workflows] Update branch filter to allow actions on all 'release_*x' branches By changing the branch filter from an explicit list to a glob, this commit hopes to reduce future maintenance burden (as long as we continue to use the same branch naming convention). --- .github/workflows/clang-tests.yml | 4 ++-- .github/workflows/flang-tests.yml | 3 ++- .github/workflows/llvm-tests.yml | 4 ++-- .github/workflows/pre-compile_llvm.yml | 3 ++- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/clang-tests.yml b/.github/workflows/clang-tests.yml index 1af3b41ba087..19c0a394de49 100644 --- a/.github/workflows/clang-tests.yml +++ b/.github/workflows/clang-tests.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: push: branches: - - 'release/**' + - 'release_*x' paths: - 'clang/**' - '.github/workflows/clang-tests.yml' @@ -12,7 +12,7 @@ on: - '!llvm/**' pull_request: branches: - - 'release/**' + - 'release_*x' paths: - 'clang/**' - '.github/workflows/clang-tests.yml' diff --git a/.github/workflows/flang-tests.yml b/.github/workflows/flang-tests.yml index 410ba05290a7..c7ce689451da 100644 --- a/.github/workflows/flang-tests.yml +++ b/.github/workflows/flang-tests.yml @@ -2,7 +2,8 @@ name: Build and test Flang on: pull_request: - branches: [ release_11x, release_12x, release_13x, release_14x ] + branches: + - 'release_*x' jobs: build: diff --git a/.github/workflows/llvm-tests.yml b/.github/workflows/llvm-tests.yml index fbff885122f2..d0ddfeca1e57 100644 --- a/.github/workflows/llvm-tests.yml +++ b/.github/workflows/llvm-tests.yml @@ -4,14 +4,14 @@ on: workflow_dispatch: push: branches: - - 'release/**' + - 'release_*x' paths: - 'llvm/**' - '.github/workflows/llvm-tests.yml' - '.github/workflows/llvm-project-tests.yml' pull_request: branches: - - 'release/**' + - 'release_*x' paths: - 'llvm/**' - '.github/workflows/llvm-tests.yml' diff --git a/.github/workflows/pre-compile_llvm.yml b/.github/workflows/pre-compile_llvm.yml index 7cb4b8ed72bd..98b54ed41f98 100644 --- a/.github/workflows/pre-compile_llvm.yml +++ b/.github/workflows/pre-compile_llvm.yml @@ -3,7 +3,8 @@ name: Pre-compile llvm on: workflow_dispatch: push: - branches: [ release_11x, release_12x, release_13x, release_14x ] + branches: + - 'release_*x' jobs: build: -- Gitee From 7ba4730ec6dce23ecb5d0f6930b0ef1080875747 Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Thu, 8 Sep 2022 09:35:31 -0400 Subject: [PATCH 29/32] [OpenMP] Exclude a test that fails on smaller GitHub runners --- openmp/runtime/test/ompt/teams/distribute_dispatch.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openmp/runtime/test/ompt/teams/distribute_dispatch.c b/openmp/runtime/test/ompt/teams/distribute_dispatch.c index 9435ff1a9fea..cfbe791a73d8 100644 --- a/openmp/runtime/test/ompt/teams/distribute_dispatch.c +++ b/openmp/runtime/test/ompt/teams/distribute_dispatch.c @@ -1,5 +1,10 @@ // RUN: %libomp-compile-and-run | %sort-threads | FileCheck %s // REQUIRES: ompt + +// This test expects 4 teams of 1 thread each to be created, and fails +// on CI runners with insufficient resources. +// UNSUPPORTED: linux + #include "callback.h" #define WORK_SIZE 64 -- Gitee From 78b038884322bc185690ef780588845841e3044b Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Tue, 18 Oct 2022 17:11:07 -0400 Subject: [PATCH 30/32] [workflows] Add AArch64 build job Unlike their flang counterparts, classic-flang-llvm-project PRs did not have any AArch64 workflows. So problems with a PR may remain hidden until another PR is submitted to the flang repo and fails the AArch64 workflow there. This patch adds the missing build job. --- .github/workflows/flang-arm64-tests.yml | 70 +++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 .github/workflows/flang-arm64-tests.yml diff --git a/.github/workflows/flang-arm64-tests.yml b/.github/workflows/flang-arm64-tests.yml new file mode 100644 index 000000000000..bd85c550f008 --- /dev/null +++ b/.github/workflows/flang-arm64-tests.yml @@ -0,0 +1,70 @@ +name: Build and test Flang + +on: + pull_request: + branches: + - 'release_*x' + +jobs: + build: + runs-on: self-hosted + env: + build_path: /home/github + install_prefix: /home/github/usr/local + container: + image: ghcr.io/${{ github.repository_owner}}/ubuntu20-flang-${{ github.base_ref }}:latest + credentials: + username: github + strategy: + matrix: + target: [AArch64] + cc: [clang] + cpp: [clang++] + version: [10, 11] + include: + - target: AArch64 + cc: gcc + cpp: g++ + version: 10 + + steps: + - name: Check tools + run: | + git --version + cmake --version + make --version + ${{ matrix.cc }}-${{ matrix.version }} --version + ${{ matrix.cpp }}-${{ matrix.version }} --version + + - name: Manual checkout to build in user's home dir (pull_request) + run: | + cd ${{ env.build_path }} + git clone https://github.com/flang-compiler/classic-flang-llvm-project.git + cd classic-flang-llvm-project + git fetch origin ${{github.ref}}:pr_branch + git checkout pr_branch + + - name: Build and install llvm + run: | + cd ${{ env.build_path }}/classic-flang-llvm-project + ./build-llvm-project.sh -t ${{ matrix.target }} -p ${{ env.install_prefix }} -a /usr/bin/${{ matrix.cc }}-${{ matrix.version }} -b /usr/bin/${{ matrix.cpp }}-${{ matrix.version }} -n $(nproc) -i -v + + - name: Checkout flang + run: | + cd ${{ env.build_path }} + git clone --depth 1 --single-branch --branch master https://github.com/flang-compiler/flang.git + + - name: Build and install libpgmath & flang + run: | + cd ${{ env.build_path }}/flang + ./build-flang.sh -t ${{ matrix.target }} -p ${{ env.install_prefix }} -n $(nproc) + + - name: Copy llvm-lit + run: | + cd ${{ env.build_path }}/flang + cp ${{ env.build_path }}/classic-flang-llvm-project/build/bin/llvm-lit build/bin/. + + - name: Test flang + run: | + cd ${{ env.build_path }}/flang/build + make check-all -- Gitee From 21a007cb433085ecbc4981ab50f3f65a50fd6202 Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Thu, 3 Nov 2022 08:57:43 -0400 Subject: [PATCH 31/32] [AsmPrinter] Delete dead code; NFC Delete some snippets that had been commented out since commit a10f592d3b027 in release_13x. --- llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h | 35 ----------- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 70 --------------------- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 8 --- 3 files changed, 113 deletions(-) diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h index e2b99d523f27..185ee92777bf 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h +++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h @@ -214,15 +214,6 @@ public: LLVM_DUMP_METHOD void dump() const { for (const DbgValueLocEntry &DV : ValueLocEntries) DV.dump(); -// if (isLocation()) { -// llvm::dbgs() << "Loc = { reg=" << Loc.getReg() << " "; -// if (Loc.isIndirect()) -// llvm::dbgs() << "+0"; -// llvm::dbgs() << "} "; -// } else if (isConstantInt()) -// Constant.CIP->dump(); -// else if (isConstantFP()) -// Constant.CFP->dump(); if (Expression) Expression->dump(); } @@ -290,9 +281,6 @@ public: DebugLocStream::ListBuilder &List, const DIBasicType *BT, DwarfCompileUnit &TheCU); - -// void finalize(const AsmPrinter &AP, DebugLocStream::ListBuilder &List, -// const DIStringType *ST, DwarfCompileUnit &TheCU); }; /// Compare two DbgValueLocEntries for equality. @@ -321,29 +309,6 @@ inline bool operator==(const DbgValueLoc &A, const DbgValueLoc &B) { A.Expression == B.Expression && A.IsVariadic == B.IsVariadic; } -//inline bool operator==(const DbgValueLoc &A, -// const DbgValueLoc &B) { -// if (A.EntryKind != B.EntryKind) -// return false; -// -// if (A.Expression != B.Expression) -// return false; -// -// switch (A.EntryKind) { -// case DbgValueLoc::E_Location: -// return A.Loc == B.Loc; -// case DbgValueLoc::E_TargetIndexLocation: -// return A.TIL == B.TIL; -// case DbgValueLoc::E_Integer: -// return A.Constant.Int == B.Constant.Int; -// case DbgValueLoc::E_ConstantFP: -// return A.Constant.CFP == B.Constant.CFP; -// case DbgValueLoc::E_ConstantInt: -// return A.Constant.CIP == B.Constant.CIP; -// } -// llvm_unreachable("unhandled EntryKind"); -//} - /// Compare two fragments based on their offset. inline bool operator<(const DbgValueLoc &A, const DbgValueLoc &B) { diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index c8cbbf6eb464..54af14429907 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1826,28 +1826,10 @@ DbgEntity *DwarfDebug::createConcreteEntity(DwarfCompileUnit &TheCU, return ConcreteEntities.back().get(); } -#if 0 -void DwarfDebug::populateDependentTypeMap() { - for (const auto &I : DbgValues) { - InlinedEntity IV = I.first; - if (I.second.empty()) - continue; - if (const DIVariable *DIV = dyn_cast(IV.first)) { - if (const DIStringType *ST = dyn_cast( - static_cast(DIV->getType()))) - if (const DIVariable *LV = ST->getStringLength()) - VariableInDependentType[LV] = ST; - } - } -} -#endif - // Find variables for each lexical scope. void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU, const DISubprogram *SP, DenseSet &Processed) { -// clearDependentTracking(); -// populateDependentTypeMap(); // Grab the variable info that was squirreled away in the MMI side-table. collectVariableInfoFromMFTable(TheCU, Processed); @@ -1866,11 +1848,6 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU, LexicalScope *Scope = nullptr; const DILocalVariable *LocalVar = cast(IV.first); -#if 0 - const DILocalVariable *LocalVar = dyn_cast(IV.first); - if (!LocalVar) - continue; -#endif if (const DILocation *IA = IV.second) Scope = LScopes.findInlinedScope(LocalVar->getScope(), IA); else @@ -1929,24 +1906,6 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU, // Finalize the entry by lowering it into a DWARF bytestream. for (auto &Entry : Entries) Entry.finalize(*Asm, List, BT, TheCU); -#if 0 - List.finalize(); - - if (VariableInDependentType.count(LocalVar)) { - const DIType *DT = VariableInDependentType[LocalVar]; - if (const DIStringType *ST = dyn_cast(DT)) { - unsigned Offset; - DbgVariable TVar = {LocalVar, IV.second}; - DebugLocStream::ListBuilder LB(DebugLocs, TheCU, *Asm, TVar, *MInsn); - for (auto &Entry : Entries) - Entry.finalize(*Asm, LB, ST, TheCU); - LB.finalize(); - Offset = TVar.getDebugLocListIndex(); - if (Offset != ~0u) - addStringTypeLoc(ST, Offset); - } - } -#endif } // For each InlinedEntity collected from DBG_LABEL instructions, convert to @@ -2718,35 +2677,6 @@ void DebugLocEntry::finalize(const AsmPrinter &AP, List.setTagOffset(*DwarfExpr.TagOffset); } -#if 0 -inline static DbgValueLoc mkDbgValueLoc(const DIExpression *expr, - DbgValueLoc &value) { - if (value.isInt()) - return DbgValueLoc(expr, value.getInt()); - if (value.isLocation()) - return DbgValueLoc(expr, value.getLoc()); - if (value.isConstantInt()) - return DbgValueLoc(expr, value.getConstantInt()); - assert(value.isConstantFP()); - return DbgValueLoc(expr, value.getConstantFP()); -} - -void DebugLocEntry::finalize(const AsmPrinter &AP, - DebugLocStream::ListBuilder &List, - const DIStringType *ST, - DwarfCompileUnit &TheCU) { - DebugLocStream::EntryBuilder Entry(List, Begin, End); - BufferByteStreamer Streamer = Entry.getStreamer(); - DebugLocDwarfExpression DwarfExpr(AP.getDwarfVersion(), Streamer, TheCU); - DbgValueLoc &Value = Values[0]; - assert(!Value.isFragment()); - assert(Values.size() == 1 && "only fragments may have >1 value"); - Value = mkDbgValueLoc(ST->getStringLengthExp(), Value); - DwarfDebug::emitDebugLocValue(AP, nullptr, Value, DwarfExpr); - DwarfExpr.finalize(); -} -#endif - void DwarfDebug::emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU) { // Emit the size. diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index b1bc16ee57a8..c249f812042f 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -628,14 +628,6 @@ private: /// Emit the reference to the section. void emitSectionReference(const DwarfCompileUnit &CU); -#if 0 - /// Populate dependent type variable map - void populateDependentTypeMap(); -#endif - - /// Clear dependent type tracking map - void clearDependentTracking() { VariableInDependentType.clear(); } - protected: /// Gather pre-function debug information. void beginFunctionImpl(const MachineFunction *MF) override; -- Gitee From b62a5e081af88b1bdd057908b67463c040e58dd5 Mon Sep 17 00:00:00 2001 From: Bryan Chan Date: Thu, 3 Nov 2022 09:06:01 -0400 Subject: [PATCH 32/32] [workflows] Delete misleading pull request template Upstream llvm-project repository does not accept pull requests, but our fork does. --- .github/PULL_REQUEST_TEMPLATE.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index a3d33bdb4d43..000000000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,5 +0,0 @@ -# **DO NOT FILE A PULL REQUEST** - -This repository does not accept pull requests. Please follow http://llvm.org/docs/Contributing.html#how-to-submit-a-patch for contribution to LLVM. - -# **DO NOT FILE A PULL REQUEST** -- Gitee