1 /*
2 * Copyright (c) 1993-2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 /** \file
19 * \brief ILI directive module
20 *
21 * Utility routines are valid after the semantic analyzer and after basic
22 * blocks have been created for a function.
23 */
24
25 #include "ilidir.h"
26 #include "gbldefs.h"
27 #include "global.h"
28 #include "error.h"
29 #include "symtab.h"
30 #include "direct.h"
31
32 #if DEBUG
33 #define TR0(s) \
34 if (DBGBIT(1, 2048)) \
35 fprintf(gbl.dbgfil, s);
36 #define TR1(s, a) \
37 if (DBGBIT(1, 2048)) \
38 fprintf(gbl.dbgfil, s, a);
39 #define TR2(s, a, b) \
40 if (DBGBIT(1, 2048)) \
41 fprintf(gbl.dbgfil, s, a, b);
42 #define TR3(s, a, b, c) \
43 if (DBGBIT(1, 2048)) \
44 fprintf(gbl.dbgfil, s, a, b, c);
45
46 #else
47 #define TR0(s)
48 #define TR1(s, a)
49 #define TR2(s, a, b)
50 #define TR3(s, a, b, c)
51
52 #endif
53
54 static int first; /* beginning loopset index for function; 0 => doesn't
55 * exist */
56 static bool opened; /* TRUE if open_pragma found a set which applies to a
57 * loop */
58
59 static int find_lpprg(int);
60
61 /** \brief All blocks have been created for a function (called at end of
62 * expand).
63 */
64 void
ili_lpprg_init(void)65 ili_lpprg_init(void)
66 {
67 int i;
68 LPPRG *lpprg;
69
70 if (direct.lpg.avail <= 1) {
71 first = 0;
72 return;
73 }
74 first = 1;
75 TR1("ili_lpprg_init: %s\n", SYMNAME(GBL_CURRFUNC));
76 for (i = first; i < direct.lpg.avail; i++) {
77 lpprg = direct.lpg.stgb + i;
78 if (lpprg->beg_line < 0)
79 break;
80 TR3("indx %d, begline %d, endline %d\n", i, lpprg->beg_line,
81 lpprg->end_line);
82 }
83
84 }
85
86 /** \brief Find and open the set of loop pragmas associated with a line number.
87 *
88 * SHOULD have a matching close_pragma().
89 */
90 void
open_pragma(int line)91 open_pragma(int line)
92 {
93 int i;
94 LPPRG *lpprg;
95 int match;
96
97 opened = false;
98 match = find_lpprg(line);
99 if (match) {
100 lpprg = direct.lpg.stgb + match;
101 TR2(" begline %d, endline %d\n", lpprg->beg_line, lpprg->end_line);
102 load_dirset(&lpprg->dirset);
103 opened = true;
104 #ifdef FE90
105 direct.indep = lpprg->indep;
106 direct.index_reuse_list = lpprg->index_reuse_list;
107 #endif
108 }
109
110 }
111
112 /** \brief Close the current pragmas => load the pragmas which have routine
113 * scope.
114 */
115 void
close_pragma(void)116 close_pragma(void)
117 {
118 if (opened) {
119 load_dirset(&direct.rou_begin);
120 opened = false;
121 #ifdef FE90
122 direct.indep = NULL;
123 direct.index_reuse_list = NULL;
124 #endif
125 }
126
127 }
128
129 #ifdef FE90
130 void
open_dynpragma(int std,int lineno)131 open_dynpragma(int std, int lineno)
132 {
133 int i;
134 LPPRG *lpprg;
135
136 for (i = 1; i < direct.dynlpg.avail; i++) {
137 lpprg = direct.dynlpg.stgb + i;
138 if (lpprg->beg_line != std)
139 continue;
140 load_dirset(&lpprg->dirset);
141 direct.indep = lpprg->indep;
142 direct.index_reuse_list = lpprg->index_reuse_list;
143 opened = TRUE;
144 return;
145 }
146 open_pragma(lineno);
147 }
148
149 /** \brief Save the current pragma for std. */
150 void
save_dynpragma(int std)151 save_dynpragma(int std)
152 {
153 int i;
154 LPPRG *lpprg;
155
156 for (i = 1; i < direct.dynlpg.avail; i++) {
157 lpprg = direct.dynlpg.stgb + i;
158 if (lpprg->beg_line != std)
159 continue;
160 store_dirset(&lpprg->dirset);
161 lpprg->indep = direct.indep;
162 lpprg->index_reuse_list = direct.index_reuse_list;
163 opened = TRUE; /* so close_pragma will work */
164 close_pragma();
165 return;
166 }
167 i = direct.dynlpg.avail++;
168 NEED(direct.dynlpg.avail, direct.dynlpg.stgb, LPPRG, direct.dynlpg.size,
169 direct.dynlpg.size + 8);
170 lpprg = direct.dynlpg.stgb + i;
171 lpprg->beg_line = std;
172 store_dirset(&lpprg->dirset);
173 lpprg->indep = direct.indep;
174 lpprg->index_reuse_list = direct.index_reuse_list;
175 opened = TRUE; /* so close_pragma will work */
176 close_pragma();
177 }
178 #endif
179
180 /** \brief Find the set of loop pragmas associated with a line number (the
181 * set's beginning and ending line numbers enclose the requested line number).
182 *
183 * Since the loop sets occur in lexical order, the last loop set found is the
184 * set with beginning line number is the floor of the requested line number.
185 */
186 static int
find_lpprg(int line)187 find_lpprg(int line)
188 {
189 int i;
190 LPPRG *lpprg;
191 int match;
192
193 if (first == 0 || line == 0)
194 return 0;
195
196 match = 0;
197 for (i = first; i < direct.lpg.avail; i++) {
198 lpprg = direct.lpg.stgb + i;
199 if (lpprg->beg_line < 0 || lpprg->beg_line > line)
200 break;
201 if (lpprg->beg_line <= line && line <= lpprg->end_line)
202 match = i;
203 }
204 TR2("find_lpprg:for line %d, match = %d\n", line, match);
205
206 return match;
207 }
208
209 #define STK_SZ 128
210
211 static int stk[STK_SZ]; /* should be dynamic ? */
212 static int top = 0; /* first entry in stack is reserved -- the
213 * value is zero => use routine's pragmas */
214
215 /** \brief Find and open and stack the set of loop pragmas associated with a
216 * line number.
217 *
218 * MUST have a matching pop_pragma(). If a match isn't found, push the
219 * routine's set.
220 */
221 void
push_pragma(int line)222 push_pragma(int line)
223 {
224 LPPRG *lpprg;
225 int match;
226
227 top++;
228 if (top >= STK_SZ) {
229 #if DEBUG
230 interr("push_pragma:stkovflw", line, ERR_Severe);
231 #endif
232 top = STK_SZ - 1;
233 }
234 match = find_lpprg(line);
235 stk[top] = match;
236 if (match) {
237 lpprg = direct.lpg.stgb + match;
238 TR2(" push: begline %d, endline %d\n", lpprg->beg_line, lpprg->end_line);
239 load_dirset(&lpprg->dirset);
240 } else {
241 TR0(" push: using routine\n");
242 load_dirset(&direct.rou_begin);
243 }
244
245 }
246
247 /** \brief Pop the set from the stack and open/restore the set which is on the
248 * top of stack.
249 */
250 void
pop_pragma(void)251 pop_pragma(void)
252 {
253 LPPRG *lpprg;
254 int match;
255
256 #if DEBUG
257 if (top <= 0) {
258 interr("pop_pragma:stkuflw", gbl.lineno, ERR_Severe);
259 load_dirset(&direct.rou_begin);
260 return;
261 }
262 #endif
263 top--;
264 match = stk[top];
265 if (match) {
266 lpprg = direct.lpg.stgb + match;
267 TR1(" pop: using %d\n", match);
268 load_dirset(&lpprg->dirset);
269 } else {
270 TR0(" pop: using routine\n");
271 load_dirset(&direct.rou_begin);
272 }
273
274 }
275