> Hi, > > sorry it took me so long, but it also took me quite a while to chew > through. Please consider posting context diff in cases like this. > Nevertheless, most of the patch is a nice improvement.
Uhm, sorry. Seems I diffed from a different users. > > There is cgraph_indirect_call_info that walks GIMPLE code and attempts to > > determine the context of a given call. It looks for objects located in > > declarations (static vars/ automatic vars/parameters), objects passed by > > invisible references and objects passed as THIS pointers. > > The second two cases are new, the first case is already done by > > gimple_extract_devirt_binfo_from_cst > > and I assume we should really put the context there, rather than > reconstructing it from the edge. Of course we must stop overloading > the offset field for that, are there any other obstacles? No, i think overloading of offset is the only obstackle. I just tried to keep the patch self-contained and do not dive into ipa-prop changes - it is long by itself. > > -/* See if BINFO's type match OTR_TYPE. If so, lookup method > > - in vtable of TYPE_BINFO and insert method to NODES array. > > +/* See if BINFO's type match OUTER_TYPE. If so, lookup > > + BINFO of subtype of TYPE at OFFSET and in that BINFO find > > + method in vtable and insert method to NODES array. > > Otherwise recurse to base BINFOs. > > This match what get_binfo_at_offset does, but with offset > > being unknown. > > This function now needs a comprehensive update of the leading comment, > we have the offset, so it is known. I also dislike the name a lot > because it does not record binfo, but extracts and records the call > target from it. Can we call it something like > record_target_from_binfo or similar? OK, record_target_from_binfo works for me. We still do not know full offset (from start of the type being walked) just partial offset within one of bases of the type. But I will try to formulate the comment better - it is indeed result of incremental updates. > > - if (types_same_for_odr (type, otr_type) > > - && !pointer_set_insert (matched_vtables, BINFO_VTABLE (type_binfo))) > > + if (types_same_for_odr (type, outer_type)) > > { > > + tree inner_binfo = get_binfo_at_offset (type_binfo, > > + offset, otr_type); > > OK, get_binfo_at_offset also traverses BINFO_BASEs, I wonder whether > we need to iterate over them and recurse when types_same_for_odr > return false, with offset, won't get_binfo_at_offset just handle both > cases correctly? No, it is the difference I described above. get_binfo_at_offset assume that the offset is from start of the BINFO's type it is given. This is not true here. We have derived_type that has outer_type as a base that has otr_type at offset inside. We do not know the offset in between derived_type and outer_type. This is why one function wraps the other. > > +/* Given REF call in FNDECL, determine class of the polymorphic > > + call (OTR_TYPE), its token (OTR_TOKEN) and CONTEXT. > > + Return pointer to object described by the context */ > > + > > The return value is never used, Is it ever going to be useful? > Especially since it can be NULL even in useful cases... Yes, it is supposed to be used by ipa-prop. We return non-NULL when the base may be PARM_DECL that can be furhter propagated through. > > > > +tree > > +get_polymorphic_call_info (tree fndecl, > > + tree ref, > > + tree *otr_type, > > + HOST_WIDE_INT *otr_token, > > + ipa_polymorphic_call_context *context) > > +{ > > + tree base_pointer; > > + *otr_type = obj_type_ref_class (ref); > > + *otr_token = tree_low_cst (OBJ_TYPE_REF_TOKEN (ref), 1); > > + > > + /* Set up basic info in case we find nothing interesting in the > > analysis. */ > > + context->outer_type = *otr_type; > > + context->offset = 0; > > + base_pointer = OBJ_TYPE_REF_OBJECT (ref); > > + context->maybe_derived_type = true; > > + context->maybe_in_construction = false; > > + > > + /* Walk SSA for outer object. */ > > + do > > + { > > + if (TREE_CODE (base_pointer) == SSA_NAME > > + && !SSA_NAME_IS_DEFAULT_DEF (base_pointer) > > + && SSA_NAME_DEF_STMT (base_pointer) > > + && gimple_assign_single_p (SSA_NAME_DEF_STMT (base_pointer))) > > + { > > + base_pointer = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (base_pointer)); > > + STRIP_NOPS (base_pointer); > > If we want to put the context on the edges, we need to adjust the > offset here. I do not follow here, strip nops should not alter offsets, right? > > + context->offset += offset2; > > + base_pointer = NULL; > > + /* Make very conservative assumption that all objects > > + may be in construction. > > + TODO: ipa-prop already contains code to tell better. > > + merge it later. */ > > + context->maybe_in_construction = true; > > + context->maybe_derived_type = false; > > + return base_pointer; > > Perhaps just return NULL? This is intended to be hooked into your code, but indeed the base_pointer = NULL above is leftover from earlier implementation. > > + If FINALp is non-NULL, store true if the list is complette. > > I'd prefer if finalp was called completep, this way it sounds like it > was dependent on the final keyword, which it isn't. Well, it originally did, but it is no longer the case, I will rename it. Thanks! I will address the comments and update patch. Honza