mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			re PR rtl-optimization/10474 (shrink wrapping for functions)
2013-10-30 Martin Jambor <mjambor@suse.cz> PR rtl-optimization/10474 * ira.c (find_moveable_pseudos): Do not calculate dominance info nor df analysis. (interesting_dest_for_shprep): New function. (split_live_ranges_for_shrink_wrap): Likewise. (ira): Calculate dominance info and df analysis. Call split_live_ranges_for_shrink_wrap. testsuite/ * gcc.dg/pr10474.c: New testcase. * gcc.dg/ira-shrinkwrap-prep-1.c: Likewise. * gcc.dg/ira-shrinkwrap-prep-2.c: Likewise. From-SVN: r204205
This commit is contained in:
		
							parent
							
								
									55ebf58738
								
							
						
					
					
						commit
						eb1474c1a2
					
				|  | @ -1,3 +1,13 @@ | |||
| 2013-10-30  Martin Jambor  <mjambor@suse.cz> | ||||
| 
 | ||||
| 	PR rtl-optimization/10474 | ||||
| 	* ira.c (find_moveable_pseudos): Do not calculate dominance info | ||||
| 	nor df analysis. | ||||
| 	(interesting_dest_for_shprep): New function. | ||||
| 	(split_live_ranges_for_shrink_wrap): Likewise. | ||||
| 	(ira): Calculate dominance info and df analysis. Call | ||||
| 	split_live_ranges_for_shrink_wrap. | ||||
| 
 | ||||
| 2013-10-30  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com> | ||||
| 
 | ||||
| 	PR target/58854 | ||||
|  |  | |||
							
								
								
									
										205
									
								
								gcc/ira.c
								
								
								
								
							
							
						
						
									
										205
									
								
								gcc/ira.c
								
								
								
								
							|  | @ -3993,9 +3993,6 @@ find_moveable_pseudos (void) | |||
|   pseudo_replaced_reg.release (); | ||||
|   pseudo_replaced_reg.safe_grow_cleared (max_regs); | ||||
| 
 | ||||
|   df_analyze (); | ||||
|   calculate_dominance_info (CDI_DOMINATORS); | ||||
| 
 | ||||
|   i = 0; | ||||
|   bitmap_initialize (&live, 0); | ||||
|   bitmap_initialize (&used, 0); | ||||
|  | @ -4315,7 +4312,196 @@ find_moveable_pseudos (void) | |||
|   regstat_free_ri (); | ||||
|   regstat_init_n_sets_and_refs (); | ||||
|   regstat_compute_ri (); | ||||
|   free_dominance_info (CDI_DOMINATORS); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* If insn is interesting for parameter range-splitting shring-wrapping
 | ||||
|    preparation, i.e. it is a single set from a hard register to a pseudo, which | ||||
|    is live at CALL_DOM, return the destination.  Otherwise return NULL.  */ | ||||
| 
 | ||||
| static rtx | ||||
| interesting_dest_for_shprep (rtx insn, basic_block call_dom) | ||||
| { | ||||
|   rtx set = single_set (insn); | ||||
|   if (!set) | ||||
|     return NULL; | ||||
|   rtx src = SET_SRC (set); | ||||
|   rtx dest = SET_DEST (set); | ||||
|   if (!REG_P (src) || !HARD_REGISTER_P (src) | ||||
|       || !REG_P (dest) || HARD_REGISTER_P (dest) | ||||
|       || (call_dom && !bitmap_bit_p (df_get_live_in (call_dom), REGNO (dest)))) | ||||
|     return NULL; | ||||
|   return dest; | ||||
| } | ||||
| 
 | ||||
| /* Split live ranges of pseudos that are loaded from hard registers in the
 | ||||
|    first BB in a BB that dominates all non-sibling call if such a BB can be | ||||
|    found and is not in a loop.  Return true if the function has made any | ||||
|    changes.  */ | ||||
| 
 | ||||
