Skip to content

Commit

Permalink
Merge branch 'salt-fm' of https://github.com/ParaToolsInc/salt into s…
Browse files Browse the repository at this point in the history
…alt-fm
  • Loading branch information
nchaimov committed Dec 5, 2024
2 parents f87e6d7 + 6191306 commit 9ab29a3
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 21 deletions.
109 changes: 95 additions & 14 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -104,6 +104,7 @@ project(SALT
find_package(LLVM REQUIRED CONFIG)
find_package(Clang REQUIRED CONFIG)


# get_cmake_property(_variableNames VARIABLES)
# list (SORT _variableNames)
# foreach (_variableName ${_variableNames})
Expand Down Expand Up @@ -153,6 +154,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
#------------------------------------------
Expand All @@ -174,19 +177,21 @@ set(CLANG_LIBS
clangRewriteFrontend
)


#-----------------------------------------
# Add an interface library to link against
#-----------------------------------------

# 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
#---------------------------------
Expand Down Expand Up @@ -217,21 +222,88 @@ set(CPARSE_LLVM_SRCS

list(TRANSFORM CPARSE_LLVM_SRCS PREPEND "${CMAKE_SOURCE_DIR}/src/")



#---------------------
# Add the main targets
#---------------------
# If we refactor into a library that executables link against it will simplify this and reduce repitition
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)

# 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}")

# 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)

# 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,-undefined -Wl,dynamic_lookup)

install(TARGETS salt-flang-plugin DESTINATION lib)

else()
message(STATUS "Flang not found -- skipping Flang frontend plugin")
endif()




#---------------
# Tests
#---------------
Expand Down Expand Up @@ -313,7 +385,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()

Expand All @@ -334,17 +406,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
Expand All @@ -361,11 +442,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
################
Expand Down
14 changes: 7 additions & 7 deletions config_files/tau_fortran_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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)"
78 changes: 78 additions & 0 deletions src/PrintFlangFunctionNames.cpp
Original file line number Diff line number Diff line change
@@ -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 <typename A> bool Pre(const A &) { return true; }
template <typename A> 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<Fortran::parser::Name>(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<Fortran::parser::Name>(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<PrintFunctionNamesAction> X(
"print-fns", "Print Function names");

0 comments on commit 9ab29a3

Please sign in to comment.