Bug Summary

File:src/usedef.c
Warning:line 318, column 7
Value stored to 'seq' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name usedef.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/kfp/aldor/aldor/aldor/src -fcoverage-compilation-dir=/home/kfp/aldor/aldor/aldor/src -resource-dir /usr/local/lib/clang/18 -D PACKAGE_NAME="aldor" -D PACKAGE_TARNAME="aldor" -D PACKAGE_VERSION="1.4.0" -D PACKAGE_STRING="aldor 1.4.0" -D PACKAGE_BUGREPORT="aldor@xinutec.org" -D PACKAGE_URL="" -D PACKAGE="aldor" -D VERSION="1.4.0" -D YYTEXT_POINTER=1 -D HAVE_STDIO_H=1 -D HAVE_STDLIB_H=1 -D HAVE_STRING_H=1 -D HAVE_INTTYPES_H=1 -D HAVE_STDINT_H=1 -D HAVE_STRINGS_H=1 -D HAVE_SYS_STAT_H=1 -D HAVE_SYS_TYPES_H=1 -D HAVE_UNISTD_H=1 -D STDC_HEADERS=1 -D HAVE_LIBREADLINE=1 -D HAVE_READLINE_READLINE_H=1 -D HAVE_READLINE_HISTORY=1 -D HAVE_READLINE_HISTORY_H=1 -D USE_GLOOP_SHELL=1 -D GENERATOR_COROUTINES=0 -D HAVE_DLFCN_H=1 -D LT_OBJDIR=".libs/" -I . -D VCSVERSION="2c53e759f1e00e345f8b172e7139debda72fda13" -internal-isystem /usr/local/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-empty-body -Wno-enum-compare -Wno-missing-field-initializers -Wno-unused -Wno-unused-parameter -Wno-error=format -Wno-error=type-limits -Wno-error=strict-aliasing -Wno-sign-compare -Wno-error=shift-negative-value -Wno-error=clobbered -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2026-01-15-223856-845667-1 -x c usedef.c
1/*****************************************************************************
2 *
3 * usedef.c: Usage definition chains
4 *
5 * Copyright (c) 1990-2007 Aldor Software Organization Ltd (Aldor.org).
6 *
7 ****************************************************************************/
8/***************************************************************************
9 *
10 * Use-Definition Chains
11 *
12 * This file provides procedures to build UD chains from a foam tree or a
13 * flog. (Refer. to 'Aho, Sethi, Ullman: "Compilers: Principles, Techinques,
14 * and Tools", Addison Wesley)
15 * UD chains are built only for Locals and Parameters, because the majority
16 * of current optimizations work only on this class of variables.
17 *
18 *************************************************************************
19 *
20 * This implementation works in three phases.
21 *
22 * 1) The foam tree is traversed and a varDefsVect is built. The i-th
23 * elem. of this vector is the list of all the foam definitions of
24 * (Loc i).
25 *
26 * 2) DataFlow analysis is performed on the base of the information stored
27 * in the varDefsVect.
28 *
29 * 3) The foam tree is traversed and, using the information in the IN sets
30 * for each block, the UD chain is built for each usage of Loc or Par.
31 * The list is attached to the corresponding usage. It can be accessed
32 * using the udReachingDefs(foam) macro.
33 *
34 *************************************************************************
35 * NOTE: in date 23 May 1994 usedef has been modified so that for each use
36 * is possible to know the reaching defs and the blocks to which these
37 * defs belong. This information will be used, in example, in loops optim.
38 *************************************************************************
39 *
40 * *** EXAMPLE: (2 blocks)
41 *
42 * -------------------------------- Block B3 ----------------
43 * (Set (Loc 0) (Glo 1)) -- s1
44 * (Set (Loc 1) (Loc 0)) -- s2
45 * (Set (Loc 0) (Lex 3)) -- s3
46 * (CCall (Loc 0)) -- s4
47 * (CCall (Loc 8)) -- s5
48 * ----------------------------------------------------------
49 *
50 * -------------------------------- Block B5 ----------------
51 * (Set (Loc 8) (Glo 12)) -- s10
52 * ----------------------------------------------------------
53 *
54 * +++++++++++++++++++ After phase (1): ++++++++++++++++++++
55 *
56 * VarDefsVect[0] = [s1, s3]
57 * VarDefsVect[1] = [s2]
58 * ...
59 * VarDefsVect[8] = [s10]
60 *
61 * +++++++++++++++++++ After phase (2): ++++++++++++++++++++
62 *
63 * Let's suppose that
64 * IN[B3] = { s10 }
65 * IN[B5] = { }
66 *
67 * +++++++++++++++++++ After phase (3): ++++++++++++++++++++
68 *
69 * -------------------------------- Block B3 ---------------------
70 * (Set (Loc 0) (Glo 1)) -- s1 udReachingDefs(Loc 0) = [s1]
71 *
72 * (Set (Loc 1) (Loc 0)) -- s2 udReachingDefs(Loc 1) = [s2]
73 udReachingDefs(Loc 0) = [s1]
74 *
75 * (Set (Loc 0) (Lex 3)) -- s3 udReachingDefs(Loc 0) = [s3]
76 *
77 * (CCall (Loc 0)) -- s4 udReachingDefs(Loc 0) = [s3]
78 * (CCall (Loc 8)) -- s5 udReachingDefs(Loc 0) = [s10]
79 * ----------------------------------------------------------------
80 * -------------------------------- Block B5 ----------------------
81 * (Set (Loc 8) (Glo 12)) -- s10 udReachingDefs(Loc 8) = [s10]
82 * ----------------------------------------------------------------
83 *
84 ***(end example)************************************************************
85 *
86 * 30 May 1994: usedef.c generate false definitions for parameters.
87 *
88 * For each (Par n) there is a false definition (Set (Par N) (Par N)) as it
89 * was the first instruction.
90 * usedefChainsFree knows about that, and free these false pieces of foam.
91 *
92 * 1 June 1994: usedef.c fixed to handle (Set (Values ...) (MFmt ....))
93 * assignments correctly.
94 *
95 * 2 June 1994: usedef.c has been extended also to lexicals.
96 * The inliner needs to trace lexicals that are assigned with a Def stmt.
97 *
98 *
99 ****************************************************************************
100 * ToDo:
101 * - keep information for each function of the lexicals and the globals
102 * modified. This will achive a lot of global optimizations that we
103 * don't perform.
104 *
105 ****************************************************************************
106 * !!!!!FIXME!!!!!
107 * Usedef doesn't handle properly FOAM_Values
108 * usedefFreeChains
109 ****************************************************************************/
110
111#include "debug.h"
112#include "dflow.h"
113#include "flog.h"
114#include "opttools.h"
115#include "store.h"
116#include "usedef.h"
117#include "util.h"
118
119/****************************************************************************
120 * :: Debug
121 ****************************************************************************/
122
123Bool udDfDebug = false((int) 0);
124Bool udDfiDebug = false((int) 0);
125
126#define udDfDEBUGif (!udDfDebug) { } else afprintf DEBUG_IF(udDf)if (!udDfDebug) { } else afprintf
127#define udDfiDEBUGif (!udDfiDebug) { } else afprintf DEBUG_IF(udDfi)if (!udDfiDebug) { } else afprintf
128
129/*****************************************************************************
130 *
131 * :: Macros
132 *
133 ****************************************************************************/
134
135# define udDefNo(foam)((foam)->foamGen.hdr.info.defNo) ((foam)->foamGen.hdr.info.defNo)
136
137 /* Note: false defs have udInfo with block == NULL, for safety */
138# define udIsFalseDef(UDI)(((((UDI)->foam)->foamSet.lhs)->hdr.tag) == FOAM_Par
&& ((((UDI)->foam)->foamSet.rhs)->hdr.tag) ==
FOAM_Par && ((UDI)->foam)->foamSet.lhs->foamPar
.index == ((UDI)->foam)->foamSet.rhs->foamPar.index &&
!((UDI)->block))
\
139 (foamTag(udInfoDef(UDI)->foamSet.lhs)((((UDI)->foam)->foamSet.lhs)->hdr.tag) == FOAM_Par && \
140 foamTag(udInfoDef(UDI)->foamSet.rhs)((((UDI)->foam)->foamSet.rhs)->hdr.tag) == FOAM_Par && \
141 udInfoDef(UDI)((UDI)->foam)->foamSet.lhs->foamPar.index == udInfoDef(UDI)((UDI)->foam)->foamSet.rhs->foamPar.index && \
142 !udInfoBlock(UDI)((UDI)->block))
143
144/****************************************************************************
145 * :: Global Data Structures
146 ****************************************************************************/
147
148
149typedef struct {
150 FoamList * varDefsVect;
151 int nPars;
152 int nLocs;
153 int nDefs;
154 BitvClass bitvClass;
155 UdOutputKind outputType;
156} UdProgInfo;
157
158static UdProgInfo udProgInfo;
159
160CREATE_LIST(UdInfo)struct UdInfo_listOpsStruct const *UdInfo_listPointer = (struct
UdInfo_listOpsStruct const *) &ptrlistOps
;
161
162/****************************************************************************
163 *
164 * :: Local prototypes
165 *
166 ****************************************************************************/
167
168localstatic void udDestroyUses (Foam);
169
170localstatic int udVarDefsVectBuild (FlowGraph);
171localstatic void udVarDefsVectUpdate (Foam);
172localstatic void udVarDefsVectFree (void);
173
174extern void udVarDefsVectPrint (void);
175extern void udPrintDbFrFlog (FlowGraph);
176
177localstatic void udFillGenKill (FlowGraph, BBlock);
178localstatic void udKillAllButThis (Bitv, Foam, int, Bool);
179localstatic void udCreateUDLists (FlowGraph);
180localstatic Foam udFindUses (Foam, Bitv, BBlock, Bool);
181
182localstatic UdInfo udInfoNew (Foam, BBlock);
183localstatic Foam udLastStmt;
184
185static int udFlogCutOff = 200; /* Max no of dataflow iterations */
186
187
188/****************************************************************************
189 *
190 * :: External entry points
191 *
192 ****************************************************************************/
193
194#if 0
195void
196useDefChainsFrFoamProg(Foam foam)
197{
198 FlowGraph flog;
199 Foam prog, defs, def;
200 int i;
201
202 assert(foamTag(foam) == FOAM_Prog)do { if (!(((foam)->hdr.tag) == FOAM_Prog)) _do_assert(("foamTag(foam) == FOAM_Prog"
),"usedef.c",202); } while (0)
;
203
204 if (foamArgc(foam->foamProg.locals)((foam->foamProg.locals)->hdr.argc) +
205 foamArgc(foam->foamProg.params)((foam->foamProg.params)->hdr.argc) == 0)
206 return;
207
208 flog = flogFrProg(foam, FLOG_UniqueExit);
209
210 useDefChainsFrFlog(flog, UD_OUTPUT_SinglePointer);
211
212 flogToProg(flog);
213}
214
215void
216usedefChainsFreeFrProg(Foam foam)
217{
218 assert(foamTag(foam) == FOAM_Prog)do { if (!(((foam)->hdr.tag) == FOAM_Prog)) _do_assert(("foamTag(foam) == FOAM_Prog"
),"usedef.c",218); } while (0)
;
219
220 /* used by udIsFalseDef */
221 udProgInfo.nPars = foamDDeclArgc(foam->foamProg.params)(((foam->foamProg.params)->hdr.argc) - (1));
222
223 udDestroyUses(foam);
224}
225#endif
226
227/* Compute, for each use of local/parameter, the set of definitions reaching
228 * it. This information is associated to the use, using the
229 * foamhdr.info.defList field.
230 *
231 * outputType must be either UD_OUTPUT_UdList or UD_OUTPUT_SinglePointer.
232 */
233Bool
234usedefChainsFrFlog(FlowGraph flog, UdOutputKind outputType)
235{
236 int i, k, nDefs;
237
238 /* !!$$ assume flog coming from a Prog, because we need to know the
239 * num of locals/params
240 * probably this info can be stored when the flog is built.
241 */
242 assert(flog->prog)do { if (!(flog->prog)) _do_assert(("flog->prog"),"usedef.c"
,242); } while (0)
;
243
244 udProgInfo.outputType = outputType;
245
246 nDefs = udVarDefsVectBuild(flog);
247
248 if (nDefs == 0) return true1;
249
250 flogBitvClass(flog)((flog)->bitvClass) = bitvClassCreate(nDefs);
251 udProgInfo.bitvClass = flogBitvClass(flog)((flog)->bitvClass);
252
253 flogIter(flog, bb, {{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { dflowNewBlockInfo(bb, nDefs, udFillGenKill
); }; }; } }; }
254 dflowNewBlockInfo(bb, nDefs, udFillGenKill);{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { dflowNewBlockInfo(bb, nDefs, udFillGenKill
); }; }; } }; }
255 }){ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { dflowNewBlockInfo(bb, nDefs, udFillGenKill
); }; }; } }; }
;
256
257 i = dflowFwdIterate(flog, DFLOW_Union, udFlogCutOff, &k, NULL((void*)0));
258
259 if (DEBUG(udDf)udDfDebug) {
260 fprintf(dbOut, i == 0 ? "Converged" : "Did not converge");
261 fprintf(dbOut, " after %d iterations\n", k);
262 flogPrint(dbOut, flog, true1);
263 }
264
265 if (i != 0) return false((int) 0);
266
267 udCreateUDLists(flog);
268
269 dflowFreeGraphInfo(flog);
270 udVarDefsVectFree();
271
272 return true1;
273}
274
275void
276usedefChainsFreeFrFlog(FlowGraph flog)
277{
278 /* used by udIsFalseDef */
279 udProgInfo.nPars = foamDDeclArgc(flog->prog->foamProg.params)(((flog->prog->foamProg.params)->hdr.argc) - (1));
280
281 flogIter(flog, bb, {{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { udDestroyUses(bb->code); }; }; } }; }
282 udDestroyUses(bb->code);{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { udDestroyUses(bb->code); }; }; } }; }
283 }){ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { udDestroyUses(bb->code); }; }; } }; }
;
284}
285
286void
287udSetFlogCutOff(int n)
288{
289 udFlogCutOff = n;
290}
291
292/****************************************************************************
293 *
294 * :: Local functions
295 *
296 ****************************************************************************/
297
298localstatic void
299udDestroyUses(Foam foam)
300{
301 foamIter(foam, arg, udDestroyUses(*arg)){ { String argf = (foamInfoTable [(int)(((foam)->hdr.tag))
-(int)FOAM_START]).argf; Length _i; for (_i = 0; _i < ((foam
)->hdr.argc); _i++, argf++) { if (*argf == '*') argf--; if
(*argf == 'C') { Foam *arg = (Foam *) ((foam)->foamGen.argv
)+_i; { udDestroyUses(*arg); }; } } }; }
;
302
303 if (otIsLocalVar(foam)(((foam)->hdr.tag) == FOAM_Loc || ((foam)->hdr.tag) == FOAM_Par
)
/*!! || otIsNonLocalVar(foam) */ &&
304 udReachingDefs(foam)((foam)->foamGen.hdr.info.defList))
305 udReachingDefs(foam)((foam)->foamGen.hdr.info.defList) = listNil(UdInfo)((UdInfoList) 0);
306 /* listFreeDeeply(UdInfo)(udReachingDefs(foam), udInfoFree); !!*/
307
308 return;
309}
310
311/* Assign a progressive number to each definition (Def or Set), and add
312 * it in the entry corresponding to the lhs, so that for each var is possible
313 * access to the list of stmts where is defined.
314 */
315localstatic int
316udVarDefsVectBuild(FlowGraph flog)
317{
318 Foam seq = flog->prog->foamProg.body;
Value stored to 'seq' during its initialization is never read
319 Foam stmt, lhs;
320 int i, nDefs;
321 int nLocs = foamDDeclArgc(flog->prog->foamProg.locals)(((flog->prog->foamProg.locals)->hdr.argc) - (1));
322 int nPars = foamDDeclArgc(flog->prog->foamProg.params)(((flog->prog->foamProg.params)->hdr.argc) - (1));
323
324 udProgInfo.nPars = nPars;
325 udProgInfo.nLocs = nLocs;
326
327 if (nLocs + nPars == 0) return 0;
328
329 otProgInfoInit(OT_ASSOCIATION_LIST0x0002, nLocs, nPars, NULL((void*)0));
330
331 nDefs = nPars; /* false definition for parameters */
332
333 /* Generate false definitions for parameters */
334 for (i = 0; i < nPars; i++) {
335 stmt = foamNewSet(foamNewPar(i), foamNewPar(i))foamNew(FOAM_Set, 2, foamNew(FOAM_Par, 1, (AInt)(i)), foamNew
(FOAM_Par, 1, (AInt)(i)))
;
336 udDefNo(stmt)((stmt)->foamGen.hdr.info.defNo) = i;
337 udVarDefsVectUpdate(stmt);
338 }
339
340 flogIter(flog, bb, {{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { seq = bb->code; for (i = 0; i < ((
seq)->hdr.argc); i++) { stmt = ((seq)->foamGen.argv)[i]
.code; if (!(((stmt)->hdr.tag) == FOAM_Set || ((stmt)->
hdr.tag) == FOAM_Def)) continue; lhs = stmt->foamDef.lhs; if
((((lhs)->hdr.tag) == FOAM_Loc || ((lhs)->hdr.tag) == FOAM_Par
) || ((lhs)->hdr.tag) == FOAM_Values || ((((lhs)->hdr.tag
) == FOAM_Lex || ((lhs)->hdr.tag) == FOAM_Glo) && (
(stmt)->hdr.tag) == FOAM_Def)) { ((stmt)->foamGen.hdr.info
.defNo) = nDefs++; udVarDefsVectUpdate(stmt); } } }; }; } }; }
341
342 seq = bb->code;{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { seq = bb->code; for (i = 0; i < ((
seq)->hdr.argc); i++) { stmt = ((seq)->foamGen.argv)[i]
.code; if (!(((stmt)->hdr.tag) == FOAM_Set || ((stmt)->
hdr.tag) == FOAM_Def)) continue; lhs = stmt->foamDef.lhs; if
((((lhs)->hdr.tag) == FOAM_Loc || ((lhs)->hdr.tag) == FOAM_Par
) || ((lhs)->hdr.tag) == FOAM_Values || ((((lhs)->hdr.tag
) == FOAM_Lex || ((lhs)->hdr.tag) == FOAM_Glo) && (
(stmt)->hdr.tag) == FOAM_Def)) { ((stmt)->foamGen.hdr.info
.defNo) = nDefs++; udVarDefsVectUpdate(stmt); } } }; }; } }; }
343
344 for (i = 0; i < foamArgc(seq); i++) {{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { seq = bb->code; for (i = 0; i < ((
seq)->hdr.argc); i++) { stmt = ((seq)->foamGen.argv)[i]
.code; if (!(((stmt)->hdr.tag) == FOAM_Set || ((stmt)->
hdr.tag) == FOAM_Def)) continue; lhs = stmt->foamDef.lhs; if
((((lhs)->hdr.tag) == FOAM_Loc || ((lhs)->hdr.tag) == FOAM_Par
) || ((lhs)->hdr.tag) == FOAM_Values || ((((lhs)->hdr.tag
) == FOAM_Lex || ((lhs)->hdr.tag) == FOAM_Glo) && (
(stmt)->hdr.tag) == FOAM_Def)) { ((stmt)->foamGen.hdr.info
.defNo) = nDefs++; udVarDefsVectUpdate(stmt); } } }; }; } }; }
345 stmt = foamArgv(seq)[i].code;{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { seq = bb->code; for (i = 0; i < ((
seq)->hdr.argc); i++) { stmt = ((seq)->foamGen.argv)[i]
.code; if (!(((stmt)->hdr.tag) == FOAM_Set || ((stmt)->
hdr.tag) == FOAM_Def)) continue; lhs = stmt->foamDef.lhs; if
((((lhs)->hdr.tag) == FOAM_Loc || ((lhs)->hdr.tag) == FOAM_Par
) || ((lhs)->hdr.tag) == FOAM_Values || ((((lhs)->hdr.tag
) == FOAM_Lex || ((lhs)->hdr.tag) == FOAM_Glo) && (
(stmt)->hdr.tag) == FOAM_Def)) { ((stmt)->foamGen.hdr.info
.defNo) = nDefs++; udVarDefsVectUpdate(stmt); } } }; }; } }; }
346
347 if (!otIsDef(stmt)) continue;{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { seq = bb->code; for (i = 0; i < ((
seq)->hdr.argc); i++) { stmt = ((seq)->foamGen.argv)[i]
.code; if (!(((stmt)->hdr.tag) == FOAM_Set || ((stmt)->
hdr.tag) == FOAM_Def)) continue; lhs = stmt->foamDef.lhs; if
((((lhs)->hdr.tag) == FOAM_Loc || ((lhs)->hdr.tag) == FOAM_Par
) || ((lhs)->hdr.tag) == FOAM_Values || ((((lhs)->hdr.tag
) == FOAM_Lex || ((lhs)->hdr.tag) == FOAM_Glo) && (
(stmt)->hdr.tag) == FOAM_Def)) { ((stmt)->foamGen.hdr.info
.defNo) = nDefs++; udVarDefsVectUpdate(stmt); } } }; }; } }; }
348
349 lhs = stmt->foamDef.lhs;{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { seq = bb->code; for (i = 0; i < ((
seq)->hdr.argc); i++) { stmt = ((seq)->foamGen.argv)[i]
.code; if (!(((stmt)->hdr.tag) == FOAM_Set || ((stmt)->
hdr.tag) == FOAM_Def)) continue; lhs = stmt->foamDef.lhs; if
((((lhs)->hdr.tag) == FOAM_Loc || ((lhs)->hdr.tag) == FOAM_Par
) || ((lhs)->hdr.tag) == FOAM_Values || ((((lhs)->hdr.tag
) == FOAM_Lex || ((lhs)->hdr.tag) == FOAM_Glo) && (
(stmt)->hdr.tag) == FOAM_Def)) { ((stmt)->foamGen.hdr.info
.defNo) = nDefs++; udVarDefsVectUpdate(stmt); } } }; }; } }; }
350
351 if (otIsLocalVar(lhs) ||{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { seq = bb->code; for (i = 0; i < ((
seq)->hdr.argc); i++) { stmt = ((seq)->foamGen.argv)[i]
.code; if (!(((stmt)->hdr.tag) == FOAM_Set || ((stmt)->
hdr.tag) == FOAM_Def)) continue; lhs = stmt->foamDef.lhs; if
((((lhs)->hdr.tag) == FOAM_Loc || ((lhs)->hdr.tag) == FOAM_Par
) || ((lhs)->hdr.tag) == FOAM_Values || ((((lhs)->hdr.tag
) == FOAM_Lex || ((lhs)->hdr.tag) == FOAM_Glo) && (
(stmt)->hdr.tag) == FOAM_Def)) { ((stmt)->foamGen.hdr.info
.defNo) = nDefs++; udVarDefsVectUpdate(stmt); } } }; }; } }; }
352 foamTag(lhs) == FOAM_Values ||{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { seq = bb->code; for (i = 0; i < ((
seq)->hdr.argc); i++) { stmt = ((seq)->foamGen.argv)[i]
.code; if (!(((stmt)->hdr.tag) == FOAM_Set || ((stmt)->
hdr.tag) == FOAM_Def)) continue; lhs = stmt->foamDef.lhs; if
((((lhs)->hdr.tag) == FOAM_Loc || ((lhs)->hdr.tag) == FOAM_Par
) || ((lhs)->hdr.tag) == FOAM_Values || ((((lhs)->hdr.tag
) == FOAM_Lex || ((lhs)->hdr.tag) == FOAM_Glo) && (
(stmt)->hdr.tag) == FOAM_Def)) { ((stmt)->foamGen.hdr.info
.defNo) = nDefs++; udVarDefsVectUpdate(stmt); } } }; }; } }; }
353 (otIsNonLocalVar(lhs) &&{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { seq = bb->code; for (i = 0; i < ((
seq)->hdr.argc); i++) { stmt = ((seq)->foamGen.argv)[i]
.code; if (!(((stmt)->hdr.tag) == FOAM_Set || ((stmt)->
hdr.tag) == FOAM_Def)) continue; lhs = stmt->foamDef.lhs; if
((((lhs)->hdr.tag) == FOAM_Loc || ((lhs)->hdr.tag) == FOAM_Par
) || ((lhs)->hdr.tag) == FOAM_Values || ((((lhs)->hdr.tag
) == FOAM_Lex || ((lhs)->hdr.tag) == FOAM_Glo) && (
(stmt)->hdr.tag) == FOAM_Def)) { ((stmt)->foamGen.hdr.info
.defNo) = nDefs++; udVarDefsVectUpdate(stmt); } } }; }; } }; }
354 foamTag(stmt) == FOAM_Def)) {{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { seq = bb->code; for (i = 0; i < ((
seq)->hdr.argc); i++) { stmt = ((seq)->foamGen.argv)[i]
.code; if (!(((stmt)->hdr.tag) == FOAM_Set || ((stmt)->
hdr.tag) == FOAM_Def)) continue; lhs = stmt->foamDef.lhs; if
((((lhs)->hdr.tag) == FOAM_Loc || ((lhs)->hdr.tag) == FOAM_Par
) || ((lhs)->hdr.tag) == FOAM_Values || ((((lhs)->hdr.tag
) == FOAM_Lex || ((lhs)->hdr.tag) == FOAM_Glo) && (
(stmt)->hdr.tag) == FOAM_Def)) { ((stmt)->foamGen.hdr.info
.defNo) = nDefs++; udVarDefsVectUpdate(stmt); } } }; }; } }; }
355
356 udDefNo(stmt) = nDefs++;{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { seq = bb->code; for (i = 0; i < ((
seq)->hdr.argc); i++) { stmt = ((seq)->foamGen.argv)[i]
.code; if (!(((stmt)->hdr.tag) == FOAM_Set || ((stmt)->
hdr.tag) == FOAM_Def)) continue; lhs = stmt->foamDef.lhs; if
((((lhs)->hdr.tag) == FOAM_Loc || ((lhs)->hdr.tag) == FOAM_Par
) || ((lhs)->hdr.tag) == FOAM_Values || ((((lhs)->hdr.tag
) == FOAM_Lex || ((lhs)->hdr.tag) == FOAM_Glo) && (
(stmt)->hdr.tag) == FOAM_Def)) { ((stmt)->foamGen.hdr.info
.defNo) = nDefs++; udVarDefsVectUpdate(stmt); } } }; }; } }; }
357 udVarDefsVectUpdate(stmt);{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { seq = bb->code; for (i = 0; i < ((
seq)->hdr.argc); i++) { stmt = ((seq)->foamGen.argv)[i]
.code; if (!(((stmt)->hdr.tag) == FOAM_Set || ((stmt)->
hdr.tag) == FOAM_Def)) continue; lhs = stmt->foamDef.lhs; if
((((lhs)->hdr.tag) == FOAM_Loc || ((lhs)->hdr.tag) == FOAM_Par
) || ((lhs)->hdr.tag) == FOAM_Values || ((((lhs)->hdr.tag
) == FOAM_Lex || ((lhs)->hdr.tag) == FOAM_Glo) && (
(stmt)->hdr.tag) == FOAM_Def)) { ((stmt)->foamGen.hdr.info
.defNo) = nDefs++; udVarDefsVectUpdate(stmt); } } }; }; } }; }
358 }{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { seq = bb->code; for (i = 0; i < ((
seq)->hdr.argc); i++) { stmt = ((seq)->foamGen.argv)[i]
.code; if (!(((stmt)->hdr.tag) == FOAM_Set || ((stmt)->
hdr.tag) == FOAM_Def)) continue; lhs = stmt->foamDef.lhs; if
((((lhs)->hdr.tag) == FOAM_Loc || ((lhs)->hdr.tag) == FOAM_Par
) || ((lhs)->hdr.tag) == FOAM_Values || ((((lhs)->hdr.tag
) == FOAM_Lex || ((lhs)->hdr.tag) == FOAM_Glo) && (
(stmt)->hdr.tag) == FOAM_Def)) { ((stmt)->foamGen.hdr.info
.defNo) = nDefs++; udVarDefsVectUpdate(stmt); } } }; }; } }; }
359 }{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { seq = bb->code; for (i = 0; i < ((
seq)->hdr.argc); i++) { stmt = ((seq)->foamGen.argv)[i]
.code; if (!(((stmt)->hdr.tag) == FOAM_Set || ((stmt)->
hdr.tag) == FOAM_Def)) continue; lhs = stmt->foamDef.lhs; if
((((lhs)->hdr.tag) == FOAM_Loc || ((lhs)->hdr.tag) == FOAM_Par
) || ((lhs)->hdr.tag) == FOAM_Values || ((((lhs)->hdr.tag
) == FOAM_Lex || ((lhs)->hdr.tag) == FOAM_Glo) && (
(stmt)->hdr.tag) == FOAM_Def)) { ((stmt)->foamGen.hdr.info
.defNo) = nDefs++; udVarDefsVectUpdate(stmt); } } }; }; } }; }
360 }){ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { seq = bb->code; for (i = 0; i < ((
seq)->hdr.argc); i++) { stmt = ((seq)->foamGen.argv)[i]
.code; if (!(((stmt)->hdr.tag) == FOAM_Set || ((stmt)->
hdr.tag) == FOAM_Def)) continue; lhs = stmt->foamDef.lhs; if
((((lhs)->hdr.tag) == FOAM_Loc || ((lhs)->hdr.tag) == FOAM_Par
) || ((lhs)->hdr.tag) == FOAM_Values || ((((lhs)->hdr.tag
) == FOAM_Lex || ((lhs)->hdr.tag) == FOAM_Glo) && (
(stmt)->hdr.tag) == FOAM_Def)) { ((stmt)->foamGen.hdr.info
.defNo) = nDefs++; udVarDefsVectUpdate(stmt); } } }; }; } }; }
;
361
362 if (DEBUG(udDf)udDfDebug) {
363 udVarDefsVectPrint();
364 }
365
366 return nDefs;
367}
368
369localstatic void
370udVarDefsVectUpdate(Foam def)
371{
372 Foam lhs = def->foamDef.lhs;
373 int var, nVars;
374 Foam * lhsVarVect;
375
376 if (foamTag(lhs)((lhs)->hdr.tag) == FOAM_Values) {
377 nVars = foamArgc(lhs)((lhs)->hdr.argc);
378 lhsVarVect = lhs->foamValues.argv;
379 }
380 else {
381 nVars = 1;
382 lhsVarVect = &lhs;
383 }
384
385 for (var = 0; var < nVars; var++) {
386
387 lhs = lhsVarVect[var];
388 assert(nVars == 1 || otIsVar(lhs))do { if (!(nVars == 1 || (((lhs)->hdr.tag) == FOAM_Loc || (
(lhs)->hdr.tag) == FOAM_Par || ((lhs)->hdr.tag) == FOAM_Lex
|| ((lhs)->hdr.tag) == FOAM_Glo))) _do_assert(("nVars == 1 || otIsVar(lhs)"
),"usedef.c",388); } while (0)
;
389
390 otAddVarInfo(def, lhs)otAddVarInfo0((VarInfo) (def), lhs);
391 }
392
393 udProgInfo.nDefs += 1;
394}
395
396localstatic void
397udVarDefsVectFree()
398{
399 otProgInfoFini();
400}
401
402
403void
404udVarDefsVectPrint()
405{
406 otPrintVarAssociations((VarInfoPrintFn) foamPrintDb);
407}
408
409/****************************************************************************
410 *
411 * :: Build Gen and Kill sets
412 *
413 ****************************************************************************/
414
415localstatic void
416udFillGenKill(FlowGraph flog, BBlock bb)
417{
418 Foam seq = bb->code, lhs, stmt;
419 int defNo, i;
420 BitvClass class = udProgInfo.bitvClass;
421
422 udDfiDEBUGif (!udDfiDebug) { } else afprintf(dbOut, "Filling Gen/Kill for %d\n", bb->label);
423
424 /*
425 * Clear the vectors.
426 */
427 bitvClearAll(class, dfFwdGen(bb)((bb)->dfinfo->gen));
428 bitvClearAll(class, dfFwdKill(bb, int0)((bb)->dfinfo->exit[((int) 0)].kill));
429
430 /* Generate false definitions for parameters */
431 if (bb == flog->block0)
432 for (i = 0; i < udProgInfo.nPars; i++)
433 bitvSet(class, dfFwdGen(bb)((bb)->dfinfo->gen), i);
434
435 for (i = 0; i < foamArgc(seq)((seq)->hdr.argc); i++) {
436 stmt = seq->foamSeq.argv[i];
437
438 if (!otIsDef(stmt)(((stmt)->hdr.tag) == FOAM_Set || ((stmt)->hdr.tag) == FOAM_Def
)
) continue;
439
440 lhs = stmt->foamDef.lhs;
441
442 if (!otIsLocalVar(lhs)(((lhs)->hdr.tag) == FOAM_Loc || ((lhs)->hdr.tag) == FOAM_Par
)
&&
443 foamTag(lhs)((lhs)->hdr.tag) != FOAM_Values &&
444 (!otIsNonLocalVar(lhs)(((lhs)->hdr.tag) == FOAM_Lex || ((lhs)->hdr.tag) == FOAM_Glo
)
||
445 foamTag(stmt)((stmt)->hdr.tag) != FOAM_Def)) {
446 udKillAllButThis(dfFwdKill(bb, int0)((bb)->dfinfo->exit[((int) 0)].kill), lhs, -1, true1);
447 continue;
448 }
449
450 defNo = udDefNo(stmt)((stmt)->foamGen.hdr.info.defNo);
451
452 /* Set gen bit for the corresponding def */
453 bitvSet(class, dfFwdGen(bb)((bb)->dfinfo->gen), defNo);
454
455 /* Unkill, needed because we use (IN \/ Gen) - Kill */
456 bitvClear(class, dfFwdKill(bb, int0)((bb)->dfinfo->exit[((int) 0)].kill), defNo);
457
458
459 udKillAllButThis(dfFwdKill(bb, int0)((bb)->dfinfo->exit[((int) 0)].kill), lhs, defNo, true1);
460 }
461}
462
463/* NOTE: "defNo" may be -1; this means that we want to kill all the definition
464 * of the lhs.
465 * This is generally used for multiple value assignments: we kill all and
466 * nothing is generated
467 */
468localstatic void
469udKillAllButThis(Bitv killv, Foam lhs, int defNo, Bool bit)
470{
471 int n;
472 int var, nVars;
473 Foam * lhsVarVect;
474 FoamList defs;
475 Bool found = false((int) 0);
476 BitvClass class = udProgInfo.bitvClass;
477
478 if (!otIsVar(lhs)(((lhs)->hdr.tag) == FOAM_Loc || ((lhs)->hdr.tag) == FOAM_Par
|| ((lhs)->hdr.tag) == FOAM_Lex || ((lhs)->hdr.tag) ==
FOAM_Glo)
&& foamTag(lhs)((lhs)->hdr.tag) != FOAM_Values)
479 return;
480
481 if (foamTag(lhs)((lhs)->hdr.tag) == FOAM_Values) {
482 nVars = foamArgc(lhs)((lhs)->hdr.argc);
483 lhsVarVect = lhs->foamValues.argv;
484 }
485 else {
486 nVars = 1;
487 lhsVarVect = &lhs;
488 }
489
490 for (var = 0; var < nVars; var++) {
491 lhs = lhsVarVect[var];
492 assert(otIsVar(lhs))do { if (!((((lhs)->hdr.tag) == FOAM_Loc || ((lhs)->hdr
.tag) == FOAM_Par || ((lhs)->hdr.tag) == FOAM_Lex || ((lhs
)->hdr.tag) == FOAM_Glo))) _do_assert(("otIsVar(lhs)"),"usedef.c"
,492); } while (0)
;
493 defs = (FoamList) otGetVarInfoList(lhs);
494
495 listIter(Foam, def, defs, {{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { n = ((def)->foamGen
.hdr.info.defNo); if (n != defNo) { if (bit) bitvSet(class, killv
, n); else bitvClear(class, killv, n); } else { found = 1; } }
; }; } }; }
496 n = udDefNo(def);{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { n = ((def)->foamGen
.hdr.info.defNo); if (n != defNo) { if (bit) bitvSet(class, killv
, n); else bitvClear(class, killv, n); } else { found = 1; } }
; }; } }; }
497 if (n != defNo) {{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { n = ((def)->foamGen
.hdr.info.defNo); if (n != defNo) { if (bit) bitvSet(class, killv
, n); else bitvClear(class, killv, n); } else { found = 1; } }
; }; } }; }
498 if (bit){ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { n = ((def)->foamGen
.hdr.info.defNo); if (n != defNo) { if (bit) bitvSet(class, killv
, n); else bitvClear(class, killv, n); } else { found = 1; } }
; }; } }; }
499 bitvSet(class, killv, n);{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { n = ((def)->foamGen
.hdr.info.defNo); if (n != defNo) { if (bit) bitvSet(class, killv
, n); else bitvClear(class, killv, n); } else { found = 1; } }
; }; } }; }
500 else{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { n = ((def)->foamGen
.hdr.info.defNo); if (n != defNo) { if (bit) bitvSet(class, killv
, n); else bitvClear(class, killv, n); } else { found = 1; } }
; }; } }; }
501 bitvClear(class, killv, n);{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { n = ((def)->foamGen
.hdr.info.defNo); if (n != defNo) { if (bit) bitvSet(class, killv
, n); else bitvClear(class, killv, n); } else { found = 1; } }
; }; } }; }
502 }{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { n = ((def)->foamGen
.hdr.info.defNo); if (n != defNo) { if (bit) bitvSet(class, killv
, n); else bitvClear(class, killv, n); } else { found = 1; } }
; }; } }; }
503 else {{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { n = ((def)->foamGen
.hdr.info.defNo); if (n != defNo) { if (bit) bitvSet(class, killv
, n); else bitvClear(class, killv, n); } else { found = 1; } }
; }; } }; }
504 /* !! Used only for the safety test,{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { n = ((def)->foamGen
.hdr.info.defNo); if (n != defNo) { if (bit) bitvSet(class, killv
, n); else bitvClear(class, killv, n); } else { found = 1; } }
; }; } }; }
505 * could be removed{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { n = ((def)->foamGen
.hdr.info.defNo); if (n != defNo) { if (bit) bitvSet(class, killv
, n); else bitvClear(class, killv, n); } else { found = 1; } }
; }; } }; }
506 */{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { n = ((def)->foamGen
.hdr.info.defNo); if (n != defNo) { if (bit) bitvSet(class, killv
, n); else bitvClear(class, killv, n); } else { found = 1; } }
; }; } }; }
507 found = true;{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { n = ((def)->foamGen
.hdr.info.defNo); if (n != defNo) { if (bit) bitvSet(class, killv
, n); else bitvClear(class, killv, n); } else { found = 1; } }
; }; } }; }
508 }{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { n = ((def)->foamGen
.hdr.info.defNo); if (n != defNo) { if (bit) bitvSet(class, killv
, n); else bitvClear(class, killv, n); } else { found = 1; } }
; }; } }; }
509 }){ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { n = ((def)->foamGen
.hdr.info.defNo); if (n != defNo) { if (bit) bitvSet(class, killv
, n); else bitvClear(class, killv, n); } else { found = 1; } }
; }; } }; }
;
510
511 assert(defNo == -1 || found)do { if (!(defNo == -1 || found)) _do_assert(("defNo == -1 || found"
),"usedef.c",511); } while (0)
;
512 }
513}
514
515/****************************************************************************
516 *
517 * :: Foam traversal and creations of ud chains.
518 *
519 ****************************************************************************/
520
521localstatic void
522udSetReachingList(Foam foam, FoamList defs, Bitv dfin, BBlock block)
523{
524 int defNo;
525 UdInfo udInfo;
526 UdInfoList udList = listNil(UdInfo)((UdInfoList) 0);
527
528 listIter(Foam, def, defs, {{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) udInfo = udInfoNew(foamCopy(def), (BBlock) ((int) 0))
; else udInfo = udInfoNew(def, block); (udList = (UdInfo_listPointer
->Cons)(udInfo, udList)); } }; }; } }; }
529 defNo = udDefNo(def);{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) udInfo = udInfoNew(foamCopy(def), (BBlock) ((int) 0))
; else udInfo = udInfoNew(def, block); (udList = (UdInfo_listPointer
->Cons)(udInfo, udList)); } }; }; } }; }
530
531 /* Still def alive ? */{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) udInfo = udInfoNew(foamCopy(def), (BBlock) ((int) 0))
; else udInfo = udInfoNew(def, block); (udList = (UdInfo_listPointer
->Cons)(udInfo, udList)); } }; }; } }; }
532 if (bitvTest(udProgInfo.bitvClass, dfin, defNo)) {{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) udInfo = udInfoNew(foamCopy(def), (BBlock) ((int) 0))
; else udInfo = udInfoNew(def, block); (udList = (UdInfo_listPointer
->Cons)(udInfo, udList)); } }; }; } }; }
533
534 if (udDefNo(def) < udProgInfo.nPars){ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) udInfo = udInfoNew(foamCopy(def), (BBlock) ((int) 0))
; else udInfo = udInfoNew(def, block); (udList = (UdInfo_listPointer
->Cons)(udInfo, udList)); } }; }; } }; }
535 udInfo = udInfoNew(foamCopy(def),{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) udInfo = udInfoNew(foamCopy(def), (BBlock) ((int) 0))
; else udInfo = udInfoNew(def, block); (udList = (UdInfo_listPointer
->Cons)(udInfo, udList)); } }; }; } }; }
536 (BBlock) int0);{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) udInfo = udInfoNew(foamCopy(def), (BBlock) ((int) 0))
; else udInfo = udInfoNew(def, block); (udList = (UdInfo_listPointer
->Cons)(udInfo, udList)); } }; }; } }; }
537 else{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) udInfo = udInfoNew(foamCopy(def), (BBlock) ((int) 0))
; else udInfo = udInfoNew(def, block); (udList = (UdInfo_listPointer
->Cons)(udInfo, udList)); } }; }; } }; }
538 udInfo = udInfoNew(def, block);{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) udInfo = udInfoNew(foamCopy(def), (BBlock) ((int) 0))
; else udInfo = udInfoNew(def, block); (udList = (UdInfo_listPointer
->Cons)(udInfo, udList)); } }; }; } }; }
539
540 listPush(UdInfo, udInfo, udList);{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) udInfo = udInfoNew(foamCopy(def), (BBlock) ((int) 0))
; else udInfo = udInfoNew(def, block); (udList = (UdInfo_listPointer
->Cons)(udInfo, udList)); } }; }; } }; }
541 }{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) udInfo = udInfoNew(foamCopy(def), (BBlock) ((int) 0))
; else udInfo = udInfoNew(def, block); (udList = (UdInfo_listPointer
->Cons)(udInfo, udList)); } }; }; } }; }
542 }){ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) udInfo = udInfoNew(foamCopy(def), (BBlock) ((int) 0))
; else udInfo = udInfoNew(def, block); (udList = (UdInfo_listPointer
->Cons)(udInfo, udList)); } }; }; } }; }
;
543
544 /* Attach the udList to the used var */
545 if (DEBUG(udDf)udDfDebug) {
546 afprintf(dbOut, "Setting reaching list %pFoam, %pUseDefList\n", foam, udList);
547 }
548
549 udReachingDefs(foam)((foam)->foamGen.hdr.info.defList) = udList;
550}
551
552localstatic Foam
553udSetReachingDef(Foam foam, FoamList defs, Bitv dfin, Bool refContext)
554{
555 Foam uniqueDef = NULL((void*)0);
556 int defNo;
557
558 listIter(Foam, def, defs, {{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) { uniqueDef = ((void*)0); break; } else if (!uniqueDef
) uniqueDef = def; else { uniqueDef = ((void*)0); break; } } }
; }; } }; }
559
560 defNo = udDefNo(def);{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) { uniqueDef = ((void*)0); break; } else if (!uniqueDef
) uniqueDef = def; else { uniqueDef = ((void*)0); break; } } }
; }; } }; }
561
562 /* Still def alive ? */{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) { uniqueDef = ((void*)0); break; } else if (!uniqueDef
) uniqueDef = def; else { uniqueDef = ((void*)0); break; } } }
; }; } }; }
563 if (bitvTest(udProgInfo.bitvClass, dfin, defNo)) {{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) { uniqueDef = ((void*)0); break; } else if (!uniqueDef
) uniqueDef = def; else { uniqueDef = ((void*)0); break; } } }
; }; } }; }
564
565 if (udDefNo(def) < udProgInfo.nPars) {{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) { uniqueDef = ((void*)0); break; } else if (!uniqueDef
) uniqueDef = def; else { uniqueDef = ((void*)0); break; } } }
; }; } }; }
566 uniqueDef = NULL;{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) { uniqueDef = ((void*)0); break; } else if (!uniqueDef
) uniqueDef = def; else { uniqueDef = ((void*)0); break; } } }
; }; } }; }
567 break;{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) { uniqueDef = ((void*)0); break; } else if (!uniqueDef
) uniqueDef = def; else { uniqueDef = ((void*)0); break; } } }
; }; } }; }
568 }{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) { uniqueDef = ((void*)0); break; } else if (!uniqueDef
) uniqueDef = def; else { uniqueDef = ((void*)0); break; } } }
; }; } }; }
569 else if (!uniqueDef){ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) { uniqueDef = ((void*)0); break; } else if (!uniqueDef
) uniqueDef = def; else { uniqueDef = ((void*)0); break; } } }
; }; } }; }
570 uniqueDef = def;{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) { uniqueDef = ((void*)0); break; } else if (!uniqueDef
) uniqueDef = def; else { uniqueDef = ((void*)0); break; } } }
; }; } }; }
571 else {{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) { uniqueDef = ((void*)0); break; } else if (!uniqueDef
) uniqueDef = def; else { uniqueDef = ((void*)0); break; } } }
; }; } }; }
572 uniqueDef = NULL;{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) { uniqueDef = ((void*)0); break; } else if (!uniqueDef
) uniqueDef = def; else { uniqueDef = ((void*)0); break; } } }
; }; } }; }
573 break;{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) { uniqueDef = ((void*)0); break; } else if (!uniqueDef
) uniqueDef = def; else { uniqueDef = ((void*)0); break; } } }
; }; } }; }
574 }{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) { uniqueDef = ((void*)0); break; } else if (!uniqueDef
) uniqueDef = def; else { uniqueDef = ((void*)0); break; } } }
; }; } }; }
575 }{ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) { uniqueDef = ((void*)0); break; } else if (!uniqueDef
) uniqueDef = def; else { uniqueDef = ((void*)0); break; } } }
; }; } }; }
576 }){ { FoamList _l0; Foam def; for (_l0 = (defs); _l0; _l0 = ((_l0
)->rest)) { def = ((_l0)->first); { { defNo = ((def)->
foamGen.hdr.info.defNo); if (bitvTest(udProgInfo.bitvClass, dfin
, defNo)) { if (((def)->foamGen.hdr.info.defNo) < udProgInfo
.nPars) { uniqueDef = ((void*)0); break; } else if (!uniqueDef
) uniqueDef = def; else { uniqueDef = ((void*)0); break; } } }
; }; } }; }
;
577
578 if (DEBUG(udDf)udDfDebug) {
579 afprintf(dbOut, "In %pFoam\n..Setting reaching def %pFoam, %pFoam\n", udLastStmt, foam, uniqueDef);
580 }
581
582 udReachingDefs(foam)((foam)->foamGen.hdr.info.defList) = (UdInfoList) uniqueDef;
583
584 /* Last condition ensure that (Set (Loc 0) (SInt 1)) is not
585 * transformed
586 */
587 if (uniqueDef && !refContext &&
588 otIsMovableData(uniqueDef->foamDef.rhs))
589 return foamCopy(uniqueDef->foamDef.rhs);
590 else
591 return foam;
592}
593
594
595localstatic void
596udCreateUDLists(FlowGraph flog)
597{
598 flogIter(flog, bb, {{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { bb->code = udFindUses(bb->code, ((
bb)->dfinfo->in), bb, ((int) 0)); }; }; } }; }
599 bb->code = udFindUses(bb->code, dfFwdIn(bb), bb, false);{ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { bb->code = udFindUses(bb->code, ((
bb)->dfinfo->in), bb, ((int) 0)); }; }; } }; }
600 }){ { int _i; BBlock bb; for (_i = 0; _i < ((flog)->blocks
->pos); _i++) { bb = bbufBlockFn((flog)->blocks,_i); if
(!bb) continue; { { bb->code = udFindUses(bb->code, ((
bb)->dfinfo->in), bb, ((int) 0)); }; }; } }; }
;
601}
602
603localstatic Foam
604udFindUses(Foam foam, Bitv dfin, BBlock block, Bool refContext)
605{
606 Foam newFoam = foam;
607 Bool track = false((int) 0);
608 switch (foamTag(foam)((foam)->hdr.tag)) {
609 case FOAM_Loc:
610 case FOAM_Par:
611 case FOAM_Lex:
612 case FOAM_Glo: {
613 FoamList defs;
614
615 /* Look which definitions are alive at this point */
616
617 defs = (FoamList) otGetVarInfoList(foam);
618
619 switch (udProgInfo.outputType) {
620 case UD_OUTPUT_UdList:
621 udSetReachingList(foam, defs, dfin, block);
622 break;
623
624 case UD_OUTPUT_SinglePointer:
625 newFoam = udSetReachingDef(foam, defs,
626 dfin,refContext);
627 break;
628
629 default:
630 bug("udFindUses: bad output type...");
631 }
632 break;
633 }
634
635 case FOAM_Set:
636 case FOAM_Def: {
637 int defNo;
638 Foam lhs = foam->foamDef.lhs;
639 BitvClass class = udProgInfo.bitvClass;
640
641 foam->foamDef.rhs = udFindUses(foam->foamDef.rhs,
642 dfin, block, false((int) 0));
643
644 /* E.g.: (Set Lex ...) or (Set (Values ... )(..)) */
645
646 defNo = udDefNo(foam)((foam)->foamGen.hdr.info.defNo);
647
648 if (otIsNonLocalVar(lhs)(((lhs)->hdr.tag) == FOAM_Lex || ((lhs)->hdr.tag) == FOAM_Glo
)
&& foamTag(foam)((foam)->hdr.tag) == FOAM_Set) {
649 udKillAllButThis(dfin, lhs, -1, false((int) 0));
650 return foam;
651 }
652
653 /* E.g.: (Set (EElt ..(Loc 4) ...) */
654 if (!otIsVar(lhs)(((lhs)->hdr.tag) == FOAM_Loc || ((lhs)->hdr.tag) == FOAM_Par
|| ((lhs)->hdr.tag) == FOAM_Lex || ((lhs)->hdr.tag) ==
FOAM_Glo)
&& foamTag(lhs)((lhs)->hdr.tag) != FOAM_Values) {
655 foam->foamDef.lhs = udFindUses(foam->foamDef.lhs,
656 dfin, block, false((int) 0));
657 return foam;
658 }
659
660 /* Cases: (Set/Def (Loc ..)), (Def (Lex/Glo)...) */
661
662 /* Kill the other definitions of lhs */
663 udKillAllButThis(dfin, lhs, defNo, false((int) 0));
664
665 /* Generate this */
666
667 bitvSet(class, dfin, defNo);
668
669 /* Analyse lhs. */
670 foam->foamDef.lhs = udFindUses(foam->foamDef.lhs,
671 dfin, block, true1);
672
673 return foam;
674 }
675 case FOAM_Seq:
676 track = true1;
677 break;
678 default:
679 break;
680 }
681
682 foamIter(foam, arg, {{ { String argf = (foamInfoTable [(int)(((foam)->hdr.tag))
-(int)FOAM_START]).argf; Length _i; for (_i = 0; _i < ((foam
)->hdr.argc); _i++, argf++) { if (*argf == '*') argf--; if
(*argf == 'C') { Foam *arg = (Foam *) ((foam)->foamGen.argv
)+_i; { { if (track) udLastStmt = *arg; *arg = udFindUses(*arg
, dfin, block, refContext); if (track) udLastStmt = ((void*)0
); }; }; } } }; }
683 if (track) udLastStmt = *arg;{ { String argf = (foamInfoTable [(int)(((foam)->hdr.tag))
-(int)FOAM_START]).argf; Length _i; for (_i = 0; _i < ((foam
)->hdr.argc); _i++, argf++) { if (*argf == '*') argf--; if
(*argf == 'C') { Foam *arg = (Foam *) ((foam)->foamGen.argv
)+_i; { { if (track) udLastStmt = *arg; *arg = udFindUses(*arg
, dfin, block, refContext); if (track) udLastStmt = ((void*)0
); }; }; } } }; }
684 *arg = udFindUses(*arg, dfin, block, refContext);{ { String argf = (foamInfoTable [(int)(((foam)->hdr.tag))
-(int)FOAM_START]).argf; Length _i; for (_i = 0; _i < ((foam
)->hdr.argc); _i++, argf++) { if (*argf == '*') argf--; if
(*argf == 'C') { Foam *arg = (Foam *) ((foam)->foamGen.argv
)+_i; { { if (track) udLastStmt = *arg; *arg = udFindUses(*arg
, dfin, block, refContext); if (track) udLastStmt = ((void*)0
); }; }; } } }; }
685 if (track) udLastStmt = NULL;{ { String argf = (foamInfoTable [(int)(((foam)->hdr.tag))
-(int)FOAM_START]).argf; Length _i; for (_i = 0; _i < ((foam
)->hdr.argc); _i++, argf++) { if (*argf == '*') argf--; if
(*argf == 'C') { Foam *arg = (Foam *) ((foam)->foamGen.argv
)+_i; { { if (track) udLastStmt = *arg; *arg = udFindUses(*arg
, dfin, block, refContext); if (track) udLastStmt = ((void*)0
); }; }; } } }; }
686 }){ { String argf = (foamInfoTable [(int)(((foam)->hdr.tag))
-(int)FOAM_START]).argf; Length _i; for (_i = 0; _i < ((foam
)->hdr.argc); _i++, argf++) { if (*argf == '*') argf--; if
(*argf == 'C') { Foam *arg = (Foam *) ((foam)->foamGen.argv
)+_i; { { if (track) udLastStmt = *arg; *arg = udFindUses(*arg
, dfin, block, refContext); if (track) udLastStmt = ((void*)0
); }; }; } } }; }
;
687 return newFoam;
688}
689
690
691/****************************************************************************
692 *
693 * :: Constructors and Destructors
694 *
695 ****************************************************************************/
696
697localstatic UdInfo
698udInfoNew(Foam def, BBlock block)
699{
700 UdInfo udinfo = (UdInfo) stoAlloc(OB_Other0, sizeof(*udinfo));
701
702 udinfo->foam = def;
703 udinfo->block = block;
704
705 return udinfo;
706}
707
708
709#if 0 /* DON'T REMOVE ! */
710
711localstatic void
712udInfoFree(UdInfo ud)
713{
714 if (!ud) return;
715
716 /* if (udIsFalseDef(ud)) foamFree(udInfoDef(ud)); !!$$*/
717 stoFree(ud);
718}
719
720#endif