On Fri, 2021-06-25 at 20:33 +0530, Ankur Saini wrote: > AIM for today : > > - try to create an intra-procedural link between the calls the calling > and returning snodes > - figure out the program point where exploded graph would know about > the function calls > - figure out how the exploded node will know which function to call > - create enodes and eedges for the calls > > — > > PROGRESS : > > - I created an intraprocedural link between where the the splitting is > happening to connect the call and returning snodes. like this :- > > (in supergraph.cc at "supergraph::supergraph (logger *logger)" ) > ``` > 185 if (cgraph_edge *edge = supergraph_call_edge (fun, stmt)) > 186 { > 187 m_cgraph_edge_to_caller_prev_node.put(edge, > node_for_stmts); > 188 node_for_stmts = add_node (fun, bb, as_a <gcall *> (stmt), > NULL); > 189 m_cgraph_edge_to_caller_next_node.put (edge, > node_for_stmts); > 190 } > 191 else > 192 { > 193 gcall *call = dyn_cast<gcall *> (stmt); > 194 if (call) > 195 { > 196 supernode *old_node_for_stmts = node_for_stmts; > 197 node_for_stmts = add_node (fun, bb, as_a <gcall *> > (stmt), NULL); ^^^^^^^^^^^^^^^^^^^^^ Given the dyn_cast of stmt to gcall * at line 193 you can use "call" here, without the as_a cast, as you've already got "stmt" as a gcall * as tline 193.
You might need to add a hash_map recording the mapping from such stmts to the edges, like line 189 does. I'm not sure, but you may need it later. > 198 > 199 superedge *sedge = new callgraph_superedge > (old_node_for_stmts, > 200 node_for_stmts, > 201 SUPEREDGE_INTRAPROCEDURAL_CALL, > 202 NULL); > 203 add_edge (sedge); > 204 } > 205 } > ``` > > - now that we have a intraprocedural link between such calls, and the > analyzer will consider them as “impossible edge” ( whenever a "node- > >on_edge()” returns false ) while processing worklist, and I think this > should be the correct place to speculate about the function call by > creating exploded nodes and edges representing calls ( maybe by adding > a custom edge info ). > > - after several of failed attempts to do as mentioned above, looks like > I was looking the wrong way all along. I think I just found out what my > mentor meant when telling me to look into "calls node->on_edge”. During > the edge inspection ( in program_point::on_edge() ) , if it’s an > Intraprocedural s sedge, maybe I can add an extra intraprocedural sedge > to the correct edge right here with the info state of that program > point. I don't think we need a superedge for such a call, just an exploded_edge. (Though perhaps adding a superedge might make things easier? I'm not sure, but I'd first try not bothering to add one) > > Q. But even if we find out which function to call, how will the > analyzer know which snode does that function belong ? Use this method of supergraph: supernode *get_node_for_function_entry (function *fun) const; to get the supernode for the entrypoint of a given function. You can get the function * from a fndecl via DECL_STRUCT_FUNCTION. > Q. on line 461 of program-point.cc > > ``` > 457 else > 458 { > 459 /* Otherwise, we ignore these edges */ > 460 if (logger) > 461 logger->log ("rejecting interprocedural edge"); > 462 return false; > 463 } > ``` > why are we rejecting “interprocedural" edge when we are examining an > “intraprocedural” edge ? or is it for the "cg_sedge->m_cedge” edge, > which is an interprocedural edge ? Currently, those interprocedural edges don't do much. Above the "else" clause of the lines above the ones you quote is some support for call summaries. The idea is that we ought to be able to compute summaries of what a function call does, and avoid exponential explosions during the analysis by reusing summaries at a callsite. But that code doesn't work well at the moment; see: https://gcc.gnu.org/bugzilla/showdependencytree.cgi?id=99390 If you ignore call summaries for now, I think you need to change this logic so it detects if we have a function pointer that we "know" the value of from the region_model, and have it generate an exploded_node and exploded_edge for the call. Have a look at how SUPEREDGE_CALL is handled by program_state and program_point; you should implement something similar, I think. Given that you need both the super_edge, point *and* state all together to detect this case, I think the logic you need to add probably needs to be in exploded_node::on_edge as a specialcase before the call there to next_point->on_edge. Hope this is helpful Dave > > STATUS AT THE END OF THE DAY :- > > - try to create an intra-procedural link between the calls the calling > and returning snodes ( Done ) > - figure out the program point where exploded graph would know about > the function calls ( Done ) > - figure out how the exploded node will know which function to call ( > Pending ) > - create enodes and eedges for the calls ( Pending ) > > > Thank you > - Ankur > > > On 25-Jun-2021, at 2:23 AM, David Malcolm <dmalc...@redhat.com> > > wrote: > > > > On Thu, 2021-06-24 at 19:59 +0530, Ankur Saini wrote: > > > CURRENT STATUS : > > > > > > analyzer is now splitting nodes even at call sites which doesn’t > > > have > > > a cgraph_edge. But as now the call and return nodes are not > > > connected, the part of the function after such calls becomes > > > unreachable making them impossible to properly analyse. > > > > > > AIM for today : > > > > > > - try to create an intra-procedural link between the calls the > > > calling and returning snodes > > > - find the place where the exploded nodes and edges are being > > > formed > > > - figure out the program point where exploded graph would know > > > about > > > the function calls > > > > > > — > > > > > > PROGRESS : > > > > > > - I initially tried to connect the calling and returning snodes > > > with > > > an intraprocedural sedge but looks like for that only nodes which > > > have a cgraph_edge or a CFG edge are connected in the supergraph. I > > > tried a few ways to connect them but at the end thought I would be > > > better off leaving them like this and connecting them during the > > > creation of exploded graph itself. > > > > > > - As the exploded graph is created during building and processing > > > of > > > the worklist, "build_initial_worklist ()” and “process_worklist()” > > > should be the interesting areas to analyse, especially the > > > processing > > > part. > > > > > > - “build_initial_worklist()” is just creating enodes for functions > > > that can be called explicitly ( possible entry points ) so I guess > > > the better place to investigate is “process_worklist ()” function. > > > > Yes. > > > > Have a look at exploded_graph::process_node (which is called by > > process_worklist). > > The eedges for calls with supergraph edges happens there in > > the "case PK_AFTER_SUPERNODE:", which looks at the outgoing > > superedges > > from that supernode and calls node->on_edge on them, creating a > > exploded nodes/exploded edge for each outgoing-superedge. > > > > So you'll need to make some changes there, I think. > > > > > > > > — > > > > > > STATUS AT THE END OF THE DAY :- > > > > > > - try to create an intra-procedural link between the calls the > > > calling and returning snodes ( Abandoned ) > > > > You may find the above useful if you're going to do it based on the > > code I mentioned above. > > > > > - find the place where the exploded nodes and edges are being > > > formed > > > ( Done ) > > > - figure out the program point where exploded graph knows about the > > > function call ( Pending ) > > > > > > > Thanks for the update. > > Hope the above is helpful. > > > > Dave >