Skip to content

Comments

Adding Fortran call graph collector#115

Open
gomfol12 wants to merge 136 commits intotudasc:develfrom
gomfol12:fortran_collector
Open

Adding Fortran call graph collector#115
gomfol12 wants to merge 136 commits intotudasc:develfrom
gomfol12:fortran_collector

Conversation

@gomfol12
Copy link
Contributor

@gomfol12 gomfol12 commented Feb 5, 2026

This adds a call graph collector for Fortran. The collector is implemented as a flang plugin and generates a call graph from source-level. See the tests for a list of language features this plugin covers.

This pull request is quite large, but it is not really possible splitting it in multiply requests without pushing broken code. The tests could be separate into a different pull request, but they are tightly coupled with the collector and would fail without it, so I think keeping it in one pull request makes sense.

What this adds:

  • new directory cgfcollector that includes flang plugin, tests, tools, etc.
  • flang plugin that generates call graph in metacg format.
  • two wrapper script cgfcollector_wrapper.sh and cgfcollector_comp_wrapper.sh that simplify running the plugin.
  • cgCompare tool: for comparing two call graphs (can be replaced with cgdiff)
  • another test runner

How to run: see cgfcollector/README.md

The commit history is a mess, and I don't know how strongly you value a clean git history and if I should clean this up.

Copy link
Member

@pearzt pearzt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for all the work, the structure looks really good. I have some initial comments, but I will try to do a more in-depth review soon.

Copy link
Member

@jplehr jplehr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for working on this.

I did an initial brief pass, please go through the comments and address them.

One more question: Does this PR as-is already run CI pipelines? If not, please add it to the CI pipelines as appropriate.

dot::DotGenerator dotGen(cg);
dotGen.generate();

std::unique_ptr<llvm::raw_pwrite_stream> dotfile = ::createOutputFile(getInstance(), getCurrentFile(), "dot");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be problematic in parallel CI runs

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should separate the concerns between call graph generation and visualization. cgfcollector produces the call graph. If the user want a visualization, they can use your dot export tool for this (which is a nice addition, btw).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would indeed be nice: have the dot generator tool as a separate PR.


std::string cgString = dumpCG();

std::unique_ptr<llvm::raw_pwrite_stream> file = ::createOutputFile(getInstance(), getCurrentFile(), "");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be problematic in parallel CI runs

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be named visual?

Is this limited to the Fortran support? I would assume this can be factored out into another PR and put in as a general tool.
Other people's thoughts?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that this is something that should extracted into a separate PR.

@pearzt
Copy link
Member

pearzt commented Feb 17, 2026

Please rebase this onto the most current devel.

generateCG(getParsing().parseTree(), getCurrentFile());

std::string cgString = dumpCG();
std::unique_ptr<llvm::raw_pwrite_stream> file = ::createOutputFile(getInstance(), getCurrentFile(), "json");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the MCGWriter infrastructure for file output. For an example how to use this, have a look at tools/cgconvert/CGConvert.cpp.

dot::DotGenerator dotGen(cg);
dotGen.generate();

std::unique_ptr<llvm::raw_pwrite_stream> dotfile = ::createOutputFile(getInstance(), getCurrentFile(), "dot");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should separate the concerns between call graph generation and visualization. cgfcollector produces the call graph. If the user want a visualization, they can use your dot export tool for this (which is a nice addition, btw).

Copy link
Member

@jplehr jplehr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another round of comments


install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake DESTINATION lib/cmake)

# visuel program to generate dot file from graph
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# visuel program to generate dot file from graph
# program to generate dot file from graph

install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake DESTINATION lib/cmake)

# visuel program to generate dot file from graph
add_executable(${PROJECT_NAME}-visuel ${CMAKE_CURRENT_SOURCE_DIR}/tools/visuel.cpp)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
add_executable(${PROJECT_NAME}-visuel ${CMAKE_CURRENT_SOURCE_DIR}/tools/visuel.cpp)
add_executable(${PROJECT_NAME}-visual ${CMAKE_CURRENT_SOURCE_DIR}/tools/visuel.cpp)

I think that's a typo

set(INSTALL_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_BASENAME}.install")

# build-time values for development
set(CGFCOLLECTOR_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}.so")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this say that it is a library?

CGFCOLLECTOR_FILE_NAME_SO or _LIB or so?


# build-time values for development
set(CGFCOLLECTOR_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}.so")
set(CGFCOLLECTOR_CGDIFF "${CMAKE_BINARY_DIR}/tools/cgdiff/cgdiff")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly should this be _BIN to indicate that's a binary?

"cmake_base.txt"
""
)
file(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this used for?


EdgeManager(std::vector<Edge>& edges) : edges(edges) {}

void addEdge(const EdgeSymbol& e, bool debug = true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does debug indicate here and should the default really be "true"?

If that is more a development thing, the default should be false and only set to true when in debug build or when set to verbose or so.


#include <flang/Semantics/symbol.h>
#include <vector>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should have this whole thing in a namespace.

I don't remember what we did with cgcollector2, but how about metacg::cgf or so?

// visitor methods

template <typename A>
bool Pre(const A&) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are all of those pre and post uppercase?

// added to cg in postProcess step
std::vector<Edge> edges;

// all functions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment does not say anything

// args when the AST walker is in the respective function.
std::vector<Function> currentFunctions;

// all types
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment does not say anything

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants