summaryrefslogtreecommitdiff
path: root/tiger-compiler/src/callgraph
diff options
context:
space:
mode:
authorMartial Simon <msimon_fr@hotmail.com>2025-09-15 01:07:58 +0200
committerMartial Simon <msimon_fr@hotmail.com>2025-09-15 01:07:58 +0200
commit967be9e750221ab2ab783f95df79bb26d290a45e (patch)
tree6802900a5e975f9f68b169f0f503f040056d6952 /tiger-compiler/src/callgraph
add: added projectsHEADmain
Diffstat (limited to 'tiger-compiler/src/callgraph')
-rw-r--r--tiger-compiler/src/callgraph/call-graph-visitor.cc56
-rw-r--r--tiger-compiler/src/callgraph/call-graph-visitor.hh38
-rw-r--r--tiger-compiler/src/callgraph/fundec-graph.hh76
-rw-r--r--tiger-compiler/src/callgraph/fundec-graph.hxx56
-rw-r--r--tiger-compiler/src/callgraph/libcallgraph.cc36
-rw-r--r--tiger-compiler/src/callgraph/libcallgraph.hh28
-rw-r--r--tiger-compiler/src/callgraph/local.am14
-rw-r--r--tiger-compiler/src/callgraph/parent-graph-visitor.cc42
-rw-r--r--tiger-compiler/src/callgraph/parent-graph-visitor.hh36
-rw-r--r--tiger-compiler/src/callgraph/tasks.cc52
-rw-r--r--tiger-compiler/src/callgraph/tasks.hh46
11 files changed, 480 insertions, 0 deletions
diff --git a/tiger-compiler/src/callgraph/call-graph-visitor.cc b/tiger-compiler/src/callgraph/call-graph-visitor.cc
new file mode 100644
index 0000000..6ad31c5
--- /dev/null
+++ b/tiger-compiler/src/callgraph/call-graph-visitor.cc
@@ -0,0 +1,56 @@
+/**
+ ** \file callgraph/call-graph-visitor.cc
+ ** \brief Implementation of callgraph::CallGraphVisitor.
+ **/
+
+#include <ast/call-exp.hh>
+#include <ast/function-dec.hh>
+#include <callgraph/call-graph-visitor.hh>
+
+namespace callgraph
+{
+ const CallGraph* CallGraphVisitor::create(const ast::Ast& tree)
+ {
+ // Create a new empty callgraph
+ callgraph_ = new CallGraph();
+
+ // Launch visitor.
+ tree.accept(*this);
+
+ // Return created callgraph.
+ return callgraph_;
+ }
+
+ CallGraph* CallGraphVisitor::create(ast::Ast& tree)
+ {
+ return const_cast<CallGraph*>(create(const_cast<const ast::Ast&>(tree)));
+ }
+
+ /*-----------.
+ | Visiting. |
+ `-----------*/
+
+ void CallGraphVisitor::operator()(const ast::CallExp& e)
+ {
+ // FIXME: Some code was deleted here (Link the Caller with the CallExp's declaration).
+ }
+
+ void CallGraphVisitor::operator()(const ast::FunctionChunk& e)
+ {
+ // First define the nodes for each defined function.
+ for (ast::FunctionDec* f : e)
+ callgraph_->fundec_add(f);
+ // Now bind callers and callees.
+ super_type::operator()(e);
+ }
+
+ void CallGraphVisitor::operator()(const ast::FunctionDec& e)
+ {
+ // Current function becomes temporarily the caller function.
+ ast::FunctionDec* save = caller;
+ caller = const_cast<ast::FunctionDec*>(&e);
+ super_type::operator()(e);
+ caller = save;
+ }
+
+} // namespace callgraph
diff --git a/tiger-compiler/src/callgraph/call-graph-visitor.hh b/tiger-compiler/src/callgraph/call-graph-visitor.hh
new file mode 100644
index 0000000..97d79b4
--- /dev/null
+++ b/tiger-compiler/src/callgraph/call-graph-visitor.hh
@@ -0,0 +1,38 @@
+/**
+ ** \file callgraph/call-graph-visitor.hh
+ ** \brief Definition of callgraph::CallGraphVisitor.
+ **/
+#pragma once
+
+#include <ast/default-visitor.hh>
+#include <ast/non-assert-visitor.hh>
+#include <ast/non-object-visitor.hh>
+#include <callgraph/fundec-graph.hh>
+
+namespace callgraph
+{
+ /// Computes the CallGraph.
+ class CallGraphVisitor
+ : protected ast::DefaultConstVisitor
+ , protected ast::NonObjectConstVisitor
+ , protected ast::NonAssertConstVisitor
+ {
+ public:
+ using super_type = ast::DefaultConstVisitor;
+ using super_type::operator();
+ const CallGraph* create(const ast::Ast& tree);
+ CallGraph* create(ast::Ast& tree);
+
+ protected:
+ void operator()(const ast::CallExp& e) override;
+ void operator()(const ast::FunctionChunk& e) override;
+ void operator()(const ast::FunctionDec& e) override;
+
+ protected:
+ /// Current function.
+ ast::FunctionDec* caller = nullptr;
+ /// Call graph.
+ CallGraph* callgraph_ = nullptr;
+ };
+
+} // namespace callgraph
diff --git a/tiger-compiler/src/callgraph/fundec-graph.hh b/tiger-compiler/src/callgraph/fundec-graph.hh
new file mode 100644
index 0000000..1addd0d
--- /dev/null
+++ b/tiger-compiler/src/callgraph/fundec-graph.hh
@@ -0,0 +1,76 @@
+/**
+ ** \file callgraph/fundec-graph.hh
+ ** \brief Declare and define fundec graph.
+ */
+
+#pragma once
+
+#include <map>
+
+#include <boost/graph/adjacency_list.hpp>
+
+#include <ast/function-dec.hh>
+#include <misc/graph.hh>
+
+namespace callgraph
+{
+ /*--------------.
+ | FundecGraph. |
+ `--------------*/
+
+ class FundecGraph : public misc::directed_graph<ast::FunctionDec*>
+ {
+ public:
+ /// Add a vertex to the graph, and attach a function definition to it.
+ void fundec_add(ast::FunctionDec* f);
+ /// Create an edge between two vertices, identified by the
+ /// FunctionDec attached to each of them.
+ void fundec_link(ast::FunctionDec* fu, ast::FunctionDec* fv);
+
+ /// Retrieve the vertex handle corresponding to a FunctionDec.
+ vertex_descriptor hfundec_get(ast::FunctionDec* f) const;
+
+ // Search if FunctionDec 'searched' is 'start' or one of its parent.
+ ast::FunctionDec* hfundec_deep_get(ast::FunctionDec* start,
+ ast::FunctionDec* searched) const;
+
+ protected:
+ /// Print the label of vertex of a graph.
+ std::ostream& vertex_print(vertex_descriptor v,
+ std::ostream& ostr) const override;
+
+ using hfundecs_type = std::map<ast::FunctionDec*, vertex_descriptor>;
+
+ hfundecs_type hfundecs;
+ };
+
+ using CallGraph = FundecGraph;
+ using ParentGraph = FundecGraph;
+
+ /*------------.
+ | Iterators. |
+ `------------*/
+
+ /// Iterator on the vertices of a FundecGraph.
+ using fundecgraph_vertex_iter_type =
+ boost::graph_traits<FundecGraph>::vertex_iterator;
+ /// Iterator on the edges of a FundecGraph.
+ using fundecgraph_edge_iter_type =
+ boost::graph_traits<FundecGraph>::edge_iterator;
+ /// Iterator on the neighborhood of a vertex of a FundecGraph.
+ using fundecgraph_neighb_iter_type =
+ boost::graph_traits<FundecGraph>::adjacency_iterator;
+
+ /// \name Aliases.
+ /// \{
+ /// Iterator on the vertices of a CallGraph.
+ using callgraph_vertex_iter_type = fundecgraph_vertex_iter_type;
+ /// Iterator on the neighborhood of a vertex of a CallGraph.
+ using callgraph_neighb_iter_type = fundecgraph_neighb_iter_type;
+ /// Iterator on the neighborhood of a vertex of a ParentGraph.
+ using parentgraph_neighb_iter_type = fundecgraph_neighb_iter_type;
+ /// \}
+
+} // namespace callgraph
+
+#include <callgraph/fundec-graph.hxx>
diff --git a/tiger-compiler/src/callgraph/fundec-graph.hxx b/tiger-compiler/src/callgraph/fundec-graph.hxx
new file mode 100644
index 0000000..d5d863e
--- /dev/null
+++ b/tiger-compiler/src/callgraph/fundec-graph.hxx
@@ -0,0 +1,56 @@
+/**
+ ** \file callgraph/fundec-graph.hxx
+ ** \brief Inline methods for callgraph/fundec-graph.hh.
+ */
+
+#pragma once
+
+#include <callgraph/fundec-graph.hh>
+
+namespace callgraph
+{
+ inline void FundecGraph::fundec_add(ast::FunctionDec* f)
+ {
+ hfundecs[f] = this->vertex_add(f);
+ }
+
+ inline void FundecGraph::fundec_link(ast::FunctionDec* fu,
+ ast::FunctionDec* fv)
+ {
+ vertex_descriptor u = hfundecs[fu];
+ vertex_descriptor v = hfundecs[fv];
+ boost::add_edge(u, v, *this);
+ }
+
+ inline FundecGraph::vertex_descriptor
+ FundecGraph::hfundec_get(ast::FunctionDec* f) const
+ {
+ hfundecs_type::const_iterator i = hfundecs.find(f);
+ assertion(i != hfundecs.end());
+ return i->second;
+ }
+
+ inline ast::FunctionDec*
+ FundecGraph::hfundec_deep_get(ast::FunctionDec* start,
+ ast::FunctionDec* searched) const
+ {
+ if (start == searched)
+ return searched;
+
+ hfundecs_type::const_iterator i = hfundecs.find(start);
+ parentgraph_neighb_iter_type parent =
+ boost::adjacent_vertices(i->second, *this).first;
+
+ if ((*this)[*parent] == start)
+ return nullptr;
+
+ return hfundec_deep_get((*this)[*parent], searched);
+ }
+
+ inline std::ostream& FundecGraph::vertex_print(vertex_descriptor v,
+ std::ostream& ostr) const
+ {
+ return ostr << (*this)[v]->name_get();
+ }
+
+} // namespace callgraph
diff --git a/tiger-compiler/src/callgraph/libcallgraph.cc b/tiger-compiler/src/callgraph/libcallgraph.cc
new file mode 100644
index 0000000..be23b16
--- /dev/null
+++ b/tiger-compiler/src/callgraph/libcallgraph.cc
@@ -0,0 +1,36 @@
+/**
+ ** \file callgraph/libcallgraph.cc
+ ** \brief Define exported callgraph functions.
+ */
+
+#include <callgraph/call-graph-visitor.hh>
+#include <callgraph/libcallgraph.hh>
+#include <callgraph/parent-graph-visitor.hh>
+
+#include <misc/contract.hh>
+#include <misc/set.hh>
+
+namespace callgraph
+{
+
+ // Build the callgraph.
+ const CallGraph* callgraph_compute(const ast::Ast& tree)
+ {
+ CallGraphVisitor callgraph_visitor;
+ return callgraph_visitor.create(tree);
+ }
+
+ CallGraph* callgraph_compute(ast::Ast& tree)
+ {
+ CallGraphVisitor callgraph_visitor;
+ return callgraph_visitor.create(tree);
+ }
+
+ // Build the parentgraph.
+ ParentGraph* parentgraph_compute(ast::Ast& tree)
+ {
+ ParentGraphVisitor parentgraph_visitor;
+ return parentgraph_visitor.create(tree);
+ }
+
+} // namespace callgraph
diff --git a/tiger-compiler/src/callgraph/libcallgraph.hh b/tiger-compiler/src/callgraph/libcallgraph.hh
new file mode 100644
index 0000000..b928bac
--- /dev/null
+++ b/tiger-compiler/src/callgraph/libcallgraph.hh
@@ -0,0 +1,28 @@
+/**
+ ** \file callgraph/libcallgraph.hh
+ ** \brief Declare functions and variables exported by callgraph module.
+ */
+
+#pragma once
+
+#include <ast/fwd.hh>
+#include <callgraph/fundec-graph.hh>
+
+/// Computing static link related information.
+namespace callgraph
+{
+
+#ifdef SWIG
+ %newobject callgraph_compute;
+#endif
+ /// Build the callgraph.
+ const CallGraph* callgraph_compute(const ast::Ast& tree);
+ CallGraph* callgraph_compute(ast::Ast& tree);
+
+#ifdef SWIG
+ %newobject parentgraph_compute;
+#endif
+ /// Build the parentgraph.
+ ParentGraph* parentgraph_compute(ast::Ast& tree);
+
+} // namespace callgraph
diff --git a/tiger-compiler/src/callgraph/local.am b/tiger-compiler/src/callgraph/local.am
new file mode 100644
index 0000000..695075f
--- /dev/null
+++ b/tiger-compiler/src/callgraph/local.am
@@ -0,0 +1,14 @@
+## module callgraph.
+
+# Compiling.
+# Libcallgraph
+src_libtc_la_SOURCES += \
+ %D%/libcallgraph.hh %D%/libcallgraph.cc \
+ %D%/fundec-graph.hh %D%/fundec-graph.hxx \
+ %D%/call-graph-visitor.hh %D%/call-graph-visitor.cc \
+ %D%/parent-graph-visitor.hh %D%/parent-graph-visitor.cc
+
+src_libtc_la_LDFLAGS += $(BOOST_GRAPH_LDFLAGS)
+src_libtc_la_LIBADD += $(BOOST_GRAPH_LIBS)
+
+TASKS += %D%/tasks.hh %D%/tasks.cc
diff --git a/tiger-compiler/src/callgraph/parent-graph-visitor.cc b/tiger-compiler/src/callgraph/parent-graph-visitor.cc
new file mode 100644
index 0000000..f99121d
--- /dev/null
+++ b/tiger-compiler/src/callgraph/parent-graph-visitor.cc
@@ -0,0 +1,42 @@
+/**
+ ** \file callgraph/parent-graph-visitor.cc
+ ** \brief Implementation for callgraph::ParentGraphVisitor.
+ **/
+
+#include <ast/function-dec.hh>
+#include <callgraph/parent-graph-visitor.hh>
+
+namespace callgraph
+{
+ ParentGraph* ParentGraphVisitor::create(ast::Ast& tree)
+ {
+ // Create a new empty parentgraph
+ parentgraph = new ParentGraph();
+
+ // Launch visitor.
+ tree.accept(*this);
+
+ // Return created parentgraph.
+ return parentgraph;
+ }
+
+ void ParentGraphVisitor::operator()(ast::FunctionChunk& e)
+ {
+ for (ast::FunctionDec* f : e)
+ {
+ parentgraph->fundec_add(f);
+ parentgraph->fundec_link(f, parent);
+ }
+ super_type::operator()(e);
+ }
+
+ void ParentGraphVisitor::operator()(ast::FunctionDec& e)
+ {
+ // Current function becomes temporarily the parent function.
+ ast::FunctionDec* tmp = parent;
+ parent = &e;
+ super_type::operator()(e);
+ parent = tmp;
+ }
+
+} // namespace callgraph
diff --git a/tiger-compiler/src/callgraph/parent-graph-visitor.hh b/tiger-compiler/src/callgraph/parent-graph-visitor.hh
new file mode 100644
index 0000000..be16987
--- /dev/null
+++ b/tiger-compiler/src/callgraph/parent-graph-visitor.hh
@@ -0,0 +1,36 @@
+/**
+ ** \file callgraph/parent-graph-visitor.hh
+ ** \brief Definition of callgraph::ParentGraphVisitor.
+ **/
+#pragma once
+
+#include <ast/default-visitor.hh>
+#include <ast/non-assert-visitor.hh>
+#include <ast/non-object-visitor.hh>
+#include <callgraph/fundec-graph.hh>
+
+namespace callgraph
+{
+ /// Compute the ParentGraph.
+ class ParentGraphVisitor
+ : public ast::DefaultVisitor
+ , public ast::NonObjectVisitor
+ , public ast::NonAssertVisitor
+ {
+ using super_type = ast::DefaultVisitor;
+ using super_type::operator();
+
+ public:
+ ParentGraph* create(ast::Ast& tree);
+
+ void operator()(ast::FunctionChunk& e) override;
+ void operator()(ast::FunctionDec& e) override;
+
+ protected:
+ /// Current function.
+ ast::FunctionDec* parent = nullptr;
+ /// Parent graph.
+ ParentGraph* parentgraph = nullptr;
+ };
+
+} // namespace callgraph
diff --git a/tiger-compiler/src/callgraph/tasks.cc b/tiger-compiler/src/callgraph/tasks.cc
new file mode 100644
index 0000000..e4d003b
--- /dev/null
+++ b/tiger-compiler/src/callgraph/tasks.cc
@@ -0,0 +1,52 @@
+/**
+ ** \file callgraph/tasks.cc
+ ** \brief Callgraph module related tasks' implementation.
+ */
+
+#include <ostream>
+
+#include <ast/libast.hh>
+#include <ast/tasks.hh>
+#define DEFINE_TASKS 1
+#include <callgraph/tasks.hh>
+#undef DEFINE_TASKS
+#include <callgraph/libcallgraph.hh>
+
+namespace callgraph::tasks
+{
+ /*------------.
+ | CallGraph. |
+ `------------*/
+
+ static std::unique_ptr<CallGraph> callgraph;
+
+ void callgraph_compute()
+ {
+ callgraph.reset(::callgraph::callgraph_compute(*ast::tasks::the_program));
+ }
+
+ void callgraph_dump()
+ {
+ precondition(callgraph.get());
+ callgraph->print("call");
+ }
+
+ /*--------------.
+ | ParentGraph. |
+ `--------------*/
+
+ static std::unique_ptr<ParentGraph> parentgraph;
+
+ void parentgraph_compute()
+ {
+ parentgraph.reset(
+ ::callgraph::parentgraph_compute(*ast::tasks::the_program));
+ }
+
+ void parentgraph_dump()
+ {
+ precondition(parentgraph.get());
+ parentgraph->print("parent");
+ }
+
+} // namespace callgraph::tasks
diff --git a/tiger-compiler/src/callgraph/tasks.hh b/tiger-compiler/src/callgraph/tasks.hh
new file mode 100644
index 0000000..e1fc584
--- /dev/null
+++ b/tiger-compiler/src/callgraph/tasks.hh
@@ -0,0 +1,46 @@
+/**
+ ** \file callgraph/tasks.hh
+ ** \brief Callgraph module related tasks.
+ */
+
+#pragma once
+
+#include <callgraph/fundec-graph.hh>
+#include <task/libtask.hh>
+
+/// The Tasks of the escapes module.
+namespace callgraph::tasks
+{
+ TASK_GROUP("3. Callgraph");
+
+ /*-------------.
+ | Call graph. |
+ `-------------*/
+
+ /// Build the call graph.
+ TASK_DECLARE("callgraph-compute",
+ "build the call graph",
+ callgraph_compute,
+ "bindings-compute");
+ /// Dump the callgraph.
+ TASK_DECLARE("callgraph-dump",
+ "dump the call graph",
+ callgraph_dump,
+ "callgraph-compute");
+
+ /*---------------.
+ | Parent graph. |
+ `---------------*/
+
+ /// Build the parent graph.
+ TASK_DECLARE("parentgraph-compute",
+ "build the parent graph",
+ parentgraph_compute,
+ "parse");
+ /// Dump the parentgraph.
+ TASK_DECLARE("parentgraph-dump",
+ "dump the parent graph",
+ parentgraph_dump,
+ "parentgraph-compute");
+
+} // namespace callgraph::tasks