2005-12-13 Paul Brook <paul@codesourcery.com>
[official-gcc.git] / gcc / tree-ssa-opfinalize.h
blobcc48e9ed742da0285647d456d5fe8976ea17d7e7
1 /* SSA operand allocation and finalizing.
2 Copyright (C) 2005 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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, 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301, USA. */
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.
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. */
41 /* This routine will either pick up a node from the free list, or allocate a
42 new one if need be. */
44 static inline FINALIZE_TYPE *
45 FINALIZE_ALLOC (void)
47 FINALIZE_TYPE *ret;
48 if (FINALIZE_FREE)
50 ret = FINALIZE_FREE;
51 FINALIZE_FREE = FINALIZE_FREE->next;
53 else
54 ret = (FINALIZE_TYPE *)ssa_operand_alloc (sizeof (FINALIZE_TYPE));
55 return ret;
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)
66 unsigned new_i;
67 FINALIZE_TYPE *old_ops, *ptr, *last;
68 FINALIZE_BASE_TYPE old_base;
69 FINALIZE_TYPE new_list;
71 new_list.next = NULL;
72 last = &new_list;
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;
80 new_i = 0;
81 while (old_ops && new_i < VEC_length (tree, FINALIZE_OPBUILD))
83 FINALIZE_BASE_TYPE new_base = FINALIZE_OPBUILD_BASE (new_i);
84 if (old_base == new_base)
86 /* if variables are the same, reuse this node. */
87 last->next = old_ops;
88 last = old_ops;
89 #ifdef FINALIZE_CORRECT_USE
90 FINALIZE_CORRECT_USE (FINALIZE_USE_PTR (last), stmt);
91 #endif
92 old_ops = old_ops->next;
93 new_i++;
95 else
96 if (old_base < new_base)
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;
108 else
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++;
117 if (old_ops)
118 old_base = FINALIZE_BASE (FINALIZE_ELEM (old_ops));
121 /* If there is anything remaining in the opbuild list, simply emit them. */
122 for ( ; new_i < VEC_length (tree, FINALIZE_OPBUILD); new_i++)
124 ptr = FINALIZE_ALLOC ();
125 FINALIZE_INITIALIZE (ptr, FINALIZE_OPBUILD_ELEM (new_i), stmt);
126 last->next = ptr;
127 last = ptr;
130 last->next = NULL;
132 /* If there is anything in the old list, free them. */
133 if (old_ops)
135 #ifdef FINALIZE_USE_PTR
136 for (ptr = old_ops; ptr; ptr = ptr->next)
138 use_operand_p use_p = FINALIZE_USE_PTR (ptr);
139 delink_imm_use (use_p);
141 #endif
142 old_ops->next = FINALIZE_FREE;
143 FINALIZE_FREE = old_ops;
146 /* NOw set the stmt's operands. */
147 FINALIZE_OPS (stmt) = new_list.next;
149 #ifdef ENABLE_CHECKING
151 unsigned x = 0;
152 for (ptr = FINALIZE_OPS (stmt); ptr; ptr = ptr->next)
153 x++;
155 gcc_assert (x == VEC_length (tree, FINALIZE_OPBUILD));
157 #endif
160 #undef FINALIZE_FUNC
161 #undef FINALIZE_ALLOC
162 #undef FINALIZE_FREE
163 #undef FINALIZE_TYPE
164 #undef FINALIZE_OPS
165 #undef FINALIZE_USE_PTR
166 #undef FINALIZE_INITIALIZE
167 #undef FINALIZE_ELEM
168 #undef FINALIZE_BASE
169 #undef FINALIZE_BASE_TYPE
170 #undef FINALIZE_OPBUILD
171 #undef FINALIZE_OPBUILD_ELEM
172 #undef FINALIZE_OPBUILD_BASE
173 #undef FINALIZE_BASE_ZERO
174 #undef FINALIZE_CORRECT_USE