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
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
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
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 *
51 FINALIZE_FREE = FINALIZE_FREE->next;
54 ret = (FINALIZE_TYPE *)ssa_operand_alloc (sizeof (FINALIZE_TYPE));
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
64 FINALIZE_FUNC (tree stmt)
67 FINALIZE_TYPE *old_ops, *ptr, *last;
68 FINALIZE_BASE_TYPE old_base;
69 FINALIZE_TYPE new_list;
74 old_ops = FINALIZE_OPS (stmt);
76 old_base = FINALIZE_BASE (FINALIZE_ELEM (old_ops));
78 old_base = FINALIZE_BASE_ZERO;
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. */
89 #ifdef FINALIZE_CORRECT_USE
90 FINALIZE_CORRECT_USE (FINALIZE_USE_PTR (last), stmt);
92 old_ops = old_ops->next;
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);
104 old_ops = old_ops->next;
105 ptr->next = FINALIZE_FREE;
110 /* This is a new operand. */
111 ptr = FINALIZE_ALLOC ();
112 FINALIZE_INITIALIZE (ptr, FINALIZE_OPBUILD_ELEM (new_i), stmt);
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);
132 /* If there is anything in the old list, free them. */
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);
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
152 for (ptr = FINALIZE_OPS (stmt); ptr; ptr = ptr->next)
155 gcc_assert (x == VEC_length (tree, FINALIZE_OPBUILD));
161 #undef FINALIZE_ALLOC
165 #undef FINALIZE_USE_PTR
166 #undef FINALIZE_INITIALIZE
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