1*e4b17023SJohn Marino /* Move registers around to reduce number of move instructions needed.
2*e4b17023SJohn Marino Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3*e4b17023SJohn Marino 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4*e4b17023SJohn Marino Free Software Foundation, Inc.
5*e4b17023SJohn Marino
6*e4b17023SJohn Marino This file is part of GCC.
7*e4b17023SJohn Marino
8*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11*e4b17023SJohn Marino version.
12*e4b17023SJohn Marino
13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16*e4b17023SJohn Marino for more details.
17*e4b17023SJohn Marino
18*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
20*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
21*e4b17023SJohn Marino
22*e4b17023SJohn Marino
23*e4b17023SJohn Marino /* This module makes some simple RTL code transformations which
24*e4b17023SJohn Marino improve the subsequent register allocation. */
25*e4b17023SJohn Marino
26*e4b17023SJohn Marino #include "config.h"
27*e4b17023SJohn Marino #include "system.h"
28*e4b17023SJohn Marino #include "coretypes.h"
29*e4b17023SJohn Marino #include "tm.h"
30*e4b17023SJohn Marino #include "rtl.h"
31*e4b17023SJohn Marino #include "tm_p.h"
32*e4b17023SJohn Marino #include "insn-config.h"
33*e4b17023SJohn Marino #include "recog.h"
34*e4b17023SJohn Marino #include "target.h"
35*e4b17023SJohn Marino #include "output.h"
36*e4b17023SJohn Marino #include "regs.h"
37*e4b17023SJohn Marino #include "hard-reg-set.h"
38*e4b17023SJohn Marino #include "flags.h"
39*e4b17023SJohn Marino #include "function.h"
40*e4b17023SJohn Marino #include "expr.h"
41*e4b17023SJohn Marino #include "basic-block.h"
42*e4b17023SJohn Marino #include "except.h"
43*e4b17023SJohn Marino #include "diagnostic-core.h"
44*e4b17023SJohn Marino #include "reload.h"
45*e4b17023SJohn Marino #include "timevar.h"
46*e4b17023SJohn Marino #include "tree-pass.h"
47*e4b17023SJohn Marino #include "df.h"
48*e4b17023SJohn Marino #include "ira.h"
49*e4b17023SJohn Marino
50*e4b17023SJohn Marino static int optimize_reg_copy_1 (rtx, rtx, rtx);
51*e4b17023SJohn Marino static void optimize_reg_copy_2 (rtx, rtx, rtx);
52*e4b17023SJohn Marino static void optimize_reg_copy_3 (rtx, rtx, rtx);
53*e4b17023SJohn Marino static void copy_src_to_dest (rtx, rtx, rtx);
54*e4b17023SJohn Marino
55*e4b17023SJohn Marino enum match_use
56*e4b17023SJohn Marino {
57*e4b17023SJohn Marino READ,
58*e4b17023SJohn Marino WRITE,
59*e4b17023SJohn Marino READWRITE
60*e4b17023SJohn Marino };
61*e4b17023SJohn Marino
62*e4b17023SJohn Marino struct match {
63*e4b17023SJohn Marino int with[MAX_RECOG_OPERANDS];
64*e4b17023SJohn Marino enum match_use use[MAX_RECOG_OPERANDS];
65*e4b17023SJohn Marino int commutative[MAX_RECOG_OPERANDS];
66*e4b17023SJohn Marino int early_clobber[MAX_RECOG_OPERANDS];
67*e4b17023SJohn Marino };
68*e4b17023SJohn Marino
69*e4b17023SJohn Marino static int find_matches (rtx, struct match *);
70*e4b17023SJohn Marino static int fixup_match_2 (rtx, rtx, rtx, rtx);
71*e4b17023SJohn Marino
72*e4b17023SJohn Marino /* Return nonzero if registers with CLASS1 and CLASS2 can be merged without
73*e4b17023SJohn Marino causing too much register allocation problems. */
74*e4b17023SJohn Marino static int
regclass_compatible_p(reg_class_t class0,reg_class_t class1)75*e4b17023SJohn Marino regclass_compatible_p (reg_class_t class0, reg_class_t class1)
76*e4b17023SJohn Marino {
77*e4b17023SJohn Marino return (class0 == class1
78*e4b17023SJohn Marino || (reg_class_subset_p (class0, class1)
79*e4b17023SJohn Marino && ! targetm.class_likely_spilled_p (class0))
80*e4b17023SJohn Marino || (reg_class_subset_p (class1, class0)
81*e4b17023SJohn Marino && ! targetm.class_likely_spilled_p (class1)));
82*e4b17023SJohn Marino }
83*e4b17023SJohn Marino
84*e4b17023SJohn Marino
85*e4b17023SJohn Marino #ifdef AUTO_INC_DEC
86*e4b17023SJohn Marino
87*e4b17023SJohn Marino /* Find the place in the rtx X where REG is used as a memory address.
88*e4b17023SJohn Marino Return the MEM rtx that so uses it.
89*e4b17023SJohn Marino If PLUSCONST is nonzero, search instead for a memory address equivalent to
90*e4b17023SJohn Marino (plus REG (const_int PLUSCONST)).
91*e4b17023SJohn Marino
92*e4b17023SJohn Marino If such an address does not appear, return 0.
93*e4b17023SJohn Marino If REG appears more than once, or is used other than in such an address,
94*e4b17023SJohn Marino return (rtx) 1. */
95*e4b17023SJohn Marino
96*e4b17023SJohn Marino static rtx
find_use_as_address(rtx x,rtx reg,HOST_WIDE_INT plusconst)97*e4b17023SJohn Marino find_use_as_address (rtx x, rtx reg, HOST_WIDE_INT plusconst)
98*e4b17023SJohn Marino {
99*e4b17023SJohn Marino enum rtx_code code = GET_CODE (x);
100*e4b17023SJohn Marino const char * const fmt = GET_RTX_FORMAT (code);
101*e4b17023SJohn Marino int i;
102*e4b17023SJohn Marino rtx value = 0;
103*e4b17023SJohn Marino rtx tem;
104*e4b17023SJohn Marino
105*e4b17023SJohn Marino if (code == MEM && XEXP (x, 0) == reg && plusconst == 0)
106*e4b17023SJohn Marino return x;
107*e4b17023SJohn Marino
108*e4b17023SJohn Marino if (code == MEM && GET_CODE (XEXP (x, 0)) == PLUS
109*e4b17023SJohn Marino && XEXP (XEXP (x, 0), 0) == reg
110*e4b17023SJohn Marino && CONST_INT_P (XEXP (XEXP (x, 0), 1))
111*e4b17023SJohn Marino && INTVAL (XEXP (XEXP (x, 0), 1)) == plusconst)
112*e4b17023SJohn Marino return x;
113*e4b17023SJohn Marino
114*e4b17023SJohn Marino if (code == SIGN_EXTRACT || code == ZERO_EXTRACT)
115*e4b17023SJohn Marino {
116*e4b17023SJohn Marino /* If REG occurs inside a MEM used in a bit-field reference,
117*e4b17023SJohn Marino that is unacceptable. */
118*e4b17023SJohn Marino if (find_use_as_address (XEXP (x, 0), reg, 0) != 0)
119*e4b17023SJohn Marino return (rtx) (size_t) 1;
120*e4b17023SJohn Marino }
121*e4b17023SJohn Marino
122*e4b17023SJohn Marino if (x == reg)
123*e4b17023SJohn Marino return (rtx) (size_t) 1;
124*e4b17023SJohn Marino
125*e4b17023SJohn Marino for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
126*e4b17023SJohn Marino {
127*e4b17023SJohn Marino if (fmt[i] == 'e')
128*e4b17023SJohn Marino {
129*e4b17023SJohn Marino tem = find_use_as_address (XEXP (x, i), reg, plusconst);
130*e4b17023SJohn Marino if (value == 0)
131*e4b17023SJohn Marino value = tem;
132*e4b17023SJohn Marino else if (tem != 0)
133*e4b17023SJohn Marino return (rtx) (size_t) 1;
134*e4b17023SJohn Marino }
135*e4b17023SJohn Marino else if (fmt[i] == 'E')
136*e4b17023SJohn Marino {
137*e4b17023SJohn Marino int j;
138*e4b17023SJohn Marino for (j = XVECLEN (x, i) - 1; j >= 0; j--)
139*e4b17023SJohn Marino {
140*e4b17023SJohn Marino tem = find_use_as_address (XVECEXP (x, i, j), reg, plusconst);
141*e4b17023SJohn Marino if (value == 0)
142*e4b17023SJohn Marino value = tem;
143*e4b17023SJohn Marino else if (tem != 0)
144*e4b17023SJohn Marino return (rtx) (size_t) 1;
145*e4b17023SJohn Marino }
146*e4b17023SJohn Marino }
147*e4b17023SJohn Marino }
148*e4b17023SJohn Marino
149*e4b17023SJohn Marino return value;
150*e4b17023SJohn Marino }
151*e4b17023SJohn Marino
152*e4b17023SJohn Marino
153*e4b17023SJohn Marino /* INC_INSN is an instruction that adds INCREMENT to REG.
154*e4b17023SJohn Marino Try to fold INC_INSN as a post/pre in/decrement into INSN.
155*e4b17023SJohn Marino Iff INC_INSN_SET is nonzero, inc_insn has a destination different from src.
156*e4b17023SJohn Marino Return nonzero for success. */
157*e4b17023SJohn Marino static int
try_auto_increment(rtx insn,rtx inc_insn,rtx inc_insn_set,rtx reg,HOST_WIDE_INT increment,int pre)158*e4b17023SJohn Marino try_auto_increment (rtx insn, rtx inc_insn, rtx inc_insn_set, rtx reg,
159*e4b17023SJohn Marino HOST_WIDE_INT increment, int pre)
160*e4b17023SJohn Marino {
161*e4b17023SJohn Marino enum rtx_code inc_code;
162*e4b17023SJohn Marino
163*e4b17023SJohn Marino rtx pset = single_set (insn);
164*e4b17023SJohn Marino if (pset)
165*e4b17023SJohn Marino {
166*e4b17023SJohn Marino /* Can't use the size of SET_SRC, we might have something like
167*e4b17023SJohn Marino (sign_extend:SI (mem:QI ... */
168*e4b17023SJohn Marino rtx use = find_use_as_address (pset, reg, 0);
169*e4b17023SJohn Marino if (use != 0 && use != (rtx) (size_t) 1)
170*e4b17023SJohn Marino {
171*e4b17023SJohn Marino int size = GET_MODE_SIZE (GET_MODE (use));
172*e4b17023SJohn Marino if (0
173*e4b17023SJohn Marino || (HAVE_POST_INCREMENT
174*e4b17023SJohn Marino && pre == 0 && (inc_code = POST_INC, increment == size))
175*e4b17023SJohn Marino || (HAVE_PRE_INCREMENT
176*e4b17023SJohn Marino && pre == 1 && (inc_code = PRE_INC, increment == size))
177*e4b17023SJohn Marino || (HAVE_POST_DECREMENT
178*e4b17023SJohn Marino && pre == 0 && (inc_code = POST_DEC, increment == -size))
179*e4b17023SJohn Marino || (HAVE_PRE_DECREMENT
180*e4b17023SJohn Marino && pre == 1 && (inc_code = PRE_DEC, increment == -size))
181*e4b17023SJohn Marino )
182*e4b17023SJohn Marino {
183*e4b17023SJohn Marino if (inc_insn_set)
184*e4b17023SJohn Marino validate_change
185*e4b17023SJohn Marino (inc_insn,
186*e4b17023SJohn Marino &SET_SRC (inc_insn_set),
187*e4b17023SJohn Marino XEXP (SET_SRC (inc_insn_set), 0), 1);
188*e4b17023SJohn Marino validate_change (insn, &XEXP (use, 0),
189*e4b17023SJohn Marino gen_rtx_fmt_e (inc_code,
190*e4b17023SJohn Marino GET_MODE (XEXP (use, 0)), reg),
191*e4b17023SJohn Marino 1);
192*e4b17023SJohn Marino if (apply_change_group ())
193*e4b17023SJohn Marino {
194*e4b17023SJohn Marino /* If there is a REG_DEAD note on this insn, we must
195*e4b17023SJohn Marino change this not to REG_UNUSED meaning that the register
196*e4b17023SJohn Marino is set, but the value is dead. Failure to do so will
197*e4b17023SJohn Marino result in sched1 dying -- when it recomputes lifetime
198*e4b17023SJohn Marino information, the number of REG_DEAD notes will have
199*e4b17023SJohn Marino changed. */
200*e4b17023SJohn Marino rtx note = find_reg_note (insn, REG_DEAD, reg);
201*e4b17023SJohn Marino if (note)
202*e4b17023SJohn Marino PUT_REG_NOTE_KIND (note, REG_UNUSED);
203*e4b17023SJohn Marino
204*e4b17023SJohn Marino add_reg_note (insn, REG_INC, reg);
205*e4b17023SJohn Marino
206*e4b17023SJohn Marino if (! inc_insn_set)
207*e4b17023SJohn Marino delete_insn (inc_insn);
208*e4b17023SJohn Marino return 1;
209*e4b17023SJohn Marino }
210*e4b17023SJohn Marino }
211*e4b17023SJohn Marino }
212*e4b17023SJohn Marino }
213*e4b17023SJohn Marino return 0;
214*e4b17023SJohn Marino }
215*e4b17023SJohn Marino #endif
216*e4b17023SJohn Marino
217*e4b17023SJohn Marino
218*e4b17023SJohn Marino static int *regno_src_regno;
219*e4b17023SJohn Marino
220*e4b17023SJohn Marino /* INSN is a copy from SRC to DEST, both registers, and SRC does not die
221*e4b17023SJohn Marino in INSN.
222*e4b17023SJohn Marino
223*e4b17023SJohn Marino Search forward to see if SRC dies before either it or DEST is modified,
224*e4b17023SJohn Marino but don't scan past the end of a basic block. If so, we can replace SRC
225*e4b17023SJohn Marino with DEST and let SRC die in INSN.
226*e4b17023SJohn Marino
227*e4b17023SJohn Marino This will reduce the number of registers live in that range and may enable
228*e4b17023SJohn Marino DEST to be tied to SRC, thus often saving one register in addition to a
229*e4b17023SJohn Marino register-register copy. */
230*e4b17023SJohn Marino
231*e4b17023SJohn Marino static int
optimize_reg_copy_1(rtx insn,rtx dest,rtx src)232*e4b17023SJohn Marino optimize_reg_copy_1 (rtx insn, rtx dest, rtx src)
233*e4b17023SJohn Marino {
234*e4b17023SJohn Marino rtx p, q;
235*e4b17023SJohn Marino rtx note;
236*e4b17023SJohn Marino rtx dest_death = 0;
237*e4b17023SJohn Marino int sregno = REGNO (src);
238*e4b17023SJohn Marino int dregno = REGNO (dest);
239*e4b17023SJohn Marino basic_block bb = BLOCK_FOR_INSN (insn);
240*e4b17023SJohn Marino
241*e4b17023SJohn Marino /* We don't want to mess with hard regs if register classes are small. */
242*e4b17023SJohn Marino if (sregno == dregno
243*e4b17023SJohn Marino || (targetm.small_register_classes_for_mode_p (GET_MODE (src))
244*e4b17023SJohn Marino && (sregno < FIRST_PSEUDO_REGISTER
245*e4b17023SJohn Marino || dregno < FIRST_PSEUDO_REGISTER))
246*e4b17023SJohn Marino /* We don't see all updates to SP if they are in an auto-inc memory
247*e4b17023SJohn Marino reference, so we must disallow this optimization on them. */
248*e4b17023SJohn Marino || sregno == STACK_POINTER_REGNUM || dregno == STACK_POINTER_REGNUM)
249*e4b17023SJohn Marino return 0;
250*e4b17023SJohn Marino
251*e4b17023SJohn Marino for (p = NEXT_INSN (insn); p; p = NEXT_INSN (p))
252*e4b17023SJohn Marino {
253*e4b17023SJohn Marino if (! INSN_P (p))
254*e4b17023SJohn Marino continue;
255*e4b17023SJohn Marino if (BLOCK_FOR_INSN (p) != bb)
256*e4b17023SJohn Marino break;
257*e4b17023SJohn Marino
258*e4b17023SJohn Marino if (reg_set_p (src, p) || reg_set_p (dest, p)
259*e4b17023SJohn Marino /* If SRC is an asm-declared register, it must not be replaced
260*e4b17023SJohn Marino in any asm. Unfortunately, the REG_EXPR tree for the asm
261*e4b17023SJohn Marino variable may be absent in the SRC rtx, so we can't check the
262*e4b17023SJohn Marino actual register declaration easily (the asm operand will have
263*e4b17023SJohn Marino it, though). To avoid complicating the test for a rare case,
264*e4b17023SJohn Marino we just don't perform register replacement for a hard reg
265*e4b17023SJohn Marino mentioned in an asm. */
266*e4b17023SJohn Marino || (sregno < FIRST_PSEUDO_REGISTER
267*e4b17023SJohn Marino && asm_noperands (PATTERN (p)) >= 0
268*e4b17023SJohn Marino && reg_overlap_mentioned_p (src, PATTERN (p)))
269*e4b17023SJohn Marino /* Don't change hard registers used by a call. */
270*e4b17023SJohn Marino || (CALL_P (p) && sregno < FIRST_PSEUDO_REGISTER
271*e4b17023SJohn Marino && find_reg_fusage (p, USE, src))
272*e4b17023SJohn Marino /* Don't change a USE of a register. */
273*e4b17023SJohn Marino || (GET_CODE (PATTERN (p)) == USE
274*e4b17023SJohn Marino && reg_overlap_mentioned_p (src, XEXP (PATTERN (p), 0))))
275*e4b17023SJohn Marino break;
276*e4b17023SJohn Marino
277*e4b17023SJohn Marino /* See if all of SRC dies in P. This test is slightly more
278*e4b17023SJohn Marino conservative than it needs to be. */
279*e4b17023SJohn Marino if ((note = find_regno_note (p, REG_DEAD, sregno)) != 0
280*e4b17023SJohn Marino && GET_MODE (XEXP (note, 0)) == GET_MODE (src))
281*e4b17023SJohn Marino {
282*e4b17023SJohn Marino int failed = 0;
283*e4b17023SJohn Marino int d_length = 0;
284*e4b17023SJohn Marino int s_length = 0;
285*e4b17023SJohn Marino int d_n_calls = 0;
286*e4b17023SJohn Marino int s_n_calls = 0;
287*e4b17023SJohn Marino int s_freq_calls = 0;
288*e4b17023SJohn Marino int d_freq_calls = 0;
289*e4b17023SJohn Marino
290*e4b17023SJohn Marino /* We can do the optimization. Scan forward from INSN again,
291*e4b17023SJohn Marino replacing regs as we go. Set FAILED if a replacement can't
292*e4b17023SJohn Marino be done. In that case, we can't move the death note for SRC.
293*e4b17023SJohn Marino This should be rare. */
294*e4b17023SJohn Marino
295*e4b17023SJohn Marino /* Set to stop at next insn. */
296*e4b17023SJohn Marino for (q = next_real_insn (insn);
297*e4b17023SJohn Marino q != next_real_insn (p);
298*e4b17023SJohn Marino q = next_real_insn (q))
299*e4b17023SJohn Marino {
300*e4b17023SJohn Marino if (reg_overlap_mentioned_p (src, PATTERN (q)))
301*e4b17023SJohn Marino {
302*e4b17023SJohn Marino /* If SRC is a hard register, we might miss some
303*e4b17023SJohn Marino overlapping registers with validate_replace_rtx,
304*e4b17023SJohn Marino so we would have to undo it. We can't if DEST is
305*e4b17023SJohn Marino present in the insn, so fail in that combination
306*e4b17023SJohn Marino of cases. */
307*e4b17023SJohn Marino if (sregno < FIRST_PSEUDO_REGISTER
308*e4b17023SJohn Marino && reg_mentioned_p (dest, PATTERN (q)))
309*e4b17023SJohn Marino failed = 1;
310*e4b17023SJohn Marino
311*e4b17023SJohn Marino /* Attempt to replace all uses. */
312*e4b17023SJohn Marino else if (!validate_replace_rtx (src, dest, q))
313*e4b17023SJohn Marino failed = 1;
314*e4b17023SJohn Marino
315*e4b17023SJohn Marino /* If this succeeded, but some part of the register
316*e4b17023SJohn Marino is still present, undo the replacement. */
317*e4b17023SJohn Marino else if (sregno < FIRST_PSEUDO_REGISTER
318*e4b17023SJohn Marino && reg_overlap_mentioned_p (src, PATTERN (q)))
319*e4b17023SJohn Marino {
320*e4b17023SJohn Marino validate_replace_rtx (dest, src, q);
321*e4b17023SJohn Marino failed = 1;
322*e4b17023SJohn Marino }
323*e4b17023SJohn Marino }
324*e4b17023SJohn Marino
325*e4b17023SJohn Marino /* For SREGNO, count the total number of insns scanned.
326*e4b17023SJohn Marino For DREGNO, count the total number of insns scanned after
327*e4b17023SJohn Marino passing the death note for DREGNO. */
328*e4b17023SJohn Marino if (!DEBUG_INSN_P (p))
329*e4b17023SJohn Marino {
330*e4b17023SJohn Marino s_length++;
331*e4b17023SJohn Marino if (dest_death)
332*e4b17023SJohn Marino d_length++;
333*e4b17023SJohn Marino }
334*e4b17023SJohn Marino
335*e4b17023SJohn Marino /* If the insn in which SRC dies is a CALL_INSN, don't count it
336*e4b17023SJohn Marino as a call that has been crossed. Otherwise, count it. */
337*e4b17023SJohn Marino if (q != p && CALL_P (q))
338*e4b17023SJohn Marino {
339*e4b17023SJohn Marino /* Similarly, total calls for SREGNO, total calls beyond
340*e4b17023SJohn Marino the death note for DREGNO. */
341*e4b17023SJohn Marino s_n_calls++;
342*e4b17023SJohn Marino s_freq_calls += REG_FREQ_FROM_BB (BLOCK_FOR_INSN (q));
343*e4b17023SJohn Marino if (dest_death)
344*e4b17023SJohn Marino {
345*e4b17023SJohn Marino d_n_calls++;
346*e4b17023SJohn Marino d_freq_calls += REG_FREQ_FROM_BB (BLOCK_FOR_INSN (q));
347*e4b17023SJohn Marino }
348*e4b17023SJohn Marino }
349*e4b17023SJohn Marino
350*e4b17023SJohn Marino /* If DEST dies here, remove the death note and save it for
351*e4b17023SJohn Marino later. Make sure ALL of DEST dies here; again, this is
352*e4b17023SJohn Marino overly conservative. */
353*e4b17023SJohn Marino if (dest_death == 0
354*e4b17023SJohn Marino && (dest_death = find_regno_note (q, REG_DEAD, dregno)) != 0)
355*e4b17023SJohn Marino {
356*e4b17023SJohn Marino if (GET_MODE (XEXP (dest_death, 0)) != GET_MODE (dest))
357*e4b17023SJohn Marino failed = 1, dest_death = 0;
358*e4b17023SJohn Marino else
359*e4b17023SJohn Marino remove_note (q, dest_death);
360*e4b17023SJohn Marino }
361*e4b17023SJohn Marino }
362*e4b17023SJohn Marino
363*e4b17023SJohn Marino if (! failed)
364*e4b17023SJohn Marino {
365*e4b17023SJohn Marino /* These counters need to be updated if and only if we are
366*e4b17023SJohn Marino going to move the REG_DEAD note. */
367*e4b17023SJohn Marino if (sregno >= FIRST_PSEUDO_REGISTER)
368*e4b17023SJohn Marino {
369*e4b17023SJohn Marino if (REG_LIVE_LENGTH (sregno) >= 0)
370*e4b17023SJohn Marino {
371*e4b17023SJohn Marino REG_LIVE_LENGTH (sregno) -= s_length;
372*e4b17023SJohn Marino /* REG_LIVE_LENGTH is only an approximation after
373*e4b17023SJohn Marino combine if sched is not run, so make sure that we
374*e4b17023SJohn Marino still have a reasonable value. */
375*e4b17023SJohn Marino if (REG_LIVE_LENGTH (sregno) < 2)
376*e4b17023SJohn Marino REG_LIVE_LENGTH (sregno) = 2;
377*e4b17023SJohn Marino }
378*e4b17023SJohn Marino
379*e4b17023SJohn Marino REG_N_CALLS_CROSSED (sregno) -= s_n_calls;
380*e4b17023SJohn Marino REG_FREQ_CALLS_CROSSED (sregno) -= s_freq_calls;
381*e4b17023SJohn Marino }
382*e4b17023SJohn Marino
383*e4b17023SJohn Marino /* Move death note of SRC from P to INSN. */
384*e4b17023SJohn Marino remove_note (p, note);
385*e4b17023SJohn Marino XEXP (note, 1) = REG_NOTES (insn);
386*e4b17023SJohn Marino REG_NOTES (insn) = note;
387*e4b17023SJohn Marino }
388*e4b17023SJohn Marino
389*e4b17023SJohn Marino /* DEST is also dead if INSN has a REG_UNUSED note for DEST. */
390*e4b17023SJohn Marino if (! dest_death
391*e4b17023SJohn Marino && (dest_death = find_regno_note (insn, REG_UNUSED, dregno)))
392*e4b17023SJohn Marino {
393*e4b17023SJohn Marino PUT_REG_NOTE_KIND (dest_death, REG_DEAD);
394*e4b17023SJohn Marino remove_note (insn, dest_death);
395*e4b17023SJohn Marino }
396*e4b17023SJohn Marino
397*e4b17023SJohn Marino /* Put death note of DEST on P if we saw it die. */
398*e4b17023SJohn Marino if (dest_death)
399*e4b17023SJohn Marino {
400*e4b17023SJohn Marino XEXP (dest_death, 1) = REG_NOTES (p);
401*e4b17023SJohn Marino REG_NOTES (p) = dest_death;
402*e4b17023SJohn Marino
403*e4b17023SJohn Marino if (dregno >= FIRST_PSEUDO_REGISTER)
404*e4b17023SJohn Marino {
405*e4b17023SJohn Marino /* If and only if we are moving the death note for DREGNO,
406*e4b17023SJohn Marino then we need to update its counters. */
407*e4b17023SJohn Marino if (REG_LIVE_LENGTH (dregno) >= 0)
408*e4b17023SJohn Marino REG_LIVE_LENGTH (dregno) += d_length;
409*e4b17023SJohn Marino REG_N_CALLS_CROSSED (dregno) += d_n_calls;
410*e4b17023SJohn Marino REG_FREQ_CALLS_CROSSED (dregno) += d_freq_calls;
411*e4b17023SJohn Marino }
412*e4b17023SJohn Marino }
413*e4b17023SJohn Marino
414*e4b17023SJohn Marino return ! failed;
415*e4b17023SJohn Marino }
416*e4b17023SJohn Marino
417*e4b17023SJohn Marino /* If SRC is a hard register which is set or killed in some other
418*e4b17023SJohn Marino way, we can't do this optimization. */
419*e4b17023SJohn Marino else if (sregno < FIRST_PSEUDO_REGISTER
420*e4b17023SJohn Marino && dead_or_set_p (p, src))
421*e4b17023SJohn Marino break;
422*e4b17023SJohn Marino }
423*e4b17023SJohn Marino return 0;
424*e4b17023SJohn Marino }
425*e4b17023SJohn Marino
426*e4b17023SJohn Marino /* INSN is a copy of SRC to DEST, in which SRC dies. See if we now have
427*e4b17023SJohn Marino a sequence of insns that modify DEST followed by an insn that sets
428*e4b17023SJohn Marino SRC to DEST in which DEST dies, with no prior modification of DEST.
429*e4b17023SJohn Marino (There is no need to check if the insns in between actually modify
430*e4b17023SJohn Marino DEST. We should not have cases where DEST is not modified, but
431*e4b17023SJohn Marino the optimization is safe if no such modification is detected.)
432*e4b17023SJohn Marino In that case, we can replace all uses of DEST, starting with INSN and
433*e4b17023SJohn Marino ending with the set of SRC to DEST, with SRC. We do not do this
434*e4b17023SJohn Marino optimization if a CALL_INSN is crossed unless SRC already crosses a
435*e4b17023SJohn Marino call or if DEST dies before the copy back to SRC.
436*e4b17023SJohn Marino
437*e4b17023SJohn Marino It is assumed that DEST and SRC are pseudos; it is too complicated to do
438*e4b17023SJohn Marino this for hard registers since the substitutions we may make might fail. */
439*e4b17023SJohn Marino
440*e4b17023SJohn Marino static void
optimize_reg_copy_2(rtx insn,rtx dest,rtx src)441*e4b17023SJohn Marino optimize_reg_copy_2 (rtx insn, rtx dest, rtx src)
442*e4b17023SJohn Marino {
443*e4b17023SJohn Marino rtx p, q;
444*e4b17023SJohn Marino rtx set;
445*e4b17023SJohn Marino int sregno = REGNO (src);
446*e4b17023SJohn Marino int dregno = REGNO (dest);
447*e4b17023SJohn Marino basic_block bb = BLOCK_FOR_INSN (insn);
448*e4b17023SJohn Marino
449*e4b17023SJohn Marino for (p = NEXT_INSN (insn); p; p = NEXT_INSN (p))
450*e4b17023SJohn Marino {
451*e4b17023SJohn Marino if (! INSN_P (p))
452*e4b17023SJohn Marino continue;
453*e4b17023SJohn Marino if (BLOCK_FOR_INSN (p) != bb)
454*e4b17023SJohn Marino break;
455*e4b17023SJohn Marino
456*e4b17023SJohn Marino set = single_set (p);
457*e4b17023SJohn Marino if (set && SET_SRC (set) == dest && SET_DEST (set) == src
458*e4b17023SJohn Marino && find_reg_note (p, REG_DEAD, dest))
459*e4b17023SJohn Marino {
460*e4b17023SJohn Marino /* We can do the optimization. Scan forward from INSN again,
461*e4b17023SJohn Marino replacing regs as we go. */
462*e4b17023SJohn Marino
463*e4b17023SJohn Marino /* Set to stop at next insn. */
464*e4b17023SJohn Marino for (q = insn; q != NEXT_INSN (p); q = NEXT_INSN (q))
465*e4b17023SJohn Marino if (INSN_P (q))
466*e4b17023SJohn Marino {
467*e4b17023SJohn Marino if (reg_mentioned_p (dest, PATTERN (q)))
468*e4b17023SJohn Marino {
469*e4b17023SJohn Marino rtx note;
470*e4b17023SJohn Marino
471*e4b17023SJohn Marino PATTERN (q) = replace_rtx (PATTERN (q), dest, src);
472*e4b17023SJohn Marino note = FIND_REG_INC_NOTE (q, dest);
473*e4b17023SJohn Marino if (note)
474*e4b17023SJohn Marino {
475*e4b17023SJohn Marino remove_note (q, note);
476*e4b17023SJohn Marino add_reg_note (q, REG_INC, src);
477*e4b17023SJohn Marino }
478*e4b17023SJohn Marino df_insn_rescan (q);
479*e4b17023SJohn Marino }
480*e4b17023SJohn Marino
481*e4b17023SJohn Marino if (CALL_P (q))
482*e4b17023SJohn Marino {
483*e4b17023SJohn Marino int freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (q));
484*e4b17023SJohn Marino REG_N_CALLS_CROSSED (dregno)--;
485*e4b17023SJohn Marino REG_N_CALLS_CROSSED (sregno)++;
486*e4b17023SJohn Marino REG_FREQ_CALLS_CROSSED (dregno) -= freq;
487*e4b17023SJohn Marino REG_FREQ_CALLS_CROSSED (sregno) += freq;
488*e4b17023SJohn Marino }
489*e4b17023SJohn Marino }
490*e4b17023SJohn Marino
491*e4b17023SJohn Marino remove_note (p, find_reg_note (p, REG_DEAD, dest));
492*e4b17023SJohn Marino REG_N_DEATHS (dregno)--;
493*e4b17023SJohn Marino remove_note (insn, find_reg_note (insn, REG_DEAD, src));
494*e4b17023SJohn Marino REG_N_DEATHS (sregno)--;
495*e4b17023SJohn Marino return;
496*e4b17023SJohn Marino }
497*e4b17023SJohn Marino
498*e4b17023SJohn Marino if (reg_set_p (src, p)
499*e4b17023SJohn Marino || find_reg_note (p, REG_DEAD, dest)
500*e4b17023SJohn Marino || (CALL_P (p) && REG_N_CALLS_CROSSED (sregno) == 0))
501*e4b17023SJohn Marino break;
502*e4b17023SJohn Marino }
503*e4b17023SJohn Marino }
504*e4b17023SJohn Marino
505*e4b17023SJohn Marino /* INSN is a ZERO_EXTEND or SIGN_EXTEND of SRC to DEST.
506*e4b17023SJohn Marino Look if SRC dies there, and if it is only set once, by loading
507*e4b17023SJohn Marino it from memory. If so, try to incorporate the zero/sign extension
508*e4b17023SJohn Marino into the memory read, change SRC to the mode of DEST, and alter
509*e4b17023SJohn Marino the remaining accesses to use the appropriate SUBREG. This allows
510*e4b17023SJohn Marino SRC and DEST to be tied later. */
511*e4b17023SJohn Marino static void
optimize_reg_copy_3(rtx insn,rtx dest,rtx src)512*e4b17023SJohn Marino optimize_reg_copy_3 (rtx insn, rtx dest, rtx src)
513*e4b17023SJohn Marino {
514*e4b17023SJohn Marino rtx src_reg = XEXP (src, 0);
515*e4b17023SJohn Marino int src_no = REGNO (src_reg);
516*e4b17023SJohn Marino int dst_no = REGNO (dest);
517*e4b17023SJohn Marino rtx p, set, set_insn;
518*e4b17023SJohn Marino enum machine_mode old_mode;
519*e4b17023SJohn Marino basic_block bb = BLOCK_FOR_INSN (insn);
520*e4b17023SJohn Marino
521*e4b17023SJohn Marino if (src_no < FIRST_PSEUDO_REGISTER
522*e4b17023SJohn Marino || dst_no < FIRST_PSEUDO_REGISTER
523*e4b17023SJohn Marino || ! find_reg_note (insn, REG_DEAD, src_reg)
524*e4b17023SJohn Marino || REG_N_DEATHS (src_no) != 1
525*e4b17023SJohn Marino || REG_N_SETS (src_no) != 1)
526*e4b17023SJohn Marino return;
527*e4b17023SJohn Marino
528*e4b17023SJohn Marino for (p = PREV_INSN (insn); p && ! reg_set_p (src_reg, p); p = PREV_INSN (p))
529*e4b17023SJohn Marino if (INSN_P (p) && BLOCK_FOR_INSN (p) != bb)
530*e4b17023SJohn Marino break;
531*e4b17023SJohn Marino
532*e4b17023SJohn Marino if (! p || BLOCK_FOR_INSN (p) != bb)
533*e4b17023SJohn Marino return;
534*e4b17023SJohn Marino
535*e4b17023SJohn Marino if (! (set = single_set (p))
536*e4b17023SJohn Marino || !MEM_P (SET_SRC (set))
537*e4b17023SJohn Marino /* If there's a REG_EQUIV note, this must be an insn that loads an
538*e4b17023SJohn Marino argument. Prefer keeping the note over doing this optimization. */
539*e4b17023SJohn Marino || find_reg_note (p, REG_EQUIV, NULL_RTX)
540*e4b17023SJohn Marino || SET_DEST (set) != src_reg)
541*e4b17023SJohn Marino return;
542*e4b17023SJohn Marino
543*e4b17023SJohn Marino /* Be conservative: although this optimization is also valid for
544*e4b17023SJohn Marino volatile memory references, that could cause trouble in later passes. */
545*e4b17023SJohn Marino if (MEM_VOLATILE_P (SET_SRC (set)))
546*e4b17023SJohn Marino return;
547*e4b17023SJohn Marino
548*e4b17023SJohn Marino /* Do not use a SUBREG to truncate from one mode to another if truncation
549*e4b17023SJohn Marino is not a nop. */
550*e4b17023SJohn Marino if (GET_MODE_BITSIZE (GET_MODE (src_reg)) <= GET_MODE_BITSIZE (GET_MODE (src))
551*e4b17023SJohn Marino && !TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (src), GET_MODE (src_reg)))
552*e4b17023SJohn Marino return;
553*e4b17023SJohn Marino
554*e4b17023SJohn Marino set_insn = p;
555*e4b17023SJohn Marino old_mode = GET_MODE (src_reg);
556*e4b17023SJohn Marino PUT_MODE (src_reg, GET_MODE (src));
557*e4b17023SJohn Marino XEXP (src, 0) = SET_SRC (set);
558*e4b17023SJohn Marino
559*e4b17023SJohn Marino /* Include this change in the group so that it's easily undone if
560*e4b17023SJohn Marino one of the changes in the group is invalid. */
561*e4b17023SJohn Marino validate_change (p, &SET_SRC (set), src, 1);
562*e4b17023SJohn Marino
563*e4b17023SJohn Marino /* Now walk forward making additional replacements. We want to be able
564*e4b17023SJohn Marino to undo all the changes if a later substitution fails. */
565*e4b17023SJohn Marino while (p = NEXT_INSN (p), p != insn)
566*e4b17023SJohn Marino {
567*e4b17023SJohn Marino if (! INSN_P (p))
568*e4b17023SJohn Marino continue;
569*e4b17023SJohn Marino
570*e4b17023SJohn Marino /* Make a tentative change. */
571*e4b17023SJohn Marino validate_replace_rtx_group (src_reg,
572*e4b17023SJohn Marino gen_lowpart_SUBREG (old_mode, src_reg),
573*e4b17023SJohn Marino p);
574*e4b17023SJohn Marino }
575*e4b17023SJohn Marino
576*e4b17023SJohn Marino validate_replace_rtx_group (src, src_reg, insn);
577*e4b17023SJohn Marino
578*e4b17023SJohn Marino /* Now see if all the changes are valid. */
579*e4b17023SJohn Marino if (! apply_change_group ())
580*e4b17023SJohn Marino {
581*e4b17023SJohn Marino /* One or more changes were no good. Back out everything. */
582*e4b17023SJohn Marino PUT_MODE (src_reg, old_mode);
583*e4b17023SJohn Marino XEXP (src, 0) = src_reg;
584*e4b17023SJohn Marino }
585*e4b17023SJohn Marino else
586*e4b17023SJohn Marino {
587*e4b17023SJohn Marino rtx note = find_reg_note (set_insn, REG_EQUAL, NULL_RTX);
588*e4b17023SJohn Marino if (note)
589*e4b17023SJohn Marino {
590*e4b17023SJohn Marino if (rtx_equal_p (XEXP (note, 0), XEXP (src, 0)))
591*e4b17023SJohn Marino {
592*e4b17023SJohn Marino XEXP (note, 0)
593*e4b17023SJohn Marino = gen_rtx_fmt_e (GET_CODE (src), GET_MODE (src),
594*e4b17023SJohn Marino XEXP (note, 0));
595*e4b17023SJohn Marino df_notes_rescan (set_insn);
596*e4b17023SJohn Marino }
597*e4b17023SJohn Marino else
598*e4b17023SJohn Marino remove_note (set_insn, note);
599*e4b17023SJohn Marino }
600*e4b17023SJohn Marino }
601*e4b17023SJohn Marino }
602*e4b17023SJohn Marino
603*e4b17023SJohn Marino
604*e4b17023SJohn Marino /* If we were not able to update the users of src to use dest directly, try
605*e4b17023SJohn Marino instead moving the value to dest directly before the operation. */
606*e4b17023SJohn Marino
607*e4b17023SJohn Marino static void
copy_src_to_dest(rtx insn,rtx src,rtx dest)608*e4b17023SJohn Marino copy_src_to_dest (rtx insn, rtx src, rtx dest)
609*e4b17023SJohn Marino {
610*e4b17023SJohn Marino rtx seq;
611*e4b17023SJohn Marino rtx link;
612*e4b17023SJohn Marino rtx next;
613*e4b17023SJohn Marino rtx set;
614*e4b17023SJohn Marino rtx move_insn;
615*e4b17023SJohn Marino rtx *p_insn_notes;
616*e4b17023SJohn Marino rtx *p_move_notes;
617*e4b17023SJohn Marino int src_regno;
618*e4b17023SJohn Marino int dest_regno;
619*e4b17023SJohn Marino
620*e4b17023SJohn Marino /* A REG_LIVE_LENGTH of -1 indicates the register is equivalent to a constant
621*e4b17023SJohn Marino or memory location and is used infrequently; a REG_LIVE_LENGTH of -2 is
622*e4b17023SJohn Marino parameter when there is no frame pointer that is not allocated a register.
623*e4b17023SJohn Marino For now, we just reject them, rather than incrementing the live length. */
624*e4b17023SJohn Marino
625*e4b17023SJohn Marino if (REG_P (src)
626*e4b17023SJohn Marino && REG_LIVE_LENGTH (REGNO (src)) > 0
627*e4b17023SJohn Marino && REG_P (dest)
628*e4b17023SJohn Marino && REG_LIVE_LENGTH (REGNO (dest)) > 0
629*e4b17023SJohn Marino && (set = single_set (insn)) != NULL_RTX
630*e4b17023SJohn Marino && !reg_mentioned_p (dest, SET_SRC (set))
631*e4b17023SJohn Marino && GET_MODE (src) == GET_MODE (dest))
632*e4b17023SJohn Marino {
633*e4b17023SJohn Marino int old_num_regs = reg_rtx_no;
634*e4b17023SJohn Marino
635*e4b17023SJohn Marino /* Generate the src->dest move. */
636*e4b17023SJohn Marino start_sequence ();
637*e4b17023SJohn Marino emit_move_insn (dest, src);
638*e4b17023SJohn Marino seq = get_insns ();
639*e4b17023SJohn Marino end_sequence ();
640*e4b17023SJohn Marino /* If this sequence uses new registers, we may not use it. */
641*e4b17023SJohn Marino if (old_num_regs != reg_rtx_no
642*e4b17023SJohn Marino || ! validate_replace_rtx (src, dest, insn))
643*e4b17023SJohn Marino {
644*e4b17023SJohn Marino /* We have to restore reg_rtx_no to its old value, lest
645*e4b17023SJohn Marino recompute_reg_usage will try to compute the usage of the
646*e4b17023SJohn Marino new regs, yet reg_n_info is not valid for them. */
647*e4b17023SJohn Marino reg_rtx_no = old_num_regs;
648*e4b17023SJohn Marino return;
649*e4b17023SJohn Marino }
650*e4b17023SJohn Marino emit_insn_before (seq, insn);
651*e4b17023SJohn Marino move_insn = PREV_INSN (insn);
652*e4b17023SJohn Marino p_move_notes = ®_NOTES (move_insn);
653*e4b17023SJohn Marino p_insn_notes = ®_NOTES (insn);
654*e4b17023SJohn Marino
655*e4b17023SJohn Marino /* Move any notes mentioning src to the move instruction. */
656*e4b17023SJohn Marino for (link = REG_NOTES (insn); link != NULL_RTX; link = next)
657*e4b17023SJohn Marino {
658*e4b17023SJohn Marino next = XEXP (link, 1);
659*e4b17023SJohn Marino if (XEXP (link, 0) == src)
660*e4b17023SJohn Marino {
661*e4b17023SJohn Marino *p_move_notes = link;
662*e4b17023SJohn Marino p_move_notes = &XEXP (link, 1);
663*e4b17023SJohn Marino }
664*e4b17023SJohn Marino else
665*e4b17023SJohn Marino {
666*e4b17023SJohn Marino *p_insn_notes = link;
667*e4b17023SJohn Marino p_insn_notes = &XEXP (link, 1);
668*e4b17023SJohn Marino }
669*e4b17023SJohn Marino }
670*e4b17023SJohn Marino
671*e4b17023SJohn Marino *p_move_notes = NULL_RTX;
672*e4b17023SJohn Marino *p_insn_notes = NULL_RTX;
673*e4b17023SJohn Marino
674*e4b17023SJohn Marino /* Update the various register tables. */
675*e4b17023SJohn Marino dest_regno = REGNO (dest);
676*e4b17023SJohn Marino INC_REG_N_SETS (dest_regno, 1);
677*e4b17023SJohn Marino REG_LIVE_LENGTH (dest_regno)++;
678*e4b17023SJohn Marino src_regno = REGNO (src);
679*e4b17023SJohn Marino if (! find_reg_note (move_insn, REG_DEAD, src))
680*e4b17023SJohn Marino REG_LIVE_LENGTH (src_regno)++;
681*e4b17023SJohn Marino }
682*e4b17023SJohn Marino }
683*e4b17023SJohn Marino
684*e4b17023SJohn Marino /* reg_set_in_bb[REGNO] points to basic block iff the register is set
685*e4b17023SJohn Marino only once in the given block and has REG_EQUAL note. */
686*e4b17023SJohn Marino
687*e4b17023SJohn Marino static basic_block *reg_set_in_bb;
688*e4b17023SJohn Marino
689*e4b17023SJohn Marino /* Size of reg_set_in_bb array. */
690*e4b17023SJohn Marino static unsigned int max_reg_computed;
691*e4b17023SJohn Marino
692*e4b17023SJohn Marino
693*e4b17023SJohn Marino /* Return whether REG is set in only one location, and is set to a
694*e4b17023SJohn Marino constant, but is set in a different basic block from INSN (an
695*e4b17023SJohn Marino instructions which uses REG). In this case REG is equivalent to a
696*e4b17023SJohn Marino constant, and we don't want to break that equivalence, because that
697*e4b17023SJohn Marino may increase register pressure and make reload harder. If REG is
698*e4b17023SJohn Marino set in the same basic block as INSN, we don't worry about it,
699*e4b17023SJohn Marino because we'll probably need a register anyhow (??? but what if REG
700*e4b17023SJohn Marino is used in a different basic block as well as this one?). */
701*e4b17023SJohn Marino
702*e4b17023SJohn Marino static bool
reg_is_remote_constant_p(rtx reg,rtx insn)703*e4b17023SJohn Marino reg_is_remote_constant_p (rtx reg, rtx insn)
704*e4b17023SJohn Marino {
705*e4b17023SJohn Marino basic_block bb;
706*e4b17023SJohn Marino rtx p;
707*e4b17023SJohn Marino int max;
708*e4b17023SJohn Marino
709*e4b17023SJohn Marino if (!reg_set_in_bb)
710*e4b17023SJohn Marino {
711*e4b17023SJohn Marino max_reg_computed = max = max_reg_num ();
712*e4b17023SJohn Marino reg_set_in_bb = XCNEWVEC (basic_block, max);
713*e4b17023SJohn Marino
714*e4b17023SJohn Marino FOR_EACH_BB (bb)
715*e4b17023SJohn Marino FOR_BB_INSNS (bb, p)
716*e4b17023SJohn Marino {
717*e4b17023SJohn Marino rtx s;
718*e4b17023SJohn Marino
719*e4b17023SJohn Marino if (!INSN_P (p))
720*e4b17023SJohn Marino continue;
721*e4b17023SJohn Marino s = single_set (p);
722*e4b17023SJohn Marino /* This is the instruction which sets REG. If there is a
723*e4b17023SJohn Marino REG_EQUAL note, then REG is equivalent to a constant. */
724*e4b17023SJohn Marino if (s != 0
725*e4b17023SJohn Marino && REG_P (SET_DEST (s))
726*e4b17023SJohn Marino && REG_N_SETS (REGNO (SET_DEST (s))) == 1
727*e4b17023SJohn Marino && find_reg_note (p, REG_EQUAL, NULL_RTX))
728*e4b17023SJohn Marino reg_set_in_bb[REGNO (SET_DEST (s))] = bb;
729*e4b17023SJohn Marino }
730*e4b17023SJohn Marino }
731*e4b17023SJohn Marino
732*e4b17023SJohn Marino gcc_assert (REGNO (reg) < max_reg_computed);
733*e4b17023SJohn Marino if (reg_set_in_bb[REGNO (reg)] == NULL)
734*e4b17023SJohn Marino return false;
735*e4b17023SJohn Marino return (reg_set_in_bb[REGNO (reg)] != BLOCK_FOR_INSN (insn));
736*e4b17023SJohn Marino }
737*e4b17023SJohn Marino
738*e4b17023SJohn Marino /* INSN is adding a CONST_INT to a REG. We search backwards looking for
739*e4b17023SJohn Marino another add immediate instruction with the same source and dest registers,
740*e4b17023SJohn Marino and if we find one, we change INSN to an increment, and return 1. If
741*e4b17023SJohn Marino no changes are made, we return 0.
742*e4b17023SJohn Marino
743*e4b17023SJohn Marino This changes
744*e4b17023SJohn Marino (set (reg100) (plus reg1 offset1))
745*e4b17023SJohn Marino ...
746*e4b17023SJohn Marino (set (reg100) (plus reg1 offset2))
747*e4b17023SJohn Marino to
748*e4b17023SJohn Marino (set (reg100) (plus reg1 offset1))
749*e4b17023SJohn Marino ...
750*e4b17023SJohn Marino (set (reg100) (plus reg100 offset2-offset1)) */
751*e4b17023SJohn Marino
752*e4b17023SJohn Marino /* ??? What does this comment mean? */
753*e4b17023SJohn Marino /* cse disrupts preincrement / postdecrement sequences when it finds a
754*e4b17023SJohn Marino hard register as ultimate source, like the frame pointer. */
755*e4b17023SJohn Marino
756*e4b17023SJohn Marino static int
fixup_match_2(rtx insn,rtx dst,rtx src,rtx offset)757*e4b17023SJohn Marino fixup_match_2 (rtx insn, rtx dst, rtx src, rtx offset)
758*e4b17023SJohn Marino {
759*e4b17023SJohn Marino rtx p, dst_death = 0;
760*e4b17023SJohn Marino int length, num_calls = 0, freq_calls = 0;
761*e4b17023SJohn Marino basic_block bb = BLOCK_FOR_INSN (insn);
762*e4b17023SJohn Marino
763*e4b17023SJohn Marino /* If SRC dies in INSN, we'd have to move the death note. This is
764*e4b17023SJohn Marino considered to be very unlikely, so we just skip the optimization
765*e4b17023SJohn Marino in this case. */
766*e4b17023SJohn Marino if (find_regno_note (insn, REG_DEAD, REGNO (src)))
767*e4b17023SJohn Marino return 0;
768*e4b17023SJohn Marino
769*e4b17023SJohn Marino /* Scan backward to find the first instruction that sets DST. */
770*e4b17023SJohn Marino
771*e4b17023SJohn Marino for (length = 0, p = PREV_INSN (insn); p; p = PREV_INSN (p))
772*e4b17023SJohn Marino {
773*e4b17023SJohn Marino rtx pset;
774*e4b17023SJohn Marino
775*e4b17023SJohn Marino if (! INSN_P (p))
776*e4b17023SJohn Marino continue;
777*e4b17023SJohn Marino if (BLOCK_FOR_INSN (p) != bb)
778*e4b17023SJohn Marino break;
779*e4b17023SJohn Marino
780*e4b17023SJohn Marino if (find_regno_note (p, REG_DEAD, REGNO (dst)))
781*e4b17023SJohn Marino dst_death = p;
782*e4b17023SJohn Marino if (! dst_death && !DEBUG_INSN_P (p))
783*e4b17023SJohn Marino length++;
784*e4b17023SJohn Marino
785*e4b17023SJohn Marino pset = single_set (p);
786*e4b17023SJohn Marino if (pset && SET_DEST (pset) == dst
787*e4b17023SJohn Marino && GET_CODE (SET_SRC (pset)) == PLUS
788*e4b17023SJohn Marino && XEXP (SET_SRC (pset), 0) == src
789*e4b17023SJohn Marino && CONST_INT_P (XEXP (SET_SRC (pset), 1)))
790*e4b17023SJohn Marino {
791*e4b17023SJohn Marino HOST_WIDE_INT newconst
792*e4b17023SJohn Marino = INTVAL (offset) - INTVAL (XEXP (SET_SRC (pset), 1));
793*e4b17023SJohn Marino rtx add = gen_add3_insn (dst, dst, GEN_INT (newconst));
794*e4b17023SJohn Marino
795*e4b17023SJohn Marino if (add && validate_change (insn, &PATTERN (insn), add, 0))
796*e4b17023SJohn Marino {
797*e4b17023SJohn Marino /* Remove the death note for DST from DST_DEATH. */
798*e4b17023SJohn Marino if (dst_death)
799*e4b17023SJohn Marino {
800*e4b17023SJohn Marino remove_death (REGNO (dst), dst_death);
801*e4b17023SJohn Marino REG_LIVE_LENGTH (REGNO (dst)) += length;
802*e4b17023SJohn Marino REG_N_CALLS_CROSSED (REGNO (dst)) += num_calls;
803*e4b17023SJohn Marino REG_FREQ_CALLS_CROSSED (REGNO (dst)) += freq_calls;
804*e4b17023SJohn Marino }
805*e4b17023SJohn Marino
806*e4b17023SJohn Marino if (dump_file)
807*e4b17023SJohn Marino fprintf (dump_file,
808*e4b17023SJohn Marino "Fixed operand of insn %d.\n",
809*e4b17023SJohn Marino INSN_UID (insn));
810*e4b17023SJohn Marino
811*e4b17023SJohn Marino #ifdef AUTO_INC_DEC
812*e4b17023SJohn Marino for (p = PREV_INSN (insn); p; p = PREV_INSN (p))
813*e4b17023SJohn Marino {
814*e4b17023SJohn Marino if (! INSN_P (p))
815*e4b17023SJohn Marino continue;
816*e4b17023SJohn Marino if (BLOCK_FOR_INSN (p) != bb)
817*e4b17023SJohn Marino break;
818*e4b17023SJohn Marino if (reg_overlap_mentioned_p (dst, PATTERN (p)))
819*e4b17023SJohn Marino {
820*e4b17023SJohn Marino if (try_auto_increment (p, insn, 0, dst, newconst, 0))
821*e4b17023SJohn Marino return 1;
822*e4b17023SJohn Marino break;
823*e4b17023SJohn Marino }
824*e4b17023SJohn Marino }
825*e4b17023SJohn Marino for (p = NEXT_INSN (insn); p; p = NEXT_INSN (p))
826*e4b17023SJohn Marino {
827*e4b17023SJohn Marino if (! INSN_P (p))
828*e4b17023SJohn Marino continue;
829*e4b17023SJohn Marino if (BLOCK_FOR_INSN (p) != bb)
830*e4b17023SJohn Marino break;
831*e4b17023SJohn Marino if (reg_overlap_mentioned_p (dst, PATTERN (p)))
832*e4b17023SJohn Marino {
833*e4b17023SJohn Marino try_auto_increment (p, insn, 0, dst, newconst, 1);
834*e4b17023SJohn Marino break;
835*e4b17023SJohn Marino }
836*e4b17023SJohn Marino }
837*e4b17023SJohn Marino #endif
838*e4b17023SJohn Marino return 1;
839*e4b17023SJohn Marino }
840*e4b17023SJohn Marino }
841*e4b17023SJohn Marino
842*e4b17023SJohn Marino if (reg_set_p (dst, PATTERN (p)))
843*e4b17023SJohn Marino break;
844*e4b17023SJohn Marino
845*e4b17023SJohn Marino /* If we have passed a call instruction, and the
846*e4b17023SJohn Marino pseudo-reg SRC is not already live across a call,
847*e4b17023SJohn Marino then don't perform the optimization. */
848*e4b17023SJohn Marino /* reg_set_p is overly conservative for CALL_INSNS, thinks that all
849*e4b17023SJohn Marino hard regs are clobbered. Thus, we only use it for src for
850*e4b17023SJohn Marino non-call insns. */
851*e4b17023SJohn Marino if (CALL_P (p))
852*e4b17023SJohn Marino {
853*e4b17023SJohn Marino if (! dst_death)
854*e4b17023SJohn Marino {
855*e4b17023SJohn Marino num_calls++;
856*e4b17023SJohn Marino freq_calls += REG_FREQ_FROM_BB (BLOCK_FOR_INSN (p));
857*e4b17023SJohn Marino }
858*e4b17023SJohn Marino
859*e4b17023SJohn Marino if (REG_N_CALLS_CROSSED (REGNO (src)) == 0)
860*e4b17023SJohn Marino break;
861*e4b17023SJohn Marino
862*e4b17023SJohn Marino if ((HARD_REGISTER_P (dst) && call_used_regs [REGNO (dst)])
863*e4b17023SJohn Marino || find_reg_fusage (p, CLOBBER, dst))
864*e4b17023SJohn Marino break;
865*e4b17023SJohn Marino }
866*e4b17023SJohn Marino else if (reg_set_p (src, PATTERN (p)))
867*e4b17023SJohn Marino break;
868*e4b17023SJohn Marino }
869*e4b17023SJohn Marino
870*e4b17023SJohn Marino return 0;
871*e4b17023SJohn Marino }
872*e4b17023SJohn Marino
873*e4b17023SJohn Marino /* A forward pass. Replace output operands with input operands. */
874*e4b17023SJohn Marino
875*e4b17023SJohn Marino static void
regmove_forward_pass(void)876*e4b17023SJohn Marino regmove_forward_pass (void)
877*e4b17023SJohn Marino {
878*e4b17023SJohn Marino basic_block bb;
879*e4b17023SJohn Marino rtx insn;
880*e4b17023SJohn Marino
881*e4b17023SJohn Marino if (! flag_expensive_optimizations)
882*e4b17023SJohn Marino return;
883*e4b17023SJohn Marino
884*e4b17023SJohn Marino if (dump_file)
885*e4b17023SJohn Marino fprintf (dump_file, "Starting forward pass...\n");
886*e4b17023SJohn Marino
887*e4b17023SJohn Marino FOR_EACH_BB (bb)
888*e4b17023SJohn Marino {
889*e4b17023SJohn Marino FOR_BB_INSNS (bb, insn)
890*e4b17023SJohn Marino {
891*e4b17023SJohn Marino rtx set = single_set (insn);
892*e4b17023SJohn Marino if (! set)
893*e4b17023SJohn Marino continue;
894*e4b17023SJohn Marino
895*e4b17023SJohn Marino if ((GET_CODE (SET_SRC (set)) == SIGN_EXTEND
896*e4b17023SJohn Marino || GET_CODE (SET_SRC (set)) == ZERO_EXTEND)
897*e4b17023SJohn Marino && REG_P (XEXP (SET_SRC (set), 0))
898*e4b17023SJohn Marino && REG_P (SET_DEST (set)))
899*e4b17023SJohn Marino optimize_reg_copy_3 (insn, SET_DEST (set), SET_SRC (set));
900*e4b17023SJohn Marino
901*e4b17023SJohn Marino if (REG_P (SET_SRC (set))
902*e4b17023SJohn Marino && REG_P (SET_DEST (set)))
903*e4b17023SJohn Marino {
904*e4b17023SJohn Marino /* If this is a register-register copy where SRC is not dead,
905*e4b17023SJohn Marino see if we can optimize it. If this optimization succeeds,
906*e4b17023SJohn Marino it will become a copy where SRC is dead. */
907*e4b17023SJohn Marino if ((find_reg_note (insn, REG_DEAD, SET_SRC (set))
908*e4b17023SJohn Marino || optimize_reg_copy_1 (insn, SET_DEST (set), SET_SRC (set)))
909*e4b17023SJohn Marino && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
910*e4b17023SJohn Marino {
911*e4b17023SJohn Marino /* Similarly for a pseudo-pseudo copy when SRC is dead. */
912*e4b17023SJohn Marino if (REGNO (SET_SRC (set)) >= FIRST_PSEUDO_REGISTER)
913*e4b17023SJohn Marino optimize_reg_copy_2 (insn, SET_DEST (set), SET_SRC (set));
914*e4b17023SJohn Marino if (regno_src_regno[REGNO (SET_DEST (set))] < 0
915*e4b17023SJohn Marino && SET_SRC (set) != SET_DEST (set))
916*e4b17023SJohn Marino {
917*e4b17023SJohn Marino int srcregno = REGNO (SET_SRC (set));
918*e4b17023SJohn Marino if (regno_src_regno[srcregno] >= 0)
919*e4b17023SJohn Marino srcregno = regno_src_regno[srcregno];
920*e4b17023SJohn Marino regno_src_regno[REGNO (SET_DEST (set))] = srcregno;
921*e4b17023SJohn Marino }
922*e4b17023SJohn Marino }
923*e4b17023SJohn Marino }
924*e4b17023SJohn Marino }
925*e4b17023SJohn Marino }
926*e4b17023SJohn Marino }
927*e4b17023SJohn Marino
928*e4b17023SJohn Marino /* A backward pass. Replace input operands with output operands. */
929*e4b17023SJohn Marino
930*e4b17023SJohn Marino static void
regmove_backward_pass(void)931*e4b17023SJohn Marino regmove_backward_pass (void)
932*e4b17023SJohn Marino {
933*e4b17023SJohn Marino basic_block bb;
934*e4b17023SJohn Marino rtx insn, prev;
935*e4b17023SJohn Marino
936*e4b17023SJohn Marino if (dump_file)
937*e4b17023SJohn Marino fprintf (dump_file, "Starting backward pass...\n");
938*e4b17023SJohn Marino
939*e4b17023SJohn Marino FOR_EACH_BB_REVERSE (bb)
940*e4b17023SJohn Marino {
941*e4b17023SJohn Marino /* ??? Use the safe iterator because fixup_match_2 can remove
942*e4b17023SJohn Marino insns via try_auto_increment. */
943*e4b17023SJohn Marino FOR_BB_INSNS_REVERSE_SAFE (bb, insn, prev)
944*e4b17023SJohn Marino {
945*e4b17023SJohn Marino struct match match;
946*e4b17023SJohn Marino rtx copy_src, copy_dst;
947*e4b17023SJohn Marino int op_no, match_no;
948*e4b17023SJohn Marino int success = 0;
949*e4b17023SJohn Marino
950*e4b17023SJohn Marino if (! INSN_P (insn))
951*e4b17023SJohn Marino continue;
952*e4b17023SJohn Marino
953*e4b17023SJohn Marino if (! find_matches (insn, &match))
954*e4b17023SJohn Marino continue;
955*e4b17023SJohn Marino
956*e4b17023SJohn Marino /* Now scan through the operands looking for a destination operand
957*e4b17023SJohn Marino which is supposed to match a source operand.
958*e4b17023SJohn Marino Then scan backward for an instruction which sets the source
959*e4b17023SJohn Marino operand. If safe, then replace the source operand with the
960*e4b17023SJohn Marino dest operand in both instructions. */
961*e4b17023SJohn Marino
962*e4b17023SJohn Marino copy_src = NULL_RTX;
963*e4b17023SJohn Marino copy_dst = NULL_RTX;
964*e4b17023SJohn Marino for (op_no = 0; op_no < recog_data.n_operands; op_no++)
965*e4b17023SJohn Marino {
966*e4b17023SJohn Marino rtx set, p, src, dst;
967*e4b17023SJohn Marino rtx src_note, dst_note;
968*e4b17023SJohn Marino int num_calls = 0, freq_calls = 0;
969*e4b17023SJohn Marino enum reg_class src_class, dst_class;
970*e4b17023SJohn Marino int length;
971*e4b17023SJohn Marino
972*e4b17023SJohn Marino match_no = match.with[op_no];
973*e4b17023SJohn Marino
974*e4b17023SJohn Marino /* Nothing to do if the two operands aren't supposed to match. */
975*e4b17023SJohn Marino if (match_no < 0)
976*e4b17023SJohn Marino continue;
977*e4b17023SJohn Marino
978*e4b17023SJohn Marino dst = recog_data.operand[match_no];
979*e4b17023SJohn Marino src = recog_data.operand[op_no];
980*e4b17023SJohn Marino
981*e4b17023SJohn Marino if (!REG_P (src))
982*e4b17023SJohn Marino continue;
983*e4b17023SJohn Marino
984*e4b17023SJohn Marino if (!REG_P (dst)
985*e4b17023SJohn Marino || REGNO (dst) < FIRST_PSEUDO_REGISTER
986*e4b17023SJohn Marino || REG_LIVE_LENGTH (REGNO (dst)) < 0
987*e4b17023SJohn Marino || GET_MODE (src) != GET_MODE (dst))
988*e4b17023SJohn Marino continue;
989*e4b17023SJohn Marino
990*e4b17023SJohn Marino /* If the operands already match, then there is nothing to do. */
991*e4b17023SJohn Marino if (operands_match_p (src, dst))
992*e4b17023SJohn Marino continue;
993*e4b17023SJohn Marino
994*e4b17023SJohn Marino if (match.commutative[op_no] >= 0)
995*e4b17023SJohn Marino {
996*e4b17023SJohn Marino rtx comm = recog_data.operand[match.commutative[op_no]];
997*e4b17023SJohn Marino if (operands_match_p (comm, dst))
998*e4b17023SJohn Marino continue;
999*e4b17023SJohn Marino }
1000*e4b17023SJohn Marino
1001*e4b17023SJohn Marino set = single_set (insn);
1002*e4b17023SJohn Marino if (! set)
1003*e4b17023SJohn Marino continue;
1004*e4b17023SJohn Marino
1005*e4b17023SJohn Marino /* Note that single_set ignores parts of a parallel set for
1006*e4b17023SJohn Marino which one of the destinations is REG_UNUSED. We can't
1007*e4b17023SJohn Marino handle that here, since we can wind up rewriting things
1008*e4b17023SJohn Marino such that a single register is set twice within a single
1009*e4b17023SJohn Marino parallel. */
1010*e4b17023SJohn Marino if (reg_set_p (src, insn))
1011*e4b17023SJohn Marino continue;
1012*e4b17023SJohn Marino
1013*e4b17023SJohn Marino /* match_no/dst must be a write-only operand, and
1014*e4b17023SJohn Marino operand_operand/src must be a read-only operand. */
1015*e4b17023SJohn Marino if (match.use[op_no] != READ
1016*e4b17023SJohn Marino || match.use[match_no] != WRITE)
1017*e4b17023SJohn Marino continue;
1018*e4b17023SJohn Marino
1019*e4b17023SJohn Marino if (match.early_clobber[match_no]
1020*e4b17023SJohn Marino && count_occurrences (PATTERN (insn), src, 0) > 1)
1021*e4b17023SJohn Marino continue;
1022*e4b17023SJohn Marino
1023*e4b17023SJohn Marino /* Make sure match_no is the destination. */
1024*e4b17023SJohn Marino if (recog_data.operand[match_no] != SET_DEST (set))
1025*e4b17023SJohn Marino continue;
1026*e4b17023SJohn Marino
1027*e4b17023SJohn Marino if (REGNO (src) < FIRST_PSEUDO_REGISTER)
1028*e4b17023SJohn Marino {
1029*e4b17023SJohn Marino if (GET_CODE (SET_SRC (set)) == PLUS
1030*e4b17023SJohn Marino && CONST_INT_P (XEXP (SET_SRC (set), 1))
1031*e4b17023SJohn Marino && XEXP (SET_SRC (set), 0) == src
1032*e4b17023SJohn Marino && fixup_match_2 (insn, dst, src,
1033*e4b17023SJohn Marino XEXP (SET_SRC (set), 1)))
1034*e4b17023SJohn Marino break;
1035*e4b17023SJohn Marino continue;
1036*e4b17023SJohn Marino }
1037*e4b17023SJohn Marino src_class = reg_preferred_class (REGNO (src));
1038*e4b17023SJohn Marino dst_class = reg_preferred_class (REGNO (dst));
1039*e4b17023SJohn Marino
1040*e4b17023SJohn Marino if (! (src_note = find_reg_note (insn, REG_DEAD, src)))
1041*e4b17023SJohn Marino {
1042*e4b17023SJohn Marino /* We used to force the copy here like in other cases, but
1043*e4b17023SJohn Marino it produces worse code, as it eliminates no copy
1044*e4b17023SJohn Marino instructions and the copy emitted will be produced by
1045*e4b17023SJohn Marino reload anyway. On patterns with multiple alternatives,
1046*e4b17023SJohn Marino there may be better solution available.
1047*e4b17023SJohn Marino
1048*e4b17023SJohn Marino In particular this change produced slower code for numeric
1049*e4b17023SJohn Marino i387 programs. */
1050*e4b17023SJohn Marino
1051*e4b17023SJohn Marino continue;
1052*e4b17023SJohn Marino }
1053*e4b17023SJohn Marino
1054*e4b17023SJohn Marino if (! regclass_compatible_p (src_class, dst_class))
1055*e4b17023SJohn Marino {
1056*e4b17023SJohn Marino if (!copy_src)
1057*e4b17023SJohn Marino {
1058*e4b17023SJohn Marino copy_src = src;
1059*e4b17023SJohn Marino copy_dst = dst;
1060*e4b17023SJohn Marino }
1061*e4b17023SJohn Marino continue;
1062*e4b17023SJohn Marino }
1063*e4b17023SJohn Marino
1064*e4b17023SJohn Marino /* Can not modify an earlier insn to set dst if this insn
1065*e4b17023SJohn Marino uses an old value in the source. */
1066*e4b17023SJohn Marino if (reg_overlap_mentioned_p (dst, SET_SRC (set)))
1067*e4b17023SJohn Marino {
1068*e4b17023SJohn Marino if (!copy_src)
1069*e4b17023SJohn Marino {
1070*e4b17023SJohn Marino copy_src = src;
1071*e4b17023SJohn Marino copy_dst = dst;
1072*e4b17023SJohn Marino }
1073*e4b17023SJohn Marino continue;
1074*e4b17023SJohn Marino }
1075*e4b17023SJohn Marino
1076*e4b17023SJohn Marino /* If src is set once in a different basic block,
1077*e4b17023SJohn Marino and is set equal to a constant, then do not use
1078*e4b17023SJohn Marino it for this optimization, as this would make it
1079*e4b17023SJohn Marino no longer equivalent to a constant. */
1080*e4b17023SJohn Marino
1081*e4b17023SJohn Marino if (reg_is_remote_constant_p (src, insn))
1082*e4b17023SJohn Marino {
1083*e4b17023SJohn Marino if (!copy_src)
1084*e4b17023SJohn Marino {
1085*e4b17023SJohn Marino copy_src = src;
1086*e4b17023SJohn Marino copy_dst = dst;
1087*e4b17023SJohn Marino }
1088*e4b17023SJohn Marino continue;
1089*e4b17023SJohn Marino }
1090*e4b17023SJohn Marino
1091*e4b17023SJohn Marino
1092*e4b17023SJohn Marino if (dump_file)
1093*e4b17023SJohn Marino fprintf (dump_file,
1094*e4b17023SJohn Marino "Could fix operand %d of insn %d matching operand %d.\n",
1095*e4b17023SJohn Marino op_no, INSN_UID (insn), match_no);
1096*e4b17023SJohn Marino
1097*e4b17023SJohn Marino /* Scan backward to find the first instruction that uses
1098*e4b17023SJohn Marino the input operand. If the operand is set here, then
1099*e4b17023SJohn Marino replace it in both instructions with match_no. */
1100*e4b17023SJohn Marino
1101*e4b17023SJohn Marino for (length = 0, p = PREV_INSN (insn); p; p = PREV_INSN (p))
1102*e4b17023SJohn Marino {
1103*e4b17023SJohn Marino rtx pset;
1104*e4b17023SJohn Marino
1105*e4b17023SJohn Marino if (! INSN_P (p))
1106*e4b17023SJohn Marino continue;
1107*e4b17023SJohn Marino if (BLOCK_FOR_INSN (p) != bb)
1108*e4b17023SJohn Marino break;
1109*e4b17023SJohn Marino
1110*e4b17023SJohn Marino if (!DEBUG_INSN_P (p))
1111*e4b17023SJohn Marino length++;
1112*e4b17023SJohn Marino
1113*e4b17023SJohn Marino /* ??? See if all of SRC is set in P. This test is much
1114*e4b17023SJohn Marino more conservative than it needs to be. */
1115*e4b17023SJohn Marino pset = single_set (p);
1116*e4b17023SJohn Marino if (pset && SET_DEST (pset) == src)
1117*e4b17023SJohn Marino {
1118*e4b17023SJohn Marino /* We use validate_replace_rtx, in case there
1119*e4b17023SJohn Marino are multiple identical source operands. All
1120*e4b17023SJohn Marino of them have to be changed at the same time:
1121*e4b17023SJohn Marino when validate_replace_rtx() calls
1122*e4b17023SJohn Marino apply_change_group(). */
1123*e4b17023SJohn Marino validate_change (p, &SET_DEST (pset), dst, 1);
1124*e4b17023SJohn Marino if (validate_replace_rtx (src, dst, insn))
1125*e4b17023SJohn Marino success = 1;
1126*e4b17023SJohn Marino break;
1127*e4b17023SJohn Marino }
1128*e4b17023SJohn Marino
1129*e4b17023SJohn Marino /* We can't make this change if DST is mentioned at
1130*e4b17023SJohn Marino all in P, since we are going to change its value.
1131*e4b17023SJohn Marino We can't make this change if SRC is read or
1132*e4b17023SJohn Marino partially written in P, since we are going to
1133*e4b17023SJohn Marino eliminate SRC. However, if it's a debug insn, we
1134*e4b17023SJohn Marino can't refrain from making the change, for this
1135*e4b17023SJohn Marino would cause codegen differences, so instead we
1136*e4b17023SJohn Marino invalidate debug expressions that reference DST,
1137*e4b17023SJohn Marino and adjust references to SRC in them so that they
1138*e4b17023SJohn Marino become references to DST. */
1139*e4b17023SJohn Marino if (reg_mentioned_p (dst, PATTERN (p)))
1140*e4b17023SJohn Marino {
1141*e4b17023SJohn Marino if (DEBUG_INSN_P (p))
1142*e4b17023SJohn Marino validate_change (p, &INSN_VAR_LOCATION_LOC (p),
1143*e4b17023SJohn Marino gen_rtx_UNKNOWN_VAR_LOC (), 1);
1144*e4b17023SJohn Marino else
1145*e4b17023SJohn Marino break;
1146*e4b17023SJohn Marino }
1147*e4b17023SJohn Marino if (reg_overlap_mentioned_p (src, PATTERN (p)))
1148*e4b17023SJohn Marino {
1149*e4b17023SJohn Marino if (DEBUG_INSN_P (p))
1150*e4b17023SJohn Marino validate_replace_rtx_group (src, dst, p);
1151*e4b17023SJohn Marino else
1152*e4b17023SJohn Marino break;
1153*e4b17023SJohn Marino }
1154*e4b17023SJohn Marino
1155*e4b17023SJohn Marino /* If we have passed a call instruction, and the
1156*e4b17023SJohn Marino pseudo-reg DST is not already live across a call,
1157*e4b17023SJohn Marino then don't perform the optimization. */
1158*e4b17023SJohn Marino if (CALL_P (p))
1159*e4b17023SJohn Marino {
1160*e4b17023SJohn Marino num_calls++;
1161*e4b17023SJohn Marino freq_calls += REG_FREQ_FROM_BB (BLOCK_FOR_INSN (p));
1162*e4b17023SJohn Marino
1163*e4b17023SJohn Marino if (REG_N_CALLS_CROSSED (REGNO (dst)) == 0)
1164*e4b17023SJohn Marino break;
1165*e4b17023SJohn Marino }
1166*e4b17023SJohn Marino }
1167*e4b17023SJohn Marino
1168*e4b17023SJohn Marino if (success)
1169*e4b17023SJohn Marino {
1170*e4b17023SJohn Marino int dstno, srcno;
1171*e4b17023SJohn Marino
1172*e4b17023SJohn Marino /* Remove the death note for SRC from INSN. */
1173*e4b17023SJohn Marino remove_note (insn, src_note);
1174*e4b17023SJohn Marino /* Move the death note for SRC to P if it is used
1175*e4b17023SJohn Marino there. */
1176*e4b17023SJohn Marino if (reg_overlap_mentioned_p (src, PATTERN (p)))
1177*e4b17023SJohn Marino {
1178*e4b17023SJohn Marino XEXP (src_note, 1) = REG_NOTES (p);
1179*e4b17023SJohn Marino REG_NOTES (p) = src_note;
1180*e4b17023SJohn Marino }
1181*e4b17023SJohn Marino /* If there is a REG_DEAD note for DST on P, then remove
1182*e4b17023SJohn Marino it, because DST is now set there. */
1183*e4b17023SJohn Marino if ((dst_note = find_reg_note (p, REG_DEAD, dst)))
1184*e4b17023SJohn Marino remove_note (p, dst_note);
1185*e4b17023SJohn Marino
1186*e4b17023SJohn Marino dstno = REGNO (dst);
1187*e4b17023SJohn Marino srcno = REGNO (src);
1188*e4b17023SJohn Marino
1189*e4b17023SJohn Marino INC_REG_N_SETS (dstno, 1);
1190*e4b17023SJohn Marino INC_REG_N_SETS (srcno, -1);
1191*e4b17023SJohn Marino
1192*e4b17023SJohn Marino REG_N_CALLS_CROSSED (dstno) += num_calls;
1193*e4b17023SJohn Marino REG_N_CALLS_CROSSED (srcno) -= num_calls;
1194*e4b17023SJohn Marino REG_FREQ_CALLS_CROSSED (dstno) += freq_calls;
1195*e4b17023SJohn Marino REG_FREQ_CALLS_CROSSED (srcno) -= freq_calls;
1196*e4b17023SJohn Marino
1197*e4b17023SJohn Marino REG_LIVE_LENGTH (dstno) += length;
1198*e4b17023SJohn Marino if (REG_LIVE_LENGTH (srcno) >= 0)
1199*e4b17023SJohn Marino {
1200*e4b17023SJohn Marino REG_LIVE_LENGTH (srcno) -= length;
1201*e4b17023SJohn Marino /* REG_LIVE_LENGTH is only an approximation after
1202*e4b17023SJohn Marino combine if sched is not run, so make sure that we
1203*e4b17023SJohn Marino still have a reasonable value. */
1204*e4b17023SJohn Marino if (REG_LIVE_LENGTH (srcno) < 2)
1205*e4b17023SJohn Marino REG_LIVE_LENGTH (srcno) = 2;
1206*e4b17023SJohn Marino }
1207*e4b17023SJohn Marino
1208*e4b17023SJohn Marino if (dump_file)
1209*e4b17023SJohn Marino fprintf (dump_file,
1210*e4b17023SJohn Marino "Fixed operand %d of insn %d matching operand %d.\n",
1211*e4b17023SJohn Marino op_no, INSN_UID (insn), match_no);
1212*e4b17023SJohn Marino
1213*e4b17023SJohn Marino break;
1214*e4b17023SJohn Marino }
1215*e4b17023SJohn Marino else if (num_changes_pending () > 0)
1216*e4b17023SJohn Marino cancel_changes (0);
1217*e4b17023SJohn Marino }
1218*e4b17023SJohn Marino
1219*e4b17023SJohn Marino /* If we weren't able to replace any of the alternatives, try an
1220*e4b17023SJohn Marino alternative approach of copying the source to the destination. */
1221*e4b17023SJohn Marino if (!success && copy_src != NULL_RTX)
1222*e4b17023SJohn Marino copy_src_to_dest (insn, copy_src, copy_dst);
1223*e4b17023SJohn Marino }
1224*e4b17023SJohn Marino }
1225*e4b17023SJohn Marino }
1226*e4b17023SJohn Marino
1227*e4b17023SJohn Marino /* Main entry for the register move optimization. */
1228*e4b17023SJohn Marino
1229*e4b17023SJohn Marino static unsigned int
regmove_optimize(void)1230*e4b17023SJohn Marino regmove_optimize (void)
1231*e4b17023SJohn Marino {
1232*e4b17023SJohn Marino int i;
1233*e4b17023SJohn Marino int nregs = max_reg_num ();
1234*e4b17023SJohn Marino
1235*e4b17023SJohn Marino df_note_add_problem ();
1236*e4b17023SJohn Marino df_analyze ();
1237*e4b17023SJohn Marino
1238*e4b17023SJohn Marino regstat_init_n_sets_and_refs ();
1239*e4b17023SJohn Marino regstat_compute_ri ();
1240*e4b17023SJohn Marino
1241*e4b17023SJohn Marino if (flag_ira_loop_pressure)
1242*e4b17023SJohn Marino ira_set_pseudo_classes (dump_file);
1243*e4b17023SJohn Marino
1244*e4b17023SJohn Marino regno_src_regno = XNEWVEC (int, nregs);
1245*e4b17023SJohn Marino for (i = nregs; --i >= 0; )
1246*e4b17023SJohn Marino regno_src_regno[i] = -1;
1247*e4b17023SJohn Marino
1248*e4b17023SJohn Marino /* A forward pass. Replace output operands with input operands. */
1249*e4b17023SJohn Marino regmove_forward_pass ();
1250*e4b17023SJohn Marino
1251*e4b17023SJohn Marino /* A backward pass. Replace input operands with output operands. */
1252*e4b17023SJohn Marino regmove_backward_pass ();
1253*e4b17023SJohn Marino
1254*e4b17023SJohn Marino /* Clean up. */
1255*e4b17023SJohn Marino free (regno_src_regno);
1256*e4b17023SJohn Marino if (reg_set_in_bb)
1257*e4b17023SJohn Marino {
1258*e4b17023SJohn Marino free (reg_set_in_bb);
1259*e4b17023SJohn Marino reg_set_in_bb = NULL;
1260*e4b17023SJohn Marino }
1261*e4b17023SJohn Marino regstat_free_n_sets_and_refs ();
1262*e4b17023SJohn Marino regstat_free_ri ();
1263*e4b17023SJohn Marino if (flag_ira_loop_pressure)
1264*e4b17023SJohn Marino free_reg_info ();
1265*e4b17023SJohn Marino return 0;
1266*e4b17023SJohn Marino }
1267*e4b17023SJohn Marino
1268*e4b17023SJohn Marino /* Returns nonzero if INSN's pattern has matching constraints for any operand.
1269*e4b17023SJohn Marino Returns 0 if INSN can't be recognized, or if the alternative can't be
1270*e4b17023SJohn Marino determined.
1271*e4b17023SJohn Marino
1272*e4b17023SJohn Marino Initialize the info in MATCHP based on the constraints. */
1273*e4b17023SJohn Marino
1274*e4b17023SJohn Marino static int
find_matches(rtx insn,struct match * matchp)1275*e4b17023SJohn Marino find_matches (rtx insn, struct match *matchp)
1276*e4b17023SJohn Marino {
1277*e4b17023SJohn Marino int likely_spilled[MAX_RECOG_OPERANDS];
1278*e4b17023SJohn Marino int op_no;
1279*e4b17023SJohn Marino int any_matches = 0;
1280*e4b17023SJohn Marino
1281*e4b17023SJohn Marino extract_insn (insn);
1282*e4b17023SJohn Marino if (! constrain_operands (0))
1283*e4b17023SJohn Marino return 0;
1284*e4b17023SJohn Marino
1285*e4b17023SJohn Marino /* Must initialize this before main loop, because the code for
1286*e4b17023SJohn Marino the commutative case may set matches for operands other than
1287*e4b17023SJohn Marino the current one. */
1288*e4b17023SJohn Marino for (op_no = recog_data.n_operands; --op_no >= 0; )
1289*e4b17023SJohn Marino matchp->with[op_no] = matchp->commutative[op_no] = -1;
1290*e4b17023SJohn Marino
1291*e4b17023SJohn Marino for (op_no = 0; op_no < recog_data.n_operands; op_no++)
1292*e4b17023SJohn Marino {
1293*e4b17023SJohn Marino const char *p;
1294*e4b17023SJohn Marino char c;
1295*e4b17023SJohn Marino int i = 0;
1296*e4b17023SJohn Marino
1297*e4b17023SJohn Marino p = recog_data.constraints[op_no];
1298*e4b17023SJohn Marino
1299*e4b17023SJohn Marino likely_spilled[op_no] = 0;
1300*e4b17023SJohn Marino matchp->use[op_no] = READ;
1301*e4b17023SJohn Marino matchp->early_clobber[op_no] = 0;
1302*e4b17023SJohn Marino if (*p == '=')
1303*e4b17023SJohn Marino matchp->use[op_no] = WRITE;
1304*e4b17023SJohn Marino else if (*p == '+')
1305*e4b17023SJohn Marino matchp->use[op_no] = READWRITE;
1306*e4b17023SJohn Marino
1307*e4b17023SJohn Marino for (;*p && i < which_alternative; p++)
1308*e4b17023SJohn Marino if (*p == ',')
1309*e4b17023SJohn Marino i++;
1310*e4b17023SJohn Marino
1311*e4b17023SJohn Marino while ((c = *p) != '\0' && c != ',')
1312*e4b17023SJohn Marino {
1313*e4b17023SJohn Marino switch (c)
1314*e4b17023SJohn Marino {
1315*e4b17023SJohn Marino case '=':
1316*e4b17023SJohn Marino break;
1317*e4b17023SJohn Marino case '+':
1318*e4b17023SJohn Marino break;
1319*e4b17023SJohn Marino case '&':
1320*e4b17023SJohn Marino matchp->early_clobber[op_no] = 1;
1321*e4b17023SJohn Marino break;
1322*e4b17023SJohn Marino case '%':
1323*e4b17023SJohn Marino matchp->commutative[op_no] = op_no + 1;
1324*e4b17023SJohn Marino matchp->commutative[op_no + 1] = op_no;
1325*e4b17023SJohn Marino break;
1326*e4b17023SJohn Marino
1327*e4b17023SJohn Marino case '0': case '1': case '2': case '3': case '4':
1328*e4b17023SJohn Marino case '5': case '6': case '7': case '8': case '9':
1329*e4b17023SJohn Marino {
1330*e4b17023SJohn Marino char *end;
1331*e4b17023SJohn Marino unsigned long match_ul = strtoul (p, &end, 10);
1332*e4b17023SJohn Marino int match = match_ul;
1333*e4b17023SJohn Marino
1334*e4b17023SJohn Marino p = end;
1335*e4b17023SJohn Marino
1336*e4b17023SJohn Marino if (match < op_no && likely_spilled[match])
1337*e4b17023SJohn Marino continue;
1338*e4b17023SJohn Marino matchp->with[op_no] = match;
1339*e4b17023SJohn Marino any_matches = 1;
1340*e4b17023SJohn Marino if (matchp->commutative[op_no] >= 0)
1341*e4b17023SJohn Marino matchp->with[matchp->commutative[op_no]] = match;
1342*e4b17023SJohn Marino }
1343*e4b17023SJohn Marino continue;
1344*e4b17023SJohn Marino
1345*e4b17023SJohn Marino case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'h':
1346*e4b17023SJohn Marino case 'j': case 'k': case 'l': case 'p': case 'q': case 't': case 'u':
1347*e4b17023SJohn Marino case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B':
1348*e4b17023SJohn Marino case 'C': case 'D': case 'W': case 'Y': case 'Z':
1349*e4b17023SJohn Marino if (targetm.class_likely_spilled_p (REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)))
1350*e4b17023SJohn Marino likely_spilled[op_no] = 1;
1351*e4b17023SJohn Marino break;
1352*e4b17023SJohn Marino }
1353*e4b17023SJohn Marino p += CONSTRAINT_LEN (c, p);
1354*e4b17023SJohn Marino }
1355*e4b17023SJohn Marino }
1356*e4b17023SJohn Marino return any_matches;
1357*e4b17023SJohn Marino }
1358*e4b17023SJohn Marino
1359*e4b17023SJohn Marino
1360*e4b17023SJohn Marino
1361*e4b17023SJohn Marino static bool
gate_handle_regmove(void)1362*e4b17023SJohn Marino gate_handle_regmove (void)
1363*e4b17023SJohn Marino {
1364*e4b17023SJohn Marino return (optimize > 0 && flag_regmove);
1365*e4b17023SJohn Marino }
1366*e4b17023SJohn Marino
1367*e4b17023SJohn Marino
1368*e4b17023SJohn Marino struct rtl_opt_pass pass_regmove =
1369*e4b17023SJohn Marino {
1370*e4b17023SJohn Marino {
1371*e4b17023SJohn Marino RTL_PASS,
1372*e4b17023SJohn Marino "regmove", /* name */
1373*e4b17023SJohn Marino gate_handle_regmove, /* gate */
1374*e4b17023SJohn Marino regmove_optimize, /* execute */
1375*e4b17023SJohn Marino NULL, /* sub */
1376*e4b17023SJohn Marino NULL, /* next */
1377*e4b17023SJohn Marino 0, /* static_pass_number */
1378*e4b17023SJohn Marino TV_REGMOVE, /* tv_id */
1379*e4b17023SJohn Marino 0, /* properties_required */
1380*e4b17023SJohn Marino 0, /* properties_provided */
1381*e4b17023SJohn Marino 0, /* properties_destroyed */
1382*e4b17023SJohn Marino 0, /* todo_flags_start */
1383*e4b17023SJohn Marino TODO_df_finish | TODO_verify_rtl_sharing |
1384*e4b17023SJohn Marino TODO_ggc_collect /* todo_flags_finish */
1385*e4b17023SJohn Marino }
1386*e4b17023SJohn Marino };
1387