> On 25-Jun-2021, at 9:04 PM, David Malcolm <dmalc...@redhat.com> wrote: > > 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.
ok > > 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. but the node is being created if there is no cgraph_edge corresponding to the call, so to what edge will I map “node_for_stmts" to ? > > >> 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) ok, will scratch this idea for now. > >> >> 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. so once we get fndecl, it should be comparatively smooth sailing from there. My attempt to get the value of function pointer from the state : - - to access the region model of the state, I tried to access “m_region_model” of that state. - now I want to access cluster for a function pointer. - but when looking at the accessible functions to region model class, I couldn’t seem to find the fitting one. ( the closest I could find was “region_model::get_reachable_svalues()” to get a set of all the svalues reachable from that model ) > >> 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 > <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 Thank you - Ankur