xref: /dflybsd-src/contrib/gcc-8.0/gcc/gcse-common.c (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj /* Shared code for before and after reload gcse implementations.
2*38fd1498Szrj    Copyright (C) 1997-2018 Free Software Foundation, Inc.
3*38fd1498Szrj 
4*38fd1498Szrj    This file is part of GCC.
5*38fd1498Szrj 
6*38fd1498Szrj    GCC is free software; you can redistribute it and/or modify it under
7*38fd1498Szrj    the terms of the GNU General Public License as published by the Free
8*38fd1498Szrj    Software Foundation; either version 3, or (at your option) any later
9*38fd1498Szrj    version.
10*38fd1498Szrj 
11*38fd1498Szrj    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12*38fd1498Szrj    WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*38fd1498Szrj    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14*38fd1498Szrj    for more details.
15*38fd1498Szrj 
16*38fd1498Szrj    You should have received a copy of the GNU General Public License
17*38fd1498Szrj    along with GCC; see the file COPYING3.  If not see
18*38fd1498Szrj    <http://www.gnu.org/licenses/>.
19*38fd1498Szrj 
20*38fd1498Szrj    It is expected that more hunks of gcse.c and postreload-gcse.c should
21*38fd1498Szrj    migrate into this file.  */
22*38fd1498Szrj 
23*38fd1498Szrj #include "config.h"
24*38fd1498Szrj #include "system.h"
25*38fd1498Szrj #include "coretypes.h"
26*38fd1498Szrj #include "backend.h"
27*38fd1498Szrj #include "rtl.h"
28*38fd1498Szrj #include "df.h"
29*38fd1498Szrj #include "gcse-common.h"
30*38fd1498Szrj 
31*38fd1498Szrj 
32*38fd1498Szrj /* Record all of the canonicalized MEMs of record_last_mem_set_info's insn.
33*38fd1498Szrj    Note we store a pair of elements in the list, so they have to be
34*38fd1498Szrj    taken off pairwise.  */
35*38fd1498Szrj 
36*38fd1498Szrj void
canon_list_insert(rtx dest,const_rtx x ATTRIBUTE_UNUSED,void * data)37*38fd1498Szrj canon_list_insert (rtx dest, const_rtx x ATTRIBUTE_UNUSED, void *data)
38*38fd1498Szrj {
39*38fd1498Szrj   rtx dest_addr;
40*38fd1498Szrj   int bb;
41*38fd1498Szrj   modify_pair pair;
42*38fd1498Szrj 
43*38fd1498Szrj   while (GET_CODE (dest) == SUBREG
44*38fd1498Szrj       || GET_CODE (dest) == ZERO_EXTRACT
45*38fd1498Szrj       || GET_CODE (dest) == STRICT_LOW_PART)
46*38fd1498Szrj     dest = XEXP (dest, 0);
47*38fd1498Szrj 
48*38fd1498Szrj   /* If DEST is not a MEM, then it will not conflict with a load.  Note
49*38fd1498Szrj      that function calls are assumed to clobber memory, but are handled
50*38fd1498Szrj      elsewhere.  */
51*38fd1498Szrj 
52*38fd1498Szrj   if (! MEM_P (dest))
53*38fd1498Szrj     return;
54*38fd1498Szrj 
55*38fd1498Szrj   dest_addr = get_addr (XEXP (dest, 0));
56*38fd1498Szrj   dest_addr = canon_rtx (dest_addr);
57*38fd1498Szrj   rtx_insn *insn = ((struct gcse_note_stores_info *)data)->insn;
58*38fd1498Szrj   bb = BLOCK_FOR_INSN (insn)->index;
59*38fd1498Szrj 
60*38fd1498Szrj   pair.dest = dest;
61*38fd1498Szrj   pair.dest_addr = dest_addr;
62*38fd1498Szrj   vec<modify_pair> *canon_mem_list
63*38fd1498Szrj     = ((struct gcse_note_stores_info *)data)->canon_mem_list;
64*38fd1498Szrj   canon_mem_list[bb].safe_push (pair);
65*38fd1498Szrj }
66*38fd1498Szrj 
67*38fd1498Szrj /* Record memory modification information for INSN.  We do not actually care
68*38fd1498Szrj    about the memory location(s) that are set, or even how they are set (consider
69*38fd1498Szrj    a CALL_INSN).  We merely need to record which insns modify memory.  */
70*38fd1498Szrj 
71*38fd1498Szrj void
record_last_mem_set_info_common(rtx_insn * insn,vec<rtx_insn * > * modify_mem_list,vec<modify_pair> * canon_modify_mem_list,bitmap modify_mem_list_set,bitmap blocks_with_calls)72*38fd1498Szrj record_last_mem_set_info_common (rtx_insn *insn,
73*38fd1498Szrj 				 vec<rtx_insn *> *modify_mem_list,
74*38fd1498Szrj 				 vec<modify_pair> *canon_modify_mem_list,
75*38fd1498Szrj 				 bitmap modify_mem_list_set,
76*38fd1498Szrj 				 bitmap blocks_with_calls)
77*38fd1498Szrj 
78*38fd1498Szrj {
79*38fd1498Szrj   int bb;
80*38fd1498Szrj 
81*38fd1498Szrj   bb = BLOCK_FOR_INSN (insn)->index;
82*38fd1498Szrj   modify_mem_list[bb].safe_push (insn);
83*38fd1498Szrj   bitmap_set_bit (modify_mem_list_set, bb);
84*38fd1498Szrj 
85*38fd1498Szrj   if (CALL_P (insn))
86*38fd1498Szrj     bitmap_set_bit (blocks_with_calls, bb);
87*38fd1498Szrj   else
88*38fd1498Szrj     {
89*38fd1498Szrj       struct gcse_note_stores_info data;
90*38fd1498Szrj       data.insn = insn;
91*38fd1498Szrj       data.canon_mem_list = canon_modify_mem_list;
92*38fd1498Szrj       note_stores (PATTERN (insn), canon_list_insert, (void*) &data);
93*38fd1498Szrj     }
94*38fd1498Szrj }
95*38fd1498Szrj 
96*38fd1498Szrj 
97*38fd1498Szrj /* For each block, compute whether X is transparent.  X is either an
98*38fd1498Szrj    expression or an assignment [though we don't care which, for this context
99*38fd1498Szrj    an assignment is treated as an expression].  For each block where an
100*38fd1498Szrj    element of X is modified, reset the INDX bit in BMAP.
101*38fd1498Szrj 
102*38fd1498Szrj    BLOCKS_WITH_CALLS indicates which blocks contain CALL_INSNs which kill
103*38fd1498Szrj    memory.
104*38fd1498Szrj 
105*38fd1498Szrj    MODIFY_MEM_LIST_SET indicates which blocks have memory stores which might
106*38fd1498Szrj    kill a particular memory location.
107*38fd1498Szrj 
108*38fd1498Szrj    CANON_MODIFY_MEM_LIST is the canonicalized list of memory locations modified
109*38fd1498Szrj    for each block.  */
110*38fd1498Szrj 
111*38fd1498Szrj void
compute_transp(const_rtx x,int indx,sbitmap * bmap,bitmap blocks_with_calls,bitmap modify_mem_list_set,vec<modify_pair> * canon_modify_mem_list)112*38fd1498Szrj compute_transp (const_rtx x, int indx, sbitmap *bmap,
113*38fd1498Szrj 		bitmap blocks_with_calls,
114*38fd1498Szrj 		bitmap modify_mem_list_set,
115*38fd1498Szrj 	        vec<modify_pair> *canon_modify_mem_list)
116*38fd1498Szrj {
117*38fd1498Szrj   int i, j;
118*38fd1498Szrj   enum rtx_code code;
119*38fd1498Szrj   const char *fmt;
120*38fd1498Szrj 
121*38fd1498Szrj   /* repeat is used to turn tail-recursion into iteration since GCC
122*38fd1498Szrj      can't do it when there's no return value.  */
123*38fd1498Szrj  repeat:
124*38fd1498Szrj 
125*38fd1498Szrj   if (x == 0)
126*38fd1498Szrj     return;
127*38fd1498Szrj 
128*38fd1498Szrj   code = GET_CODE (x);
129*38fd1498Szrj   switch (code)
130*38fd1498Szrj     {
131*38fd1498Szrj     case REG:
132*38fd1498Szrj 	{
133*38fd1498Szrj 	  df_ref def;
134*38fd1498Szrj 	  for (def = DF_REG_DEF_CHAIN (REGNO (x));
135*38fd1498Szrj 	       def;
136*38fd1498Szrj 	       def = DF_REF_NEXT_REG (def))
137*38fd1498Szrj 	    bitmap_clear_bit (bmap[DF_REF_BB (def)->index], indx);
138*38fd1498Szrj 	}
139*38fd1498Szrj 
140*38fd1498Szrj       return;
141*38fd1498Szrj 
142*38fd1498Szrj     case MEM:
143*38fd1498Szrj       if (! MEM_READONLY_P (x))
144*38fd1498Szrj 	{
145*38fd1498Szrj 	  bitmap_iterator bi;
146*38fd1498Szrj 	  unsigned bb_index;
147*38fd1498Szrj 	  rtx x_addr;
148*38fd1498Szrj 
149*38fd1498Szrj 	  x_addr = get_addr (XEXP (x, 0));
150*38fd1498Szrj 	  x_addr = canon_rtx (x_addr);
151*38fd1498Szrj 
152*38fd1498Szrj 	  /* First handle all the blocks with calls.  We don't need to
153*38fd1498Szrj 	     do any list walking for them.  */
154*38fd1498Szrj 	  EXECUTE_IF_SET_IN_BITMAP (blocks_with_calls, 0, bb_index, bi)
155*38fd1498Szrj 	    {
156*38fd1498Szrj 	      bitmap_clear_bit (bmap[bb_index], indx);
157*38fd1498Szrj 	    }
158*38fd1498Szrj 
159*38fd1498Szrj 	  /* Now iterate over the blocks which have memory modifications
160*38fd1498Szrj 	     but which do not have any calls.  */
161*38fd1498Szrj 	  EXECUTE_IF_AND_COMPL_IN_BITMAP (modify_mem_list_set,
162*38fd1498Szrj 					  blocks_with_calls,
163*38fd1498Szrj 					  0, bb_index, bi)
164*38fd1498Szrj 	    {
165*38fd1498Szrj 	      vec<modify_pair> list
166*38fd1498Szrj 		= canon_modify_mem_list[bb_index];
167*38fd1498Szrj 	      modify_pair *pair;
168*38fd1498Szrj 	      unsigned ix;
169*38fd1498Szrj 
170*38fd1498Szrj 	      FOR_EACH_VEC_ELT_REVERSE (list, ix, pair)
171*38fd1498Szrj 		{
172*38fd1498Szrj 		  rtx dest = pair->dest;
173*38fd1498Szrj 		  rtx dest_addr = pair->dest_addr;
174*38fd1498Szrj 
175*38fd1498Szrj 		  if (canon_true_dependence (dest, GET_MODE (dest),
176*38fd1498Szrj 					     dest_addr, x, x_addr))
177*38fd1498Szrj 		    {
178*38fd1498Szrj 		      bitmap_clear_bit (bmap[bb_index], indx);
179*38fd1498Szrj 		      break;
180*38fd1498Szrj 		    }
181*38fd1498Szrj 	        }
182*38fd1498Szrj 	    }
183*38fd1498Szrj 	}
184*38fd1498Szrj 
185*38fd1498Szrj       x = XEXP (x, 0);
186*38fd1498Szrj       goto repeat;
187*38fd1498Szrj 
188*38fd1498Szrj     case PC:
189*38fd1498Szrj     case CC0: /*FIXME*/
190*38fd1498Szrj     case CONST:
191*38fd1498Szrj     CASE_CONST_ANY:
192*38fd1498Szrj     case SYMBOL_REF:
193*38fd1498Szrj     case LABEL_REF:
194*38fd1498Szrj     case ADDR_VEC:
195*38fd1498Szrj     case ADDR_DIFF_VEC:
196*38fd1498Szrj       return;
197*38fd1498Szrj 
198*38fd1498Szrj     default:
199*38fd1498Szrj       break;
200*38fd1498Szrj     }
201*38fd1498Szrj 
202*38fd1498Szrj   for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
203*38fd1498Szrj     {
204*38fd1498Szrj       if (fmt[i] == 'e')
205*38fd1498Szrj 	{
206*38fd1498Szrj 	  /* If we are about to do the last recursive call
207*38fd1498Szrj 	     needed at this level, change it into iteration.
208*38fd1498Szrj 	     This function is called enough to be worth it.  */
209*38fd1498Szrj 	  if (i == 0)
210*38fd1498Szrj 	    {
211*38fd1498Szrj 	      x = XEXP (x, i);
212*38fd1498Szrj 	      goto repeat;
213*38fd1498Szrj 	    }
214*38fd1498Szrj 
215*38fd1498Szrj 	  compute_transp (XEXP (x, i), indx, bmap, blocks_with_calls,
216*38fd1498Szrj 			  modify_mem_list_set, canon_modify_mem_list);
217*38fd1498Szrj 	}
218*38fd1498Szrj       else if (fmt[i] == 'E')
219*38fd1498Szrj 	for (j = 0; j < XVECLEN (x, i); j++)
220*38fd1498Szrj 	  compute_transp (XVECEXP (x, i, j), indx, bmap, blocks_with_calls,
221*38fd1498Szrj 			  modify_mem_list_set, canon_modify_mem_list);
222*38fd1498Szrj     }
223*38fd1498Szrj }
224