| static bool | ||||
| split_live_ranges_for_shrink_wrap (void) | ||||
| { | ||||
|   basic_block bb, call_dom = NULL; | ||||
|   basic_block first = single_succ (ENTRY_BLOCK_PTR); | ||||
|   rtx insn, last_interesting_insn = NULL; | ||||
|   bitmap_head need_new, reachable; | ||||
|   vec<basic_block> queue; | ||||
| 
 | ||||
|   if (!flag_shrink_wrap) | ||||
|     return false; | ||||
| 
 | ||||
|   bitmap_initialize (&need_new, 0); | ||||
|   bitmap_initialize (&reachable, 0); | ||||
|   queue.create (n_basic_blocks); | ||||
| 
 | ||||
|   FOR_EACH_BB (bb) | ||||
|     FOR_BB_INSNS (bb, insn) | ||||
|       if (CALL_P (insn) && !SIBLING_CALL_P (insn)) | ||||
| 	{ | ||||
| 	  if (bb == first) | ||||
| 	    { | ||||
| 	      bitmap_clear (&need_new); | ||||
| 	      bitmap_clear (&reachable); | ||||
| 	      queue.release (); | ||||
| 	      return false; | ||||
| 	    } | ||||
| 
 | ||||
| 	  bitmap_set_bit (&need_new, bb->index); | ||||
| 	  bitmap_set_bit (&reachable, bb->index); | ||||
| 	  queue.quick_push (bb); | ||||
| 	  break; | ||||
| 	} | ||||
| 
 | ||||
|   if (queue.is_empty ()) | ||||
|     { | ||||
|       bitmap_clear (&need_new); | ||||
|       bitmap_clear (&reachable); | ||||
|       queue.release (); | ||||
|       return false; | ||||
|     } | ||||
| 
 | ||||
|   while (!queue.is_empty ()) | ||||
|     { | ||||
|       edge e; | ||||
|       edge_iterator ei; | ||||
| 
 | ||||
|       bb = queue.pop (); | ||||
|       FOR_EACH_EDGE (e, ei, bb->succs) | ||||
| 	if (e->dest != EXIT_BLOCK_PTR | ||||
| 	    && bitmap_set_bit (&reachable, e->dest->index)) | ||||
| 	  queue.quick_push (e->dest); | ||||
|     } | ||||
|   queue.release (); | ||||
| 
 | ||||
|   FOR_BB_INSNS (first, insn) | ||||
|     { | ||||
|       rtx dest = interesting_dest_for_shprep (insn, NULL); | ||||
|       if (!dest) | ||||
| 	continue; | ||||
| 
 | ||||
|       if (DF_REG_DEF_COUNT (REGNO (dest)) > 1) | ||||
| 	{ | ||||
| 	  bitmap_clear (&need_new); | ||||
| 	  bitmap_clear (&reachable); | ||||
| 	  return false; | ||||
| 	} | ||||
| 
 | ||||
|       for (df_ref use = DF_REG_USE_CHAIN (REGNO(dest)); | ||||
| 	   use; | ||||
| 	   use = DF_REF_NEXT_REG (use)) | ||||
| 	{ | ||||
| 	  if (NONDEBUG_INSN_P (DF_REF_INSN (use)) | ||||
| 	      && GET_CODE (DF_REF_REG (use)) == SUBREG) | ||||
| 	    { | ||||
| 	      /* This is necessary to avoid hitting an assert at
 | ||||
| 		 postreload.c:2294 in libstc++ testcases on x86_64-linux.  I'm | ||||
| 		 not really sure what the probblem actually is there.  */ | ||||
| 	      bitmap_clear (&need_new); | ||||
| 	      bitmap_clear (&reachable); | ||||
| 	      return false; | ||||
| 	    } | ||||
| 
 | ||||
| 	  int ubbi = DF_REF_BB (use)->index; | ||||
| 	  if (bitmap_bit_p (&reachable, ubbi)) | ||||
| 	    bitmap_set_bit (&need_new, ubbi); | ||||
| 	} | ||||
|       last_interesting_insn = insn; | ||||
|     } | ||||
| 
 | ||||
|   bitmap_clear (&reachable); | ||||
|   if (!last_interesting_insn) | ||||
|     { | ||||
|       bitmap_clear (&need_new); | ||||
|       return false; | ||||
|     } | ||||
| 
 | ||||
|   call_dom = nearest_common_dominator_for_set (CDI_DOMINATORS, &need_new); | ||||
|   bitmap_clear (&need_new); | ||||
|   if (call_dom == first) | ||||
|     return false; | ||||
| 
 | ||||
|   loop_optimizer_init (AVOID_CFG_MODIFICATIONS); | ||||
|   while (bb_loop_depth (call_dom) > 0) | ||||
|     call_dom = get_immediate_dominator (CDI_DOMINATORS, call_dom); | ||||
|   loop_optimizer_finalize (); | ||||
| 
 | ||||
|   if (call_dom == first) | ||||
|     return false; | ||||
| 
 | ||||
|   calculate_dominance_info (CDI_POST_DOMINATORS); | ||||
|   if (dominated_by_p (CDI_POST_DOMINATORS, first, call_dom)) | ||||
|     { | ||||
|       free_dominance_info (CDI_POST_DOMINATORS); | ||||
|       return false; | ||||
|     } | ||||
|   free_dominance_info (CDI_POST_DOMINATORS); | ||||
| 
 | ||||
|   if (dump_file) | ||||
|     fprintf (dump_file, "Will split live ranges of parameters at BB %i\n", | ||||
| 	     call_dom->index); | ||||
| 
 | ||||
|   bool ret = false; | ||||
|   FOR_BB_INSNS (first, insn) | ||||
|     { | ||||
|       rtx dest = interesting_dest_for_shprep (insn, call_dom); | ||||
|       if (!dest) | ||||
| 	continue; | ||||
| 
 | ||||
|       rtx newreg = NULL_RTX; | ||||
|       df_ref use, next; | ||||
|       for (use = DF_REG_USE_CHAIN (REGNO(dest)); use; use = next) | ||||
| 	{ | ||||
| 	  rtx uin = DF_REF_INSN (use); | ||||
| 	  next = DF_REF_NEXT_REG (use); | ||||
| 
 | ||||
| 	  basic_block ubb = BLOCK_FOR_INSN (uin); | ||||
| 	  if (ubb == call_dom | ||||
| 	      || dominated_by_p (CDI_DOMINATORS, ubb, call_dom)) | ||||
| 	    { | ||||
| 	      if (!newreg) | ||||
| 		newreg = ira_create_new_reg (dest); | ||||
| 	      validate_change (uin, DF_REF_LOC (use), newreg, true); | ||||
| 	    } | ||||
| 	} | ||||
| 
 | ||||
|       if (newreg) | ||||
| 	{ | ||||
| 	  rtx new_move = gen_move_insn (newreg, dest); | ||||
| 	  emit_insn_after (new_move, bb_note (call_dom)); | ||||
| 	  if (dump_file) | ||||
| 	    { | ||||
| 	      fprintf (dump_file, "Split live-range of register "); | ||||
| 	      print_rtl_single (dump_file, dest); | ||||
| 	    } | ||||
| 	  ret = true; | ||||
| 	} | ||||
| 
 | ||||
|       if (insn == last_interesting_insn) | ||||
| 	break; | ||||
|     } | ||||
|   apply_change_group (); | ||||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| /* Perform the second half of the transformation started in
 | ||||
|  | @ -4526,7 +4712,16 @@ ira (FILE *f) | |||
|      allocation because of -O0 usage or because the function is too | ||||
|      big.  */ | ||||
|   if (ira_conflicts_p) | ||||
|     find_moveable_pseudos (); | ||||
|     { | ||||
|       df_analyze (); | ||||
|       calculate_dominance_info (CDI_DOMINATORS); | ||||
| 
 | ||||
|       find_moveable_pseudos (); | ||||
|       if (split_live_ranges_for_shrink_wrap ()) | ||||
| 	df_analyze (); | ||||
| 
 | ||||
|       free_dominance_info (CDI_DOMINATORS); | ||||
|     } | ||||
| 
 | ||||
|   max_regno_before_ira = max_reg_num (); | ||||
|   ira_setup_eliminable_regset (true); | ||||
|  |  | |||
|  | @ -1,3 +1,10 @@ | |||
| 2013-10-30  Martin Jambor  <mjambor@suse.cz> | ||||
| 
 | ||||
| 	PR rtl-optimization/10474 | ||||
| 	* gcc.dg/pr10474.c: New testcase. | ||||
| 	* gcc.dg/ira-shrinkwrap-prep-1.c: Likewise. | ||||
| 	* gcc.dg/ira-shrinkwrap-prep-2.c: Likewise. | ||||
| 
 | ||||
| 2013-10-29  Andrew Pinski <apinski@cavium.com> | ||||
|             Zhenqiang Chen  <zhenqiang.chen@linaro.org> | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,31 @@ | |||
| /* { dg-do compile } */ | ||||
| /* { dg-options "-O3 -fdump-rtl-ira -fdump-rtl-pro_and_epilogue"  } */ | ||||
| 
 | ||||
| int __attribute__((noinline, noclone)) | ||||
| foo (int a) | ||||
| { | ||||
|   return a + 5; | ||||
| } | ||||
| 
 | ||||
| static int g; | ||||
| 
 | ||||
| int __attribute__((noinline, noclone)) | ||||
| bar (int a) | ||||
| { | ||||
|   int r; | ||||
| 
 | ||||
|   if (a) | ||||
|     { | ||||
|       r = foo (a); | ||||
|       g = r + a; | ||||
|     } | ||||
|   else | ||||
|     r = a+1; | ||||
|   return r; | ||||
| } | ||||
| 
 | ||||
| /* { dg-final { scan-rtl-dump "Will split live ranges of parameters" "ira"  } } */ | ||||
| /* { dg-final { scan-rtl-dump "Split live-range of register" "ira"  } } */ | ||||
| /* { dg-final { scan-rtl-dump "Performing shrink-wrapping" "pro_and_epilogue"  } } */ | ||||
| /* { dg-final { cleanup-rtl-dump "ira" } } */ | ||||
| /* { dg-final { cleanup-rtl-dump "pro_and_epilogue" } } */ | ||||
|  | @ -0,0 +1,36 @@ | |||
| /* { dg-do compile } */ | ||||
| /* { dg-options "-O3 -fdump-rtl-ira -fdump-rtl-pro_and_epilogue"  } */ | ||||
| 
 | ||||
| int __attribute__((noinline, noclone)) | ||||
| foo (int a) | ||||
| { | ||||
|   return a + 5; | ||||
| } | ||||
| 
 | ||||
| static int g; | ||||
| 
 | ||||
| int __attribute__((noinline, noclone)) | ||||
| bar (int a) | ||||
| { | ||||
|   int r; | ||||
| 
 | ||||
|   if (a) | ||||
|     { | ||||
|       r = a; | ||||
|       while (r < 500) | ||||
| 	if (r % 2) | ||||
| 	  r = foo (r); | ||||
| 	else | ||||
| 	  r = foo (r+1); | ||||
|       g = r + a; | ||||
|     } | ||||
|   else | ||||
|     r = g+1; | ||||
|   return r; | ||||
| } | ||||
| 
 | ||||
| /* { dg-final { scan-rtl-dump "Will split live ranges of parameters" "ira"  } } */ | ||||
| /* { dg-final { scan-rtl-dump "Split live-range of register" "ira"  } } */ | ||||
| /* { dg-final { scan-rtl-dump "Performing shrink-wrapping" "pro_and_epilogue"  } } */ | ||||
| /* { dg-final { cleanup-rtl-dump "ira" } } */ | ||||
| /* { dg-final { cleanup-rtl-dump "pro_and_epilogue" } } */ | ||||
|  | @ -0,0 +1,16 @@ | |||
| /* { dg-do compile } */ | ||||
| /* { dg-options "-O3 -fdump-rtl-pro_and_epilogue"  } */ | ||||
| 
 | ||||
| void f(int *i) | ||||
| { | ||||
| 	if (!i) | ||||
| 		return; | ||||
| 	else | ||||
| 	{ | ||||
| 		__builtin_printf("Hi"); | ||||
| 		*i=0; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /* { dg-final { scan-rtl-dump "Performing shrink-wrapping" "pro_and_epilogue"  } } */ | ||||
| /* { dg-final { cleanup-rtl-dump "pro_and_epilogue" } } */ | ||||
		Loading…
	
		Reference in New Issue
	
	 Martin Jambor
						Martin Jambor