/** ** \file inlining/inliner.cc ** \brief Implementation of inlining::Inliner. */ #include #include #include #include #include #include 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(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& Inliner::rec_funs_get() const { return rec_funs_; } // FIXME: Some code was deleted here. } // namespace inlining