> On 25-Jun-2021, at 9:04 PM, David Malcolm <[email protected]> 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