diff options
Diffstat (limited to 'tiger-compiler/src/inlining/inliner.cc')
| -rw-r--r-- | tiger-compiler/src/inlining/inliner.cc | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/tiger-compiler/src/inlining/inliner.cc b/tiger-compiler/src/inlining/inliner.cc new file mode 100644 index 0000000..85bbc88 --- /dev/null +++ b/tiger-compiler/src/inlining/inliner.cc @@ -0,0 +1,64 @@ +/** + ** \file inlining/inliner.cc + ** \brief Implementation of inlining::Inliner. + */ + +#include <boost/graph/transitive_closure.hpp> + +#include <ranges> +#include <callgraph/libcallgraph.hh> +#include <inlining/inliner.hh> +#include <parse/libparse.hh> +#include <parse/tweast.hh> + +namespace inlining +{ + using namespace ast; + + Inliner::Inliner(const ast::Ast& tree) + : super_type() + , rec_funs_() + { + // Compute the transitive closure of the call graph to compute the + // set of recursive functions. + const callgraph::CallGraph* graph = callgraph::callgraph_compute(tree); + callgraph::CallGraph closure; + boost::transitive_closure(*graph, closure); + + // Compute the parent graph to get nested functions. + const callgraph::ParentGraph* parentGraph = + callgraph::parentgraph_compute(const_cast<ast::Ast&>(tree)); + + // Re-attach properties to the vertices. + for (auto [i, i_end] = boost::vertices(closure); i != i_end; ++i) + closure[*i] = (*graph)[*i]; + // Detect recursive functions. + for (auto [i, i_end] = boost::vertices(closure); i != i_end; ++i) + { + for (auto [j, j_end] = boost::adjacent_vertices(*i, closure); + j != j_end; ++j) + { + // Check all parent functions to detect cases like these : + // function a() = + // ( + // let + // function b() = a() + // in + // end + // ) + if (parentGraph->hfundec_deep_get(closure[*i], closure[*j])) + rec_funs_.insert(closure[*j]); + } + } + delete graph; + delete parentGraph; + } + + const misc::set<const ast::FunctionDec*>& Inliner::rec_funs_get() const + { + return rec_funs_; + } + + // FIXME: Some code was deleted here. + +} // namespace inlining |
