On Fri, Oct 16, 2020 at 9:59 PM Gary Oblock via Gcc <gcc@gcc.gnu.org> wrote:
>
> I have a tiny program composed of a few functions
> and one of those functions (setupB) has gone missing.
> Since I need to walk its GIMPLE, this is a problem.
>
> The program:
>
> -- aux.h -----------------------------------------
> #include "stdlib.h"
> typedef struct A A_t;
> typedef struct A B_t;
> struct A {
>   int i;
>   double x;
> };
>
> #define MAX(x,y) ((x)>(y) ? (x) : (y))
>
> extern int max1( A_t *, size_t);
> extern double max2( B_t *, size_t);
> extern A_t *setupA( size_t);
> extern B_t *setupB( size_t);
> -- aux.c ----------------------------------------
> #include "aux.h"
> #include "stdlib.h"
>
> A_t *
> setupA( size_t size)
> {
>   A_t *data = (A_t *)malloc( size * sizeof(A_t));
>   size_t i;
>   for( i = 0; i < size; i++ ) {
>     data[i].i = rand();
>     data[i].x = drand48();
>   }
>   return data;
> }
>
> B_t *
> setupB( size_t size)
> {
>   B_t *data = (B_t *)malloc( size * sizeof(B_t));
>   size_t i;
>   for( i = 0; i < size; i++ ) {
>     data[i].i = rand();
>     data[i].x = drand48();
>   }
>   return data;
> }
>
> int
> max1( A_t *array, size_t len)
> {
>   size_t i;
>   int result = array[0].i;
>   for( i = 1; i < len; i++  ) {
>     result = MAX( array[i].i, result);
>   }
>   return result;
> }
>
> double
> max2( B_t *array, size_t len)
> {
>   size_t i;
>   double result = array[0].x;
>   for( i = 1; i < len; i++  ) {
>     result = MAX( array[i].x, result);
>   }
>   return result;
> }
> -- main.c -------------------------------------
> #include "stdio.h"
>
> A_t *data1;
>
> int
> main(void)
> {
>   B_t *data2 = setupB(200);
>   data1 = setupA(100);
>
>   printf("First %d\n" , max1(data1,100));
>   printf("Second %e\n", max2(data2,200));
> }
> ------------------------------------------------
>
> Here is its GIMPLE dump:
> (for the sole purpose of letting you see
> with your own eyes that setupB is indeed missing)
> ------------------------------------------------
> Program:
>   static struct A_t * data1;
> struct A_t * <T623> (size_t)
>
> ;; Function setupA (setupA, funcdef_no=4, decl_uid=4398, cgraph_uid=6, 
> symbol_order=48) (executed once)
>
> setupA (size_t size)
> {
>   size_t i;
>   struct A_t * data;
>
>   <bb 2> [local count: 118111600]:
>   _1 = size_8(D) * 16;
>   data_11 = malloc (_1);
>   goto <bb 4>; [100.00%]
>
>   <bb 3> [local count: 955630225]:
>   _2 = i_6 * 16;
>   _3 = data_11 + _2;
>   _4 = rand ();
>   _3->i = _4;
>   _5 = drand48 ();
>   _3->x = _5;
>   i_16 = i_6 + 1;
>
>   <bb 4> [local count: 1073741824]:
>   # i_6 = PHI <0(2), i_16(3)>
>   if (i_6 < size_8(D))
>     goto <bb 3>; [89.00%]
>   else
>     goto <bb 5>; [11.00%]
>
>   <bb 5> [local count: 118111600]:
>   return data_11;
>
> }
>
>
> int <T622> (struct A_t *)
>
> ;; Function max1.constprop (max1.constprop.0, funcdef_no=1, decl_uid=4397, 
> cgraph_uid=5, symbol_order=58) (executed once)
>
> max1.constprop (struct A_t * array)
> {
>   size_t i;
>   int result;
>   size_t len;
>
>   <bb 6> [local count: 118111600]:
>
>   <bb 2> [local count: 118111600]:
>   result_2 = array_1(D)->i;
>   goto <bb 4>; [100.00%]
>
>   <bb 3> [local count: 955630225]:
>   _4 = i_3 * 16;
>   _5 = array_1(D) + _4;
>   _6 = _5->i;
>   result_8 = MAX_EXPR <_6, result_7>;
>   i_9 = i_3 + 1;
>
>   <bb 4> [local count: 1073741824]:
>   # i_3 = PHI <1(2), i_9(3)>
>   # result_7 = PHI <result_2(2), result_8(3)>
>   if (i_3 <= 99)
>     goto <bb 3>; [89.00%]
>   else
>     goto <bb 5>; [11.00%]
>
>   <bb 5> [local count: 118111600]:
>   # result_10 = PHI <result_7(4)>
>   return result_10;
>
> }
>
>
> double <T61e> (struct B_t *)
>
> ;; Function max2.constprop (max2.constprop.0, funcdef_no=3, decl_uid=4395, 
> cgraph_uid=3, symbol_order=59) (executed once)
>
> max2.constprop (struct B_t * array)
> {
>   size_t i;
>   double result;
>   size_t len;
>
>   <bb 8> [local count: 118111600]:
>
>   <bb 2> [local count: 118111600]:
>   result_2 = array_1(D)->x;
>   goto <bb 6>; [100.00%]
>
>   <bb 3> [local count: 955630225]:
>   _4 = i_3 * 16;
>   _5 = array_1(D) + _4;
>   _6 = _5->x;
>   if (_6 > result_7)
>     goto <bb 4>; [50.00%]
>   else
>     goto <bb 5>; [50.00%]
>
>   <bb 4> [local count: 477815112]:
>
>   <bb 5> [local count: 955630225]:
>   # _10 = PHI <result_7(3), _6(4)>
>   i_8 = i_3 + 1;
>
>   <bb 6> [local count: 1073741824]:
>   # i_3 = PHI <1(2), i_8(5)>
>   # result_7 = PHI <result_2(2), _10(5)>
>   if (i_3 <= 199)
>     goto <bb 3>; [89.00%]
>   else
>     goto <bb 7>; [11.00%]
>
>   <bb 7> [local count: 118111600]:
>   # result_9 = PHI <result_7(6)>
>   return result_9;
>
> }
>
>
> int <T619> (void)
>
> ;; Function main (main, funcdef_no=5, decl_uid=4392, cgraph_uid=1, 
> symbol_order=25) (executed once)
>
> main ()
> {
>   struct B_t * data2;
>
>   <bb 2> [local count: 1073741824]:
>   data2_6 = setupB (200);
>   _1 = setupA (100);
>   data1 = _1;
>   _2 = max1 (_1, 100);
>   printf ("First %d\n", _2);
>   _3 = max2 (data2_6, 200);
>   printf ("Second %e\n", _3);
>   return 0;
>
> }
> ------------------------------------------------
> The pass is invoked at this location in passes.def
>
>   /* Simple IPA passes executed after the regular passes.  In WHOPR mode the
>      passes are executed after partitioning and thus see just parts of the
>      compiled unit.  */
>   INSERT_PASSES_AFTER (all_late_ipa_passes)
>   NEXT_PASS (pass_materialize_all_clones);
>   NEXT_PASS (pass_ipa_type_escape_analysis);
>   NEXT_PASS (pass_ipa_structure_reorg); <========== my pass!
>   NEXT_PASS (pass_ipa_prototype);
>   NEXT_PASS (pass_ipa_pta);
>   NEXT_PASS (pass_omp_simd_clone);
>   TERMINATE_PASS_LIST (all_late_ipa_passes)
>
> --------------------------------------------------------------------------
> The program was compiled with these options:
>
> export OPTIONS='-O2 -fdump-passes -flto -flto-partition=one 
> -fipa-instance-interleave -fdump-ipa-all-details -save-temps -v'
>
> By the way, changing -flto-partition=one to -flto-partition=none
> makes no difference.
>
> ---------------------------------------------------------------------------
> Here is how the dump was done:
>
> void
> print_program ( FILE *file, bool my_format, int leading_space, Info_t *info)
> {
>   struct cgraph_node *node;
>   fprintf ( file, "%*sProgram:\n", leading_space, "");
>
>   // Print Global Decls
>   //
>   varpool_node *var;
>   FOR_EACH_VARIABLE ( var)
>   {
>     tree decl = var->decl;
>     fprintf ( file, "%*s", leading_space, "");
>     flexible_print ( file, decl, 1, (dump_flags_t)0);
>   }
>
>   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node)
>   {
>     struct function *func = DECL_STRUCT_FUNCTION ( node->decl);
>     flexible_print ( file, TREE_TYPE( func->decl), 1, (dump_flags_t)0);
>     dump_function_header ( file, func->decl, (dump_flags_t)0);
>     dump_function_to_file ( func->decl, file, (dump_flags_t)0);
>   }
> }
>
> Note, flexible_print is a wrapper that calls either print_generic_decl
> or print_generic_expr depending on whether or not it's a decl. The "1"
> just causes a "\n" to be emmited...
>
> I also should mention I spin through the following loop at the
> start of my pass to make sure the functions are sane:
>
>   cgraph_node* node;
>   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY ( node)
>     node->get_untransformed_body ();
>
> I don't think I left out any pertinent details.
>
> Any suggestions (other than don't use lto this way)
> are welcome.

Try -fno-ipa-icf - it looks like setupA and setupB are
identical.  You'll see adjusted calls only after IPA
transform.

Richard.

> Thanks,
>
> Gary
>
>
>
>
> CONFIDENTIALITY NOTICE: This e-mail message, including any attachments, is 
> for the sole use of the intended recipient(s) and contains information that 
> is confidential and proprietary to Ampere Computing or its subsidiaries. It 
> is to be used solely for the purpose of furthering the parties' business 
> relationship. Any unauthorized review, copying, or distribution of this email 
> (or any attachments thereto) is strictly prohibited. If you are not the 
> intended recipient, please contact the sender immediately and permanently 
> delete the original and any copies of this email and any attachments thereto.

Reply via email to