Re: ipa pta: How did this .arg1 pt set get filled?
Richard Biener via Gcc <[email protected]> Mon, 29 Jun 2026 17:54:49 +0200
| Newsgroups | gmane.comp.gcc.devel |
|---|---|
| Message-ID | <[email protected]> |
> Am 29.06.2026 um 17:25 schrieb Filip Kastl <[email protected]>: > > On Mon 2026-06-29 16:02:25, Richard Biener wrote: >> On Mon, 29 Jun 2026, Filip Kastl wrote: >> >>>> On Mon, 29 Jun 2026, Filip Kastl wrote: >>>>> Ah and one more detail: I'm working with all constraints involving uses and >>>>> clobbers disabled (I don't call >>>>> gimple-ssa-pta-constraints.cc:find_func_clobbers). I'm mentioning that in case >>>>> you'd be confused that some constraints are missing. >>>>> >>>>> But the mystery of why Andersen decides to fill those sets remains. >>>>> >>>>> Filip >>>>> >>>>>> On Mon 2026-06-29 11:57:49, Filip Kastl wrote: >>>>>>> Hi Richi, >>>>>>> >>>>>>> I have another question about PTA that may or may not be related to the last >>>>>>> week's question. >>>>>>> >>>>>>> I'm debugging a difference between what my Steensgaard-style solver and what >>>>>>> GCC's Andersen-style solver compute. In particular on my testcase (gcc_r from >>>>>>> 2017 SPEC CPU) Steensgaard computes these sets... >>>>>>> >>>>>>> ix86_encode_section_info.clobber = { } >>>>>>> ix86_encode_section_info.use = { } >>>>>>> ix86_encode_section_info.result = { } >>>>>>> ix86_encode_section_info.arg0 = { NULL ANYTHING STRING ESCAPED N ... >>>>>>> ix86_encode_section_info.arg1 = { NULL ANYTHING STRING ESCAPED N ... >>>>>>> ix86_encode_section_info.arg2 = { } >>>>>>> >>>>>>> ...while Steensgaard computes this: >>>>>>> >>>>>>> ix86_encode_section_info.clobber = { NULL ANYTHING p p } >>>>>>> ix86_encode_section_info.use = { NULL ANYTHING p p } >>>>>>> ix86_encode_section_info.result = { NULL ANYTHING p p } >>>>>>> ix86_encode_section_info.arg0 = { NULL ANYTHING p p } >>>>>>> ix86_encode_section_info.arg1 = { NULL ANYTHING p p } >>>>>>> ix86_encode_section_info.arg2 = { NULL ANYTHING p p } >>>>>>> >>>>>>> To figure out how Andersen arrived at these sets I searched the IPA PTA dump >>>>>>> for constraints involving ix86_encode_section_info*. I found only these... >>>>> >>>>> It's been some time since I had the Andersen code swapped in my brain, >>>>> so please bear with me eventually giving false hints ... >>>>> >>>>>>> Generating constraints for ix86_encode_section_info/332 (ix86_encode_section_info) >>>>>>> _18 = *ix86_encode_section_info.arg1 >>>>>>> _19 = *ix86_encode_section_info.arg1 + 64 >>>>>>> _24 = *ix86_encode_section_info.arg0 >>>>>>> *_26 + 5 = ix86_encode_section_info.arg0 >>>>>>> _30 = *ix86_encode_section_info.arg0 >>>>>>> _31 = *ix86_encode_section_info.arg0 + 1165 >>>>>>> _32 = *ix86_encode_section_info.arg0 + 1160 >>>>>>> *_38 + 5 = ix86_encode_section_info.arg0 >>>>>>> _41 = *ix86_encode_section_info.arg0 >>>>>>> _44 = *ix86_encode_section_info.arg0 + 472 >>>>>>> _46 = *ix86_encode_section_info.arg0 + 24 >>>>>>> _1 = *ix86_encode_section_info.arg0 >>>>>>> _2 = *ix86_encode_section_info.arg0 + 24 >>>>>>> _4 = *ix86_encode_section_info.arg0 + 472 >>>>>>> _55 = *ix86_encode_section_info.arg0 >>>>>>> _56 = *ix86_encode_section_info.arg0 + 1024 >>>>>>> _60 = *ix86_encode_section_info.arg0 + 128 >>>>>>> _17 = *ix86_encode_section_info.arg1 + 64 >>>>>>> >>>>>>> ...which is strange. I don't see any assigning into ix86_encode_section_info* >>>>>>> nor assigning &ix86_encode_section_info* into any other set. Shouldn't then >>>>>>> Andersen compute empty sets for all of these? (Although it is a good thing >>>>>>> that Andersen fills those sets. Otherwise, there would be a miscompilation. >>>>>>> I just want to understand what is it that my solver fails to do here.) >>>>> >>>>> There must be call sites of ix86_encode_section_info/332 and I'd expect >>>>> those to have constraints like >>>>> >>>>> ix86_encode_section_info.arg0 = ... >>> >>> I don't see any constraints like this. But since the function only gets called >>> indirectly, that makes sense to me. >>> >>>> &ix86_encode_section_info itself would appear when the function is only >>>> called indirectly ... >>>> >>>>>> First explanation I came up with was expanding of ix86_encode_section_info (the >>>>>> fninfo) using '+ UNKNOWN' that we discussed last week. But >>>>>> ix86_encode_section_info is not present in any constraint at all so it cannot >>>>>> be present in any pt set and therefore it cannot get expanded this way. >>>>>> >>>>>> Note that ix86_encode_section_info is only ever called indirectly through a >>>>>> function pointer targetm.encode_section_info. That may be relevant here, I >>>>>> think. >>>> >>>> ... as you say here. It might be only visible when creating >>>> constraints for the targem initializer (a global). >>> >>> Not sure what you mean by this sentence ^. Could you expand on this a bit? >> >> targetm is initialized from >> >> struct gcc_target targetm = TARGET_INITIALIZER; >> >> in config/*/*.cc >> >> constraints for that are generated by ipa_create_global_variable_infos, >> so you should see >> >> targetm[ + N] = ... >> >> in the 'Generating constraints for global initializers' section. > > Alright, makes sense. I see... > > targetm = NONLOCAL > targetm = &ANYTHING > > ...so I believe that targetm is too big for field sensitivity. > >>>> We might end up >>>> with just feeding that from NONLOCAL and thus you'd get ESCAPED >>>> at uses and ix86_encode_section_info should be escaped? >>> >>> Hm, doesn't look like ix86_encode_section_info escaped though: >>> >>> ESCAPED = { NULL ANYTHING STRING ESCAPED NONLOCAL output_object_block_htab const_desc_eq assemble_real.arg0 mark_constant object_block_entry_hash gt_pch_p_P23constant_descriptor_rtx4htab gt_pch_p_17rtx_constant_pool const_rtx_hash_1 section_entry_eq emutls_common_1 const_desc_rtx_eq section_entry_hash gt_pch_p_23constant_descriptor_rtx compute_reloc_for_rtx_1 const_desc_rtx_hash const_desc_hash object_block_entry_eq build_int_cst_wide_type.arg1 build_int_cst_wide_type.arg2 type_hash_eq gt_pch_p_P9type_hash4htab gt_pch_p_9type_hash cl_option_hash_eq cl_option_hash_hash type_hash_hash tree_map_hash tree_map_base_hash tree_map_base_eq int_cst_hash_eq int_cst_hash_hash gt_pch_p_17stack_local_entry ix86_init_machine_status extended_reg_mentioned_1 get_some_local_dynamic_name_1 dconst0 dconsthalf dconstm1 internal_label_prefix optab_table dconst1 isa_other target_other name name label tmp_label key.0+64 key.0+64 buf buf buffer x reloc flagchars ggc_calloc ggc_free in.0+64 label tmp.0+64 >> x h label data body in.0+64 lhd_dwarf_name gimple_decl_printable_name lhd_set_decl_assembler_name gimple_fold_obj_type_ref mode_name_buf D.16879.0+64 D.16880.0+64 dc p code code precision in.0+64 in.0+64 in.0+64 in.0+64 in.0+64 in.0+64 in in p low1 hi d.0+32 TWO52r.0+32 half_minus_pred_half.0+32 pred_half.0+32 TWO52r.0+32 TWO52r.0+32 TWO52r.0+32 TWO52r.0+32 TWO52r.0+32 TWO52r.0+32 half_minus_pred_half.0+32 pred_half.0+32 r.0+32 inf.0+32 words use r.0+32 dstr dstr ONE16r.0+32 TWO31r.0+32 r.0+32 l xops xops name r.0+32 cur_target rperm rperm rperm rperm name xops rperm buf name } same as lookup_constant_def.result >>> >>> In fact, I don't see ix86_encode_section_info in any PT set in the dump. >> >> Do you see targetm? I suppose it's too large for field-sensitivity, >> but still. > > In the other mail, you note that there is ANYTHING inside the ESCAPE set. That > got me thinking -- maybe ANYTHING (or some similar special variable) is > involved in the filling of ix86_encode_section_info.arg1? Through GDB, I've > also discovered that the filling happens because there is an edge in the > Andersen graph from STOREDANYTHING to ix86_encode_section_info.arg1. I don't > yet understand what STOREDANYTHING is used for but I've noticed that the > Steensgaard solver outputs... > > STOREDANYTHING = { } > > ...while the Andersen solver outputs > > STOREDANYTHING = { NULL ANYTHING ... > > And once again, I don't see any constraints involving STOREDANYTHING. That's > explained by this code from pta-andersen.cc: > > /* Add edges from STOREDANYTHING to all nodes that can receive pointers. */ > t = find (storedanything_id); > for (i = integer_id + 1; i < FIRST_REF_NODE; ++i) > { > if (get_varinfo (i)->may_have_pointers) > add_graph_edge (graph, find (i), t); > } > > Andersen adds edges that aren't based on any constraints and I didn't know > about this while writing Steensgaard. > > Maybe this explains why ix86_encode_section_info.arg1 gets filled by Andersen > and not by Steensgaard. I'll have to look into what STOREDANYTHING is and > think about this. It is when ANYTHING is on the LHS. Above means you have a *ANYTHING = ANYTHING constraint which is pretty bad quality wise. We don’t want to explicitly manage edges for this case (and we failed to, before I introduced STOREDANYTHING) Richard > > Thanks for the hints, > Filip