OSDN Git Service

* timevar.def (TV_SCEV_CONST): New timevar.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-opfinalize.h
1 /* SSA operand allocation and finalizing.
2    Copyright (C) 2005 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING.  If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA.  */
20
21
22 /* This file contains common code which is used by each of the 5 operand 
23    types.  Macros are defined to specify the varying components.
24
25    FINALIZE_FUNC - name of finalize function.
26    FINALIZE_ALLOC - name of allocation routine.
27    FINALIZE_FREE - name of free list.
28    FINALIZE_TYPE - type of node.
29    FINALIZE_OPS - Lead element in list.
30    FINALIZE_USE_PTR - How to get the use_operand_p, if this is a use operand.
31    FINALIZE_INITIALIZE - How to initialize an element.
32    FINALIZE_ELEM - How to retrieve an element.
33    FINALIZE_BASE - How to retrieve the base variable of an element.
34    FINALIZE_BASE_TYPE - Type of the base variable.
35    FINALIZE_OPBUILD - Opbuild array for these nodes.
36    FINALIZE_OPBUILD_ELEM - How to get an element from the opbuild list.
37    FINALIZE_OPBUILD_BASE - How to get an element base from the opbuild list.
38    FINALIZE_BASE_ZERO - How to zero an element.  */
39
40
41 /* This routine will either pick up a node from the free list, or allocate a
42    new one if need be.  */
43
44 static inline FINALIZE_TYPE *
45 FINALIZE_ALLOC (void)
46 {
47   FINALIZE_TYPE *ret;
48   if (FINALIZE_FREE)
49     {
50       ret = FINALIZE_FREE;
51       FINALIZE_FREE = FINALIZE_FREE->next;
52     }
53   else
54     ret = (FINALIZE_TYPE *)ssa_operand_alloc (sizeof (FINALIZE_TYPE));
55   return ret;
56 }
57
58
59
60 /* This routine will take the new operands from FINALIZE_OPBUILD and turn them
61    into the new operands for STMT.  All required linking and deleting is u
62    performed here.  */
63 static inline void
64 FINALIZE_FUNC (tree stmt)
65 {
66   int new_i;
67   FINALIZE_TYPE *old_ops, *ptr, *last;
68   FINALIZE_BASE_TYPE old_base;
69   FINALIZE_TYPE new_list;
70
71   new_list.next = NULL;
72   last = &new_list;
73
74   old_ops = FINALIZE_OPS (stmt);
75   if (old_ops)
76     old_base = FINALIZE_BASE (FINALIZE_ELEM (old_ops));
77   else
78     old_base = FINALIZE_BASE_ZERO;
79
80   new_i = opbuild_first (&FINALIZE_OPBUILD);
81   while (old_ops && new_i != OPBUILD_LAST)
82     {
83       FINALIZE_BASE_TYPE new_base = FINALIZE_OPBUILD_BASE (new_i);
84       if (old_base == new_base)
85         {
86           /* if variables are the same, reuse this node.  */
87           last->next = old_ops;
88           last = old_ops;
89 #ifdef FINALIZE_USE_PTR
90           correct_use_link (FINALIZE_USE_PTR (last), stmt);
91 #endif
92           old_ops = old_ops->next;
93           new_i = opbuild_next (&FINALIZE_OPBUILD, new_i);
94         }
95       else
96         if (old_base < new_base)
97           {
98             /* if old is less than new, old goes to the free list.  */
99 #ifdef FINALIZE_USE_PTR
100             use_operand_p use_p = FINALIZE_USE_PTR (old_ops);
101             delink_imm_use (use_p);
102 #endif
103             ptr = old_ops;
104             old_ops = old_ops->next;
105             ptr->next = FINALIZE_FREE;
106             FINALIZE_FREE = ptr;
107           }
108         else
109           {
110             /* This is a new operand.  */
111             ptr = FINALIZE_ALLOC ();
112             FINALIZE_INITIALIZE (ptr, FINALIZE_OPBUILD_ELEM (new_i), stmt);
113             last->next = ptr;
114             last = ptr;
115             new_i = opbuild_next (&FINALIZE_OPBUILD, new_i);
116           }
117       if (old_ops)
118         old_base = FINALIZE_BASE (FINALIZE_ELEM (old_ops));
119     }
120
121   /* If there is anything remaining in the opbuild list, simply emit them.  */
122   for ( ; 
123         new_i != OPBUILD_LAST; 
124         new_i = opbuild_next (&FINALIZE_OPBUILD, new_i))
125     {
126       ptr = FINALIZE_ALLOC ();
127       FINALIZE_INITIALIZE (ptr, FINALIZE_OPBUILD_ELEM (new_i), stmt);
128       last->next = ptr;
129       last = ptr;
130     }
131
132   last->next = NULL;
133
134   /* If there is anything in the old list, free them.  */
135   if (old_ops)
136     {
137 #ifdef FINALIZE_USE_PTR
138       for (ptr = old_ops; ptr; ptr = ptr->next)
139         {
140           use_operand_p use_p = FINALIZE_USE_PTR (ptr);
141           delink_imm_use (use_p);
142         }
143 #endif
144       old_ops->next = FINALIZE_FREE;
145       FINALIZE_FREE = old_ops;
146     }
147
148   /* NOw set the stmt's operands.  */
149   FINALIZE_OPS (stmt) = new_list.next;
150
151 #ifdef ENABLE_CHECKING
152   {
153     unsigned x = 0;
154     for (ptr = FINALIZE_OPS (stmt); ptr; ptr = ptr->next)
155       x++;
156
157     gcc_assert (x == opbuild_num_elems (&FINALIZE_OPBUILD));
158   }
159 #endif
160 }
161
162 #undef FINALIZE_FUNC
163 #undef FINALIZE_ALLOC
164 #undef FINALIZE_FREE
165 #undef FINALIZE_TYPE
166 #undef FINALIZE_OPS
167 #undef FINALIZE_USE_PTR
168 #undef FINALIZE_INITIALIZE
169 #undef FINALIZE_ELEM
170 #undef FINALIZE_BASE
171 #undef FINALIZE_BASE_TYPE
172 #undef FINALIZE_OPBUILD
173 #undef FINALIZE_OPBUILD_ELEM
174 #undef FINALIZE_OPBUILD_BASE
175 #undef FINALIZE_BASE_ZERO