From 9dd706ae51bfc310f79b0dcf9295254704ca5710 Mon Sep 17 00:00:00 2001 From: Nicholas Chaimov Date: Wed, 4 Dec 2024 16:00:09 -0800 Subject: [PATCH 1/4] Add attempt to build the PrintFlangFunctionNames example Add source to llvm-project/flang/examples/PrintFlangFunctionNames and attempt to build out of tree. Compiles and links but crashes when run. --- CMakeLists.txt | 82 ++++++++++++++++++++++++++++++++- src/PrintFlangFunctionNames.cpp | 78 +++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 src/PrintFlangFunctionNames.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 350346b..3d8295e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,6 +102,7 @@ project(SALT find_package(LLVM REQUIRED CONFIG) find_package(Clang REQUIRED CONFIG) + # get_cmake_property(_variableNames VARIABLES) # list (SORT _variableNames) # foreach (_variableName ${_variableNames}) @@ -151,6 +152,8 @@ configure_file( "${CMAKE_SOURCE_DIR}/include/clang_header_includes.h.in" "${CMAKE_BINARY_DIR}/include/clang_header_includes.h" @ONLY) + + #------------------------------------------ # Specify clang and system libraries needed #------------------------------------------ @@ -172,6 +175,7 @@ set(CLANG_LIBS clangRewriteFrontend ) + #----------------------------------------- # Add an interface library to link against #----------------------------------------- @@ -179,12 +183,13 @@ set(CLANG_LIBS # This provides an abstraction and shorthand so that you can just `target_link_libraries()` against # the SALT_LLVM_TOOLING interface library add_library(SALT_LLVM_TOOLING INTERFACE) -target_compile_features(SALT_LLVM_TOOLING INTERFACE cxx_std_14) +target_compile_features(SALT_LLVM_TOOLING INTERFACE cxx_std_17) target_include_directories(SALT_LLVM_TOOLING INTERFACE ${LLVM_INCLUDE_DIRS}) target_compile_definitions(SALT_LLVM_TOOLING INTERFACE ${LLVM_DEFINITIONS_LIST}) target_compile_options(SALT_LLVM_TOOLING INTERFACE ${USE_RTTI} -Wall -Werror -Wpedantic) target_link_libraries(SALT_LLVM_TOOLING INTERFACE ${CLANG_LIBS} ${LLVM_LIBS}) + #--------------------------------- # List the header and source files #--------------------------------- @@ -215,6 +220,8 @@ set(CPARSE_LLVM_SRCS list(TRANSFORM CPARSE_LLVM_SRCS PREPEND "${CMAKE_SOURCE_DIR}/src/") + + #--------------------- # Add the main targets #--------------------- @@ -222,7 +229,7 @@ list(TRANSFORM CPARSE_LLVM_SRCS PREPEND "${CMAKE_SOURCE_DIR}/src/") add_executable(cparse-llvm) target_sources(cparse-llvm PUBLIC ${CPARSE_LLVM_SRCS}) target_include_directories(cparse-llvm PUBLIC "${CMAKE_SOURCE_DIR}/include" "${CMAKE_BINARY_DIR}/include") -target_compile_features(cparse-llvm PUBLIC cxx_std_14) +target_compile_features(cparse-llvm PUBLIC cxx_std_17) target_link_libraries(cparse-llvm PUBLIC SALT_LLVM_TOOLING) # Inherit definitions, compile features, etc. # You can try adding -static target_link_options(cparse-llvm PUBLIC -Wl,--as-needed -Wl,--no-allow-shlib-undefined -Wl,--no-undefined) @@ -230,6 +237,77 @@ target_link_options(cparse-llvm PUBLIC -Wl,--as-needed -Wl,--no-allow-shlib-unde # Install the target install(TARGETS cparse-llvm DESTINATION bin) + +#--------------------- +# Flang Frontend library +#--------------------- + +# Flang package requires MLIR +find_package(MLIR CONFIG) +if(MLIR_FOUND) + message(STATUS "Found MLIR -- will check for Flang") + find_package(Flang CONFIG) +else() + message(STATUS "MLIR not found -- skipping Flang") +endif() + +if(MLIR_FOUND AND Flang_FOUND) + message(STATUS "Found Flang -- will build Flang frontend plugin") + +# Variables set i1n FlangConfig.cmake + message(STATUS "FLANG_CMAKE_DIR: ${FLANG_CMAKE_DIR}") + message(STATUS "FLANG_EXPORTED_TARGETS: ${FLANG_EXPORTED_TARGETS}") + message(STATUS "FLANG_INCLUDE_DIRS: ${FLANG_INCLUDE_DIRS}") + +# Libraries required by Flang plugin + set(FLANG_LIBS + flangFrontend + ) + +# Interface for Flang frontend plugins + add_library(SALT_FLANG_FRONTEND INTERFACE) + target_compile_features(SALT_FLANG_FRONTEND INTERFACE cxx_std_17) + target_include_directories(SALT_FLANG_FRONTEND INTERFACE ${LLVM_INCLUDE_DIRS} ${FLANG_INCLUDE_DIRS}) + target_compile_definitions(SALT_FLANG_FRONTEND INTERFACE ${LLVM_DEFINITIONS_LIST}) + target_compile_options(SALT_FLANG_FRONTEND INTERFACE ${USE_RTTI} -Wall -Werror -Wpedantic) + target_link_libraries(SALT_FLANG_FRONTEND INTERFACE ${FLANG_LIBS}) + +# Endianness definitions are required, and Flang does not export a definitions list + include(TestBigEndian) + test_big_endian(IS_BIGENDIAN) + if (IS_BIGENDIAN) + target_compile_definitions(SALT_FLANG_FRONTEND INTERFACE FLANG_BIG_ENDIAN=1) + else () + target_compile_definitions(SALT_FLANG_FRONTEND INTERFACE FLANG_LITTLE_ENDIAN=1) + endif () + + set(SALT_FLANG_PLUGIN_HEADER_FILES + selectfile.hpp + tau_datatypes.h + ) + list(TRANSFORM SALT_FLANG_PLUGIN_HEADER_FILES PREPEND "${CMAKE_SOURCE_DIR}/include/") + + set(SALT_FLANG_PLUGIN_SRCS + PrintFlangFunctionNames.cpp + ) + list(TRANSFORM SALT_FLANG_PLUGIN_SRCS PREPEND "${CMAKE_SOURCE_DIR}/src/") + + add_library(salt-flang-plugin SHARED) + target_sources(salt-flang-plugin PUBLIC ${SALT_FLANG_PLUGIN_SRCS}) + target_include_directories(salt-flang-plugin PUBLIC "${CMAKE_SOURCE_DIR}/include" "${CMAKE_BINARY_DIR}/include" ) + target_compile_features(salt-flang-plugin PUBLIC cxx_std_17) + target_link_libraries(salt-flang-plugin PUBLIC SALT_FLANG_FRONTEND) + target_link_options(salt-flang-plugin PUBLIC -Wl,--as-needed -Wl,--no-allow-shlib-undefined -Wl,--no-undefined) + + install(TARGETS salt-flang-plugin DESTINATION lib) + +else() + message(STATUS "Flang not found -- skipping Flang frontend plugin") +endif() + + + + #--------------- # Tests #--------------- diff --git a/src/PrintFlangFunctionNames.cpp b/src/PrintFlangFunctionNames.cpp new file mode 100644 index 0000000..4a84c3b --- /dev/null +++ b/src/PrintFlangFunctionNames.cpp @@ -0,0 +1,78 @@ +//===-- PrintFlangFunctionNames.cpp ---------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Small example Flang plugin to count/print Functions & Subroutines names. +// It walks the Parse Tree using a Visitor struct that has Post functions for +// FunctionStmt and SubroutineStmt to access the names of functions & +// subroutines. It also has Pre functions for FunctionSubprogram and +// SubroutineSubprogram so a Bool can be set to show that it is the definition +// of a function/subroutine, and not print those that are in an Interface. +// This plugin does not recognise Statement Functions or Module Procedures, +// which could be dealt with through StmtFunctionStmt and MpSubprogramStmt nodes +// respectively. +// +//===----------------------------------------------------------------------===// + +#include "flang/Frontend/FrontendActions.h" +#include "flang/Frontend/FrontendPluginRegistry.h" +#include "flang/Parser/dump-parse-tree.h" +#include "flang/Parser/parsing.h" + +using namespace Fortran::frontend; + +class PrintFunctionNamesAction : public PluginParseTreeAction { + + // Visitor struct that defines Pre/Post functions for different types of nodes + struct ParseTreeVisitor { + template bool Pre(const A &) { return true; } + template void Post(const A &) {} + + bool Pre(const Fortran::parser::FunctionSubprogram &) { + isInSubprogram_ = true; + return true; + } + void Post(const Fortran::parser::FunctionStmt &f) { + if (isInSubprogram_) { + llvm::outs() << "Function:\t" + << std::get(f.t).ToString() << "\n"; + fcounter++; + isInSubprogram_ = false; + } + } + + bool Pre(const Fortran::parser::SubroutineSubprogram &) { + isInSubprogram_ = true; + return true; + } + void Post(const Fortran::parser::SubroutineStmt &s) { + if (isInSubprogram_) { + llvm::outs() << "Subroutine:\t" + << std::get(s.t).ToString() << "\n"; + scounter++; + isInSubprogram_ = false; + } + } + + int fcounter{0}; + int scounter{0}; + + private: + bool isInSubprogram_{false}; + }; + + void executeAction() override { + ParseTreeVisitor visitor; + Fortran::parser::Walk(getParsing().parseTree(), visitor); + + llvm::outs() << "\n==== Functions: " << visitor.fcounter << " ====\n"; + llvm::outs() << "==== Subroutines: " << visitor.scounter << " ====\n"; + } +}; + +static FrontendPluginRegistry::Add X( + "print-fns", "Print Function names"); From 8411f62267a10a95c4f0f8d3bd90068a0d8d0170 Mon Sep 17 00:00:00 2001 From: Nicholas Chaimov Date: Wed, 4 Dec 2024 17:17:23 -0800 Subject: [PATCH 2/4] Fix Flang plugin link stage Unlike Clang plugins, Flang plugins are *not* supposed to be linked against the Flang library. Remove link to flangFrontend, allow undefined symbols. The example plugin works now. --- CMakeLists.txt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d8295e..2768679 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -259,18 +259,12 @@ if(MLIR_FOUND AND Flang_FOUND) message(STATUS "FLANG_EXPORTED_TARGETS: ${FLANG_EXPORTED_TARGETS}") message(STATUS "FLANG_INCLUDE_DIRS: ${FLANG_INCLUDE_DIRS}") -# Libraries required by Flang plugin - set(FLANG_LIBS - flangFrontend - ) - # Interface for Flang frontend plugins add_library(SALT_FLANG_FRONTEND INTERFACE) target_compile_features(SALT_FLANG_FRONTEND INTERFACE cxx_std_17) target_include_directories(SALT_FLANG_FRONTEND INTERFACE ${LLVM_INCLUDE_DIRS} ${FLANG_INCLUDE_DIRS}) target_compile_definitions(SALT_FLANG_FRONTEND INTERFACE ${LLVM_DEFINITIONS_LIST}) target_compile_options(SALT_FLANG_FRONTEND INTERFACE ${USE_RTTI} -Wall -Werror -Wpedantic) - target_link_libraries(SALT_FLANG_FRONTEND INTERFACE ${FLANG_LIBS}) # Endianness definitions are required, and Flang does not export a definitions list include(TestBigEndian) @@ -297,7 +291,7 @@ if(MLIR_FOUND AND Flang_FOUND) target_include_directories(salt-flang-plugin PUBLIC "${CMAKE_SOURCE_DIR}/include" "${CMAKE_BINARY_DIR}/include" ) target_compile_features(salt-flang-plugin PUBLIC cxx_std_17) target_link_libraries(salt-flang-plugin PUBLIC SALT_FLANG_FRONTEND) - target_link_options(salt-flang-plugin PUBLIC -Wl,--as-needed -Wl,--no-allow-shlib-undefined -Wl,--no-undefined) + target_link_options(salt-flang-plugin PUBLIC -Wl,--as-needed -Wl,-undefined -Wl,dynamic_lookup) install(TARGETS salt-flang-plugin DESTINATION lib) From 539d74954207daca8d64d91f676447eecd1abc78 Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Thu, 5 Dec 2024 17:49:16 -0500 Subject: [PATCH 3/4] Make injected TAU procedure names uppercase again Fortran is case agnostic, but the tests for the C/C++ instrumentor check for uppercase injected instrumentation --- config_files/tau_fortran_config.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/config_files/tau_fortran_config.yaml b/config_files/tau_fortran_config.yaml index 56aa6bc..b26122d 100644 --- a/config_files/tau_fortran_config.yaml +++ b/config_files/tau_fortran_config.yaml @@ -5,20 +5,20 @@ instrumentation: tauFortran program_insert: - " integer, save :: tauProfileTimer(2) = [0, 0]" - - " call tau_profile_init()" - - " call tau_profile_timer(tauProfileTimer, &" + - " call TAU_PROFILE_INIT()" + - " call TAU_PROFILE_TIMER(tauProfileTimer, &" - " \"${full_timer_name}\")" - - " call tau_profile_start(tauProfileTimer)" + - " call TAU_PROFILE_START(tauProfileTimer)" - "#ifndef TAU_MPI" - - " call tau_profile_set_node(0);" + - " call TAU_PROFILE_SET_NODE(0);" - "#endif ! TAU_MPI" procedure_begin_insert: - " integer, save :: tauProfileTimer(2) = [0, 0]" - - " call tau_profile_timer(tauProfileTimer, &" + - " call TAU_PROFILE_TIMER(tauProfileTimer, &" - " \"${full_timer_name}\")" - - " call tau_profile_start(tauProfileTimer)" + - " call TAU_PROFILE_START(tauProfileTimer)" procedure_end_insert: - - " call tau_profile_stop(tauProfileTimer)" + - " call TAU_PROFILE_STOP(tauProfileTimer)" From 619130654a760d72b33cb57f0e0c23f4c586e755 Mon Sep 17 00:00:00 2001 From: Izaak Beekman Date: Thu, 5 Dec 2024 17:50:38 -0500 Subject: [PATCH 4/4] CMake: Fix a typo & update testing to find TAU in multiple places --- CMakeLists.txt | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2768679..7d56c1b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.13.1) # Ensure policies are set as they have been tested -cmake_policy(VERSION 3.13.1...3.23.2) +cmake_policy(VERSION 3.13.1...3.31.2) if(POLICY CMP0144) cmake_policy(SET CMP0144 NEW) endif() @@ -383,7 +383,7 @@ function(add_instrumentor_test test_src) set_tests_properties(${TEST_NAME}_exists PROPERTIES DEPENDS ${TEST_NAME} - PASS_REGULAR_EXPERSSION "TAU_" + PASS_REGULAR_EXPRESSION "TAU_" ) endfunction() @@ -404,17 +404,26 @@ endforeach() # Check if TAU_ROOT is set as an environment variable and if not set it as a CMake cache variable to /usr/local # otherwise, use the value from the environment -if(NOT DEFINED $ENV{TAU_ROOT}) - set(TAU_ROOT "/usr/local" CACHE PATH "TAU Root Directory") -else() +if(NOT DEFINED ENV{TAU_ROOT}) + find_program(TAU_EXEC tau_exec + PATH_SUFFIXES x86_64 x86_64/bin craycnl craycnl/bin apple apple/bin + ) + if(NOT TAU_EXEC) + message(FATAL_ERROR "TAU not found. Please set TAU_ROOT to the TAU installation directory.") + else() + get_filename_component(TAU_ROOT ${TAU_EXEC} DIRECTORY) # This will be a bin directory + get_filename_component(TAU_ROOT ${TAU_ROOT} DIRECTORY) # This might be an arch directory + string(REGEX REPLACE "(/x86_64$)|(/apple$)|(/craycnl$)" "" TAU_ROOT ${TAU_ROOT}) set(TAU_ROOT $ENV{TAU_ROOT} CACHE PATH "TAU Root Directory") endif() -find_file(TAU_CLANG_MAKEFILE Makefile.tau-clang-pthread -PATHS ${TAU_ROOT} PATH_SUFFIXES x86_64 x86_64/lib +find_file(TAU_CLANG_MAKEFILE + NAMES Makefile.tau-clang-pthread + PATHS ${TAU_ROOT} PATH_SUFFIXES x86_64 x86_64/lib ) -find_file(TAU_GCC_MAKEFILE Makefile.tau-pthread -PATHS ${TAU_ROOT} PATH_SUFFIXES x86_64 x86_64/lib +find_file(TAU_GCC_MAKEFILE + NAMES Makefile.tau-pthread Makefile.tau-pthread-pdt + PATHS ${TAU_ROOT} PATH_SUFFIXES x86_64 x86_64/lib ) find_program(TAUCC tau_cc.sh PATHS ${TAU_ROOT} PATH_SUFFIXES x86_64 x86_64/bin @@ -431,11 +440,11 @@ set(TAU_HEADER_LOCATIONS ) set(TAU_CLANG_HEADER_LOCATIONS -I${TAU_ROOT}/x86_64/libdwarf-clang/include - -I${TAU_ROOT}/x86_64/libunwind-1.3.1-clang/include + -I${TAU_ROOT}/x86_64/libunwind-1.6.2-clang/include ) set(TAU_GCC_HEADER_LOCATIONS - -I${TAU_ROOT}/x86_64/libdwarf-clang/include - -I${TAU_ROOT}/x86_64/libunwind-1.3.1-clang/include + -I${TAU_ROOT}/x86_64/libdwarf-gcc/include + -I${TAU_ROOT}/x86_64/libunwind-1.6.2-gcc/include ) # End of section that note applies to ################