Bug Summary

File:src/of_retyp2.c
Warning:line 693, column 3
Value stored to 'orig' 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 of_retyp2.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 of_retyp2.c
1#include "foam.h"
2#include "debug.h"
3#include "javasig.h"
4#include "of_peep.h"
5#include "of_retyp.h"
6#include "of_util.h"
7#include "optfoam.h"
8#include "opttools.h"
9#include "store.h"
10#include "fbox.h"
11#include "syme.h"
12#include "util.h"
13
14/*
15 * Retype pass.
16 *
17 * This replaces Word valued variables with more specific types.
18 * Algorithm is to run over the foam, and any instances of (Cast XX (Loc Y))
19 * indicate that Y may be converted to XX, provided that Y is a Word and
20 * other casts do not conflict.
21 *
22 * A caveat: This will break if the same variable is used for values of
23 * two differently represented types (eg. BInt and Double).. genfoam should not
24 * generate any cases like this, but optimisations might.
25 */
26
27/******************************************************************************
28 *
29 * :: Debug
30 *
31 *****************************************************************************/
32
33Bool retDebug = false((int) 0);
34
35#define retDEBUGif (!retDebug) { } else afprintf DEBUG_IF(ret)if (!retDebug) { } else afprintf
36
37
38
39localstatic void rtcReplaceDecls(RetContext context);
40localstatic void rtcRearrangeMultiAssign(RetContext context);
41
42localstatic FoamTag rtcFoamExprType(RetContext context, Foam foam, AInt *pfmt);
43localstatic FoamList rtcMultiAssignVars(RetContext context, FoamBox tempLocals, Foam lhs);
44localstatic Foam rtcMultiAssignValues(RetContext context, FoamList extraVars, Foam lhs);
45localstatic FoamList rtcMultiAssignFollows(RetContext context, FoamList extraVars, Foam lhs);
46
47
48localstatic Bool retCanConvert(FoamTag fromType, FoamTag toType);
49localstatic Bool retIsCompatible(RetContext context, Foam currentDecl, FoamTag type, AInt fmt);
50localstatic void retAddUse(RetContext context, FoamTag type, AInt fmt, Foam foam);
51localstatic void retRetypeProg(RetContext context, Foam prog);
52localstatic void retMarkCasts(RetContext context, Foam prog);
53localstatic void retMarkExpr(RetContext context, Foam foam);
54localstatic void retMarkPCallJava(RetContext context, Foam foam);
55localstatic void retMarkPCall(RetContext context, Foam foam);
56localstatic Bool retRearrangeProg(RetContext context);
57localstatic Foam retRearrangeExpr(RetContext context, Foam expr, Bool isLhs);
58localstatic Foam retRearrangeSet(RetContext context, Foam set);
59localstatic Foam retRearrangeVar(RetContext context, Foam var);
60localstatic Foam retCast(RetContext context, FoamTag type, Foam foam);
61localstatic Foam retPeepCasts(Foam foam);
62localstatic Bool retIsLocal(Foam foam);
63localstatic Foam retLocal(Foam foam);
64
65
66RetContext
67rtcInit(Foam unit)
68{
69 RetContext context = (RetContext) stoAlloc(OB_Other0, sizeof(*context));
70 context->formats = unit->foamUnit.formats;
71 context->globals = unit->foamUnit.formats->foamDFmt.argv[globalsSlot0];
72 context->locDecls = NULL((void*)0);
73 context->parDecls = NULL((void*)0);
74 context->parLocs = NULL((void*)0);
75 context->nUses = NULL((void*)0);
76 context->nLocals = 0;
77 return context;
78}
79
80RetContext
81rtcNewProg(RetContext global, Foam prog, int nLocals)
82{
83 int nParams = foamDDeclArgc(prog->foamProg.params)(((prog->foamProg.params)->hdr.argc) - (1));
84 int i;
85
86 RetContext context = (RetContext) stoAlloc(OB_Other0, sizeof(*context));
87
88 context->locDecls = (Foam *) stoAlloc(OB_Other0, nLocals * sizeof(Foam));
89 context->parDecls = (Foam *) stoAlloc(OB_Other0, nParams * sizeof(Foam));
90 context->parLocs = NULL((void*)0);
91 context->nUses = (int *) stoAlloc(OB_Other0, nParams * sizeof(int));
92 context->nLocals = nLocals;
93
94 context->formats = global->formats;
95 context->globals = global->globals;
96 context->prog = prog;
97 for (i = 0; i < nLocals; i++) {
98 context->locDecls[i] = foamCopy(context->prog->foamProg.locals->foamDDecl.argv[i]);
99 }
100 for (i = 0; i < nParams; i++) {
101 context->parDecls[i] = foamCopy(context->prog->foamProg.params->foamDDecl.argv[i]);
102 context->nUses[i] = 0;
103 }
104 return context;
105}
106
107void
108rtcFree(RetContext context)
109{
110 stoFree(context->locDecls);
111 stoFree(context->parDecls);
112 stoFree(context->parLocs);
113 stoFree(context->nUses);
114 stoFree(context);
115}
116
117FoamTag
118rtcFoamExprType(RetContext context, Foam foam, AInt *pfmt)
119{
120 return foamExprType0(foam, context->prog, context->formats,
121 NULL((void*)0), NULL((void*)0), pfmt);
122}
123
124Foam
125rtcCurrentDecl(RetContext context, Foam foam)
126{
127 Foam decl;
128
129 decl = rtcNewDecl(context, foam);
130 if (decl != NULL((void*)0))
131 return decl;
132
133 return rtcOriginalDecl(context, foam);
134}
135
136Foam
137rtcOriginalDecl(RetContext context, Foam foam)
138{
139 Foam decl;
140 int index;
141
142 switch (foamTag(foam)((foam)->hdr.tag)) {
143 case FOAM_Loc:
144 index = foam->foamLoc.index;
145 decl = context->prog->foamProg.locals->foamDDecl.argv[index];
146 break;
147 case FOAM_Par:
148 index = foam->foamPar.index;
149 decl = context->prog->foamProg.params->foamDDecl.argv[index];
150 break;
151 default:
152 decl = NULL((void*)0);
153 bug("bad case");
154 }
155 return decl;
156}
157
158Bool
159rtcHasNewDecl(RetContext context, Foam foam)
160{
161 Foam decl = rtcNewDecl(context, foam);
162 if (decl == NULL((void*)0))
163 return false((int) 0);
164
165 return true1;
166}
167
168Foam
169rtcNewDecl(RetContext context, Foam foam)
170{
171 Foam decl;
172 int index;
173
174 switch (foamTag(foam)((foam)->hdr.tag)) {
175 case FOAM_Loc:
176 index = foam->foamLoc.index;
177 if (index < context->nLocals)
178 decl = context->locDecls[index];
179 else
180 decl = NULL((void*)0);
181 break;
182 case FOAM_Par:
183 index = foam->foamPar.index;
184 decl = context->parDecls[index];
185 break;
186 default:
187 decl = NULL((void*)0);
188 bug("bad case");
189 }
190 return decl;
191}
192
193void
194rtcSetUnchanged(RetContext context, Foam foam)
195{
196 AInt index;
197
198 retDEBUGif (!retDebug) { } else afprintf(dbOut, "Not changing %pFoam\n", foam);
199
200 switch (foamTag(foam)((foam)->hdr.tag)) {
201 case FOAM_Loc:
202 index = foam->foamLoc.index;
203 if (index < context->nLocals)
204 context->locDecls[index] = NULL((void*)0);
205 break;
206 case FOAM_Par:
207 index = foam->foamPar.index;
208 context->parDecls[index] = NULL((void*)0);
209 break;
210 default:
211 bug("bad case");
212 }
213}
214
215void
216rtcAddUse(RetContext context, Foam foam)
217{
218 if (foamTag(foam)((foam)->hdr.tag) == FOAM_Par) {
219 context->nUses[foam->foamPar.index]++;
220 }
221}
222
223void
224rtcSetType(RetContext context, Foam foam, FoamTag type, AInt fmt)
225{
226 Foam decl;
227
228 decl = rtcNewDecl(context, foam);
229 if (decl == NULL((void*)0)) {
230 return;
231 }
232 retDEBUGif (!retDebug) { } else afprintf(dbOut, "Changing %pFoam from %s(%d) to %s (%d)\n", foam,
233 foamStr(decl->foamDecl.type)((foamInfoTable [(int)(decl->foamDecl.type)-(int)FOAM_START
]).str)
, decl->foamDecl.format,
234 foamStr(type)((foamInfoTable [(int)(type)-(int)FOAM_START]).str), fmt);
235
236 if (type == FOAM_Rec && decl->foamDecl.type == FOAM_Rec) {
237 if (fmt == 0 && decl->foamDecl.format != 0)
238 bug("Bad conversion");
239 }
240
241 decl->foamDecl.type = type;
242 decl->foamDecl.format = fmt;
243}
244
245localstatic void
246retAddUse(RetContext context, FoamTag type, AInt fmt, Foam foam)
247{
248
249 Foam currentDecl = rtcCurrentDecl(context, foam);
250 Foam originalDecl = rtcOriginalDecl(context, foam);
251 FoamTag currentType = currentDecl->foamDecl.type;
252 AInt currentFmt = currentDecl->foamDecl.format;
253
254 rtcAddUse(context, foam);
255
256 if (!retIsCompatible(context, currentDecl, type, fmt)) {
257 rtcSetUnchanged(context, foam);
258 return;
259 }
260
261 if (!retCanConvert(originalDecl->foamDecl.type, type)) {
262 return;
263 }
264
265 if (type == FOAM_Rec && fmt == 0) {
266 return;
267 }
268
269 if (currentType == type && currentFmt == fmt)
270 return;
271
272 rtcSetType(context, foam, type, fmt);
273}
274
275localstatic Bool
276retIsCompatible(RetContext context, Foam currentDecl, FoamTag type, AInt fmt)
277{
278 FoamTag currentType = currentDecl->foamDecl.type;
279 FoamTag currentFmt = currentDecl->foamDecl.format;
280 if (currentType == FOAM_Word)
281 return true1;
282
283 switch (type) {
284 case FOAM_Rec:
285 if (currentType == FOAM_Rec)
286 return currentFmt == 0 || currentFmt == fmt || fmt == 0;
287 return false((int) 0);
288 case FOAM_Arr:
289 if (currentType == FOAM_Arr)
290 return currentFmt == 0 || currentFmt == fmt || fmt == 0;
291 return false((int) 0);
292 default:
293 if (currentType == type)
294 return true1;
295 break;
296 }
297
298 return false((int) 0);
299}
300
301
302/*
303 * T --> T no
304 * X --> Word no
305 * Word --> Any yes
306 * Any --> Any no
307 */
308localstatic Bool
309retCanConvert(FoamTag fromType, FoamTag toType)
310{
311 if (fromType == toType) {
312 return false((int) 0);
313 }
314 if (toType == FOAM_Word) {
315 return false((int) 0);
316 }
317 if (toType == FOAM_Clos) {
318 return false((int) 0);
319 }
320 if (toType == FOAM_Ptr) {
321 return false((int) 0);
322 }
323 if (fromType == FOAM_Word) {
324 return true1;
325 }
326 return false((int) 0);
327}
328
329
330void
331retypeUnit(Foam foam)
332{
333 RetContext globals;
334 int i;
335
336 assert(foamTag(foam) == FOAM_Unit)do { if (!(((foam)->hdr.tag) == FOAM_Unit)) _do_assert(("foamTag(foam) == FOAM_Unit"
),"of_retyp2.c",336); } while (0)
;
337 globals = rtcInit(foam);
338
339 for (i = 0; i < foamArgc(foam->foamUnit.defs)((foam->foamUnit.defs)->hdr.argc); i++) {
340 Foam decl, def;
341
342 def = foam->foamUnit.defs->foamDDef.argv[i];
343
344 if (foamTag(def->foamDef.lhs)((def->foamDef.lhs)->hdr.tag) != FOAM_Const) continue;
345 if (foamTag(def->foamDef.rhs)((def->foamDef.rhs)->hdr.tag) != FOAM_Prog) continue;
346
347 decl = foamUnitConstants(foam)((((foam)->foamUnit.formats)->foamGen.argv)[1].code)->foamDDecl.argv[i];
348
349 retDEBUGif (!retDebug) { } else afprintf(dbOut, "(Retype begins.. %d - %s\n", i, decl->foamDecl.id);
350
351 retRetypeProg(globals, def->foamDef.rhs);
352
353 retDEBUGif (!retDebug) { } else afprintf(dbOut, " Retype ends.. %d - %s)\n", i, decl->foamDecl.id);
354 }
355
356 rtcFree(globals);
357}
358
359localstatic void
360retRetypeProg(RetContext globals, Foam prog)
361{
362 Bool changed = true1;
363 int nLocals = foamDDeclArgc(prog->foamProg.locals)(((prog->foamProg.locals)->hdr.argc) - (1));
364 while (changed) {
365 RetContext context = rtcNewProg(globals, prog, nLocals);
366
367 retDEBUGif (!retDebug) { } else afprintf(dbOut, "Initial:\n%pFoam\n", prog);
368 retPeepCasts(prog);
369
370 retMarkCasts(context, prog);
371
372 changed = rtcRearrangeProg(context);
373
374 retDEBUGif (!retDebug) { } else afprintf(dbOut, "Final:\n%pFoam\n", prog);
375 rtcFree(context);
376 }
377}
378
379localstatic void
380retMarkCasts(RetContext context, Foam prog)
381{
382 retMarkExpr(context, prog->foamProg.body);
383}
384
385localstatic Foam
386retLocal(Foam foam)
387{
388 switch (foamTag(foam)((foam)->hdr.tag)) {
389 case FOAM_Loc:
390 case FOAM_Par:
391 return foam;
392 case FOAM_Cast:
393 return retLocal(foam->foamCast.expr);
394 case FOAM_RElt:
395 return retLocal(foam->foamRElt.expr);
396 /* FOAM_Arr, FOAM_TRElt, etc */
397 default:
398 return NULL((void*)0);
399 }
400
401 return foam;
402}
403
404localstatic Bool
405retIsLocal(Foam foam)
406{
407 return retLocal(foam) != NULL((void*)0);
408}
409
410
411localstatic void
412retMarkExpr(RetContext context, Foam foam)
413{
414 foamIter(foam, arg, retMarkExpr(context, *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; { retMarkExpr(context, *arg);; }; } } }; }
;
415
416 switch (foamTag(foam)((foam)->hdr.tag)) {
417 case FOAM_Cast:
418 if (retIsLocal(foam)) {
419 retAddUse(context, foam->foamCast.type, 0, retLocal(foam));
420 }
421 break;
422 case FOAM_RElt:
423 if (retIsLocal(foam)) {
424 retAddUse(context, FOAM_Rec, foam->foamRElt.format, retLocal(foam));
425 }
426 break;
427 case FOAM_PCall:
428 retMarkPCall(context, foam);
429 break;
430 case FOAM_Set:
431 case FOAM_Def:
432 break;
433
434 default:
435 break;
436 }
437}
438
439localstatic void
440retMarkPCall(RetContext context, Foam foam)
441{
442 switch (foam->foamPCall.protocol) {
443 case FOAM_Proto_Java:
444 case FOAM_Proto_JavaMethod:
445 case FOAM_Proto_JavaConstructor:
446 retMarkPCallJava(context, foam);
447 default:
448 break;
449 }
450}
451
452localstatic void
453retMarkPCallJava(RetContext context, Foam foam)
454{
455 Foam op = foam->foamPCall.op;
456
457 if (foamTag(op)((op)->hdr.tag) != FOAM_Glo) {
458 return;
459 }
460
461 Foam gdecl = context->globals->foamDDecl.argv[op->foamGlo.index];
462 Foam ddecl = context->formats->foamDFmt.argv[gdecl->foamGDecl.format];
463
464 for (int i=0; i<foamPCallArgc(foam)(((foam)->hdr.argc) - (3)); i++) {
465 Foam arg = foam->foamPCall.argv[i];
466 if (retIsLocal(arg)) {
467 retAddUse(context,
468 javaSigArgN(ddecl, i)->foamDecl.type,
469 javaSigArgN(ddecl, i)->foamDecl.format,
470 //ddecl->foamDDecl.argv[i+1]->foamDecl.type,
471 //ddecl->foamDDecl.argv[i+1]->foamDecl.format,
472 retLocal(arg));
473 }
474 }
475}
476
477
478
479Bool
480rtcRearrangeProg(RetContext context)
481{
482 FoamBox newLocals;
483 FoamList newAssignments;
484 Foam prog = context->prog;
485 int i;
486 int paramCount = foamDDeclArgc(prog->foamProg.params)(((prog->foamProg.params)->hdr.argc) - (1));
487 int changeCount = 0;
488 /* Mark locals that should be converted */
489 for (i = 0; i < context->nLocals; i++) {
490 Foam origDecl = prog->foamProg.locals->foamDDecl.argv[i];
491 if (context->locDecls[i] == NULL((void*)0)) {
492 }
493 else if (foamDeclEqual(origDecl,
494 context->locDecls[i])) {
495 foamFree(context->locDecls[i]);
496 context->locDecls[i] = NULL((void*)0);
497 }
498 else if (origDecl->foamDecl.symeIndex != SYME_NUMBER_UNASSIGNED(0x7FFF)) {
499 foamFree(context->locDecls[i]);
500 context->locDecls[i] = NULL((void*)0);
501 }
502 else {
503 changeCount++;
504 }
505 }
506
507 /* Mark params that should be converted */
508 for (i = 0; i < paramCount; i++) {
509 Foam origDecl = prog->foamProg.params->foamDDecl.argv[i];
510 if (context->parDecls[i] == NULL((void*)0)) {
511 }
512 else if (foamDeclEqual(origDecl,
513 context->parDecls[i])) {
514 foamFree(context->parDecls[i]);
515 context->parDecls[i] = NULL((void*)0);
516 }
517 else if (context->nUses[i] <= 1) {
518 foamFree(context->parDecls[i]);
519 context->parDecls[i] = NULL((void*)0);
520 }
521 else if (origDecl->foamDecl.symeIndex != -1) {
522 foamFree(context->parDecls[i]);
523 context->parDecls[i] = NULL((void*)0);
524 }
525 else {
526 changeCount++;
527 }
528
529 }
530
531 if (changeCount == 0)
532 return false((int) 0);
533
534 /* Deal with values in set statements */
535 rtcRearrangeMultiAssign(context);
536
537 /* Parameters */
538 newLocals = fboxNew(prog->foamProg.locals);
539 newAssignments = listNil(Foam)((FoamList) 0);
540
541 context->parLocs = (int *) stoAlloc(OB_Other0,
542 sizeof(Foam) * foamDDeclArgc(prog->foamProg.params)(((prog->foamProg.params)->hdr.argc) - (1)));
543 for (i = 0; i < foamDDeclArgc(prog->foamProg.params)(((prog->foamProg.params)->hdr.argc) - (1)); i++) {
544 Foam newDecl = context->parDecls[i];
545 if (context->parDecls[i] != NULL((void*)0)) {
546 int id = fboxAdd(newLocals, newDecl);
547 Foam newAssignment = foamNewSet(foamNewLoc(id),foamNew(FOAM_Set, 2, foamNew(FOAM_Loc, 1, (AInt)(id)), foamNew
(FOAM_Cast, 2, newDecl->foamDecl.type, foamNew(FOAM_Par, 1
, (AInt)(i))))
548 foamNewCast(newDecl->foamDecl.type,foamNew(FOAM_Set, 2, foamNew(FOAM_Loc, 1, (AInt)(id)), foamNew
(FOAM_Cast, 2, newDecl->foamDecl.type, foamNew(FOAM_Par, 1
, (AInt)(i))))
549 foamNewPar(i)))foamNew(FOAM_Set, 2, foamNew(FOAM_Loc, 1, (AInt)(id)), foamNew
(FOAM_Cast, 2, newDecl->foamDecl.type, foamNew(FOAM_Par, 1
, (AInt)(i))))
;
550 newAssignments = listCons(Foam)(Foam_listPointer->Cons)(newAssignment, newAssignments);
551 context->parLocs[i] = id;
552 }
553 else {
554 context->parLocs[i] = -1;
555 }
556 }
557 prog->foamProg.locals = fboxMake(newLocals);
558
559 if (newAssignments == listNil(Foam)((FoamList) 0))
560 retRearrangeExpr(context, context->prog->foamProg.body, false((int) 0));
561 else {
562 int bodyArgc = foamArgc(prog->foamProg.body)((prog->foamProg.body)->hdr.argc);
563 Foam newSeq = foamNewEmpty(FOAM_Seq,
564 bodyArgc + listLength(Foam)(Foam_listPointer->_Length)(newAssignments));
565 int i = 0, j = 0;
566 while (newAssignments != listNil(Foam)((FoamList) 0)) {
567 newSeq->foamSeq.argv[i] = car(newAssignments)((newAssignments)->first);
568 newAssignments = listFreeCons(Foam)(Foam_listPointer->FreeCons)(newAssignments);
569 i++;
570 }
571
572 for (j = 0; j < bodyArgc; j++) {
573 newSeq->foamSeq.argv[i] = retRearrangeExpr(context,
574 prog->foamProg.body->foamSeq.argv[j],
575 false((int) 0));
576 i++;
577 }
578 foamFreeNode(prog->foamProg.body);
579 prog->foamProg.body = newSeq;
580 }
581
582 for (i = 0; i < context->nLocals; i++) {
583 if (context->locDecls[i] != NULL((void*)0)) {
584 foamFreeNode(prog->foamProg.locals->foamDDecl.argv[i]);
585 prog->foamProg.locals->foamDDecl.argv[i] = context->locDecls[i];
586 }
587 }
588
589 return true1;
590}
591
592localstatic void
593rtcRearrangeMultiAssign(RetContext context)
594{
595 Foam prog = context->prog;
596 Bool hasMultiAssign = foamProgHasMultiAssign(prog);
597 int i;
598
599 if (hasMultiAssign) {
600 FoamBox tmpLocals = fboxNew(prog->foamProg.locals);
601 FoamBox stmts = fboxNewEmpty(FOAM_Seq);
602 Foam seq = prog->foamProg.body;
603 int bodyArgc = foamArgc(seq)((seq)->hdr.argc);
604 for (i=0; i<bodyArgc; i++) {
605 Foam stmt = seq->foamSeq.argv[i];
606 if (!foamIsMultiAssign(stmt))
607 fboxAdd(stmts, stmt);
608 else {
609 Foam lhs = stmt->foamSet.lhs;
610 Foam rhs = stmt->foamSet.rhs;
611 FoamList extraVars = rtcMultiAssignVars(context, tmpLocals, lhs);
612 Foam modifiedValues = rtcMultiAssignValues(context, extraVars, lhs);
613 FoamList extraStmts = rtcMultiAssignFollows(context, extraVars, lhs);
614
615 fboxAdd(stmts, foamNewSet(modifiedValues, rhs)foamNew(FOAM_Set, 2, modifiedValues, rhs));
616 while (extraStmts != listNil(Foam)((FoamList) 0)) {
617 fboxAdd(stmts, car(extraStmts)((extraStmts)->first));
618 extraStmts = listFreeCons(Foam)(Foam_listPointer->FreeCons)(extraStmts);
619 }
620 while (extraVars != listNil(Foam)((FoamList) 0)) {
621 foamFreeNode(car(extraVars)((extraVars)->first));
622 extraVars = listFreeCons(Foam)(Foam_listPointer->FreeCons)(extraVars);
623 }
624 }
625 }
626 prog->foamProg.locals = fboxMake(tmpLocals);
627 prog->foamProg.body = fboxMake(stmts);
628 }
629}
630
631
632localstatic FoamList
633rtcMultiAssignVars(RetContext context, FoamBox tempLocals, Foam lhs)
634{
635 FoamList extraVars = listNil(Foam)((FoamList) 0);
636 int i;
637
638 for (i=0; i<foamArgc(lhs)((lhs)->hdr.argc); i++) {
639 Foam loc = lhs->foamValues.argv[i];
640 if (!rtcHasNewDecl(context, loc))
641 extraVars = listCons(Foam)(Foam_listPointer->Cons)(NULL((void*)0), extraVars);
642 else {
643 int id = fboxAdd(tempLocals, foamCopy(rtcOriginalDecl(context, loc)));
644 extraVars = listCons(Foam)(Foam_listPointer->Cons)(foamNewLoc(id)foamNew(FOAM_Loc, 1, (AInt)(id)), extraVars);
645 }
646 }
647 return listNReverse(Foam)(Foam_listPointer->NReverse)(extraVars);
648}
649
650localstatic Foam
651rtcMultiAssignValues(RetContext context, FoamList extraVars, Foam lhs)
652{
653 FoamBox box = fboxNewEmpty(FOAM_Values);
654 int i;
655 for (i=0; i<foamArgc(lhs)((lhs)->hdr.argc); i++) {
656 if (car(extraVars)((extraVars)->first) == NULL((void*)0))
657 fboxAdd(box, lhs->foamValues.argv[i]);
658 else
659 fboxAdd(box, foamCopy(car(extraVars)((extraVars)->first)));
660 extraVars = cdr(extraVars)((extraVars)->rest);
661 }
662
663 return fboxMake(box);
664}
665
666localstatic FoamList
667rtcMultiAssignFollows(RetContext context, FoamList extraVars, Foam lhs)
668{
669 FoamList follows = listNil(Foam)((FoamList) 0);
670 int i;
671
672 for (i=0; i<foamArgc(lhs)((lhs)->hdr.argc); i++) {
673 if (car(extraVars)((extraVars)->first) != NULL((void*)0)) {
674 follows = listCons(Foam)(Foam_listPointer->Cons)(foamNewSet(lhs->foamValues.argv[i],foamNew(FOAM_Set, 2, lhs->foamValues.argv[i], foamCopy(((extraVars
)->first)))
675 foamCopy(car(extraVars)))foamNew(FOAM_Set, 2, lhs->foamValues.argv[i], foamCopy(((extraVars
)->first)))
,
676 follows);
677 }
678
679 extraVars = cdr(extraVars)((extraVars)->rest);
680 }
681 return listNReverse(Foam)(Foam_listPointer->NReverse)(follows);
682}
683
684localstatic Foam
685retRearrangeExpr(RetContext context, Foam expr, Bool isLhs)
686{
687 Foam result;
688 Foam orig = expr;
689
690 switch (foamTag(expr)((expr)->hdr.tag)) {
691 case FOAM_Set:
692 case FOAM_Def:
693 orig = foamCopy(expr);
Value stored to 'orig' is never read
694 result = retRearrangeSet(context, expr);
695 return result;
696 }
697 foamIter(expr, arg, *arg = retRearrangeExpr(context, *arg, false)){ { String argf = (foamInfoTable [(int)(((expr)->hdr.tag))
-(int)FOAM_START]).argf; Length _i; for (_i = 0; _i < ((expr
)->hdr.argc); _i++, argf++) { if (*argf == '*') argf--; if
(*argf == 'C') { Foam *arg = (Foam *) ((expr)->foamGen.argv
)+_i; { *arg = retRearrangeExpr(context, *arg, ((int) 0)); };
} } }; }
;
698
699 switch (foamTag(expr)((expr)->hdr.tag)) {
700 case FOAM_Loc:
701 case FOAM_Par:
702 orig = foamCopy(expr);
703 result = retRearrangeVar(context, expr);
704 break;
705 case FOAM_Cast:
706 if (foamTag(expr->foamCast.expr)((expr->foamCast.expr)->hdr.tag) == FOAM_Cast) {
707 Foam value = expr->foamCast.expr->foamCast.expr;
708 foamFreeNode(expr->foamCast.expr);
709 expr->foamCast.expr = value;
710 }
711 result = expr;
712 break;
713 default:
714 result = expr;
715 break;
716 }
717
718 if (expr != result) {
719 retDEBUGif (!retDebug) { } else afprintf(dbOut, " Rearranged: %pFoam to %pFoam\n", orig, result);
720 }
721 return result;
722}
723
724localstatic Bool
725retIsVar(Foam foam)
726{
727 return foamTag(foam)((foam)->hdr.tag) == FOAM_Loc || foamTag(foam)((foam)->hdr.tag) == FOAM_Par;
728}
729
730localstatic Foam
731retRearrangeSet(RetContext context, Foam set)
732{
733 Foam decl;
734 Foam lhs = set->foamSet.lhs;
735 Foam rhs = set->foamSet.rhs;
736
737 set->foamSet.rhs = retRearrangeExpr(context, rhs, false((int) 0));
738
739 if (!retIsVar(lhs)) {
740 set->foamSet.lhs = retRearrangeExpr(context, lhs, true1);
741 return set;
742 }
743 if (!rtcHasNewDecl(context, lhs)) {
744 return set;
745 }
746 decl = rtcCurrentDecl(context, lhs);
747
748 foamFreeNode(set);
749
750 return foamNewSet(lhs, foamNewCast(decl->foamDecl.type, rhs))foamNew(FOAM_Set, 2, lhs, foamNew(FOAM_Cast, 2, decl->foamDecl
.type, rhs))
;
751}
752
753localstatic Foam
754retRearrangeVar(RetContext context, Foam var)
755{
756 Foam originalDecl;
757 int index;
758
759 if (!rtcHasNewDecl(context, var))
760 return var;
761
762 originalDecl = rtcOriginalDecl(context, var);
763
764 index = var->foamPar.index;
765 if (foamTag(var)((var)->hdr.tag) == FOAM_Par
766 && context->parLocs[index] != -1) {
767 foamFree(var);
768 var = foamNewLoc(context->parLocs[index])foamNew(FOAM_Loc, 1, (AInt)(context->parLocs[index]));
769 }
770 return foamNewCast(originalDecl->foamDecl.type, var)foamNew(FOAM_Cast, 2, originalDecl->foamDecl.type, var);
771}
772
773localstatic Foam
774retCast(RetContext context, FoamTag type, Foam foam)
775{
776 FoamTag current;
777
778 while (foamTag(foam)((foam)->hdr.tag) == FOAM_Cast)
779 foam = foam->foamCast.expr;
780
781 current = rtcFoamExprType(context, foam, NULL((void*)0));
782
783 if (type != current)
784 return foamNewCast(type, foam)foamNew(FOAM_Cast, 2, type, foam);
785 else
786 return foam;
787}
788
789
790localstatic Foam
791retPeepCasts(Foam foam)
792{
793 Foam value;
794 AInt type;
795
796 foamIter(foam, arg, *arg = retPeepCasts(*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; { *arg = retPeepCasts(*arg);; }; } } }; }
;
797
798 if (foamTag(foam)((foam)->hdr.tag) != FOAM_Cast) return foam;
799
800 value = foam->foamCast.expr;
801
802 /* Dereference Casts releasing unused nodes */
803 while (foamTag(value)((value)->hdr.tag) == FOAM_Cast) {
804 Foam expr = value->foamCast.expr;
805 foamFreeNode(value);
806 value = expr;
807 }
808
809 if (foamTag(value)((value)->hdr.tag) == FOAM_BCall)
810 type = foamBValInfo(value->foamBCall.op)(foamBValInfoTable[(int)(value->foamBCall.op)-(int)FOAM_BVAL_START
])
.retType;
811
812 else if (foamTag(value)((value)->hdr.tag) == FOAM_CCall)
813 type = value->foamCCall.type;
814 else
815 type = FOAM_NOp;
816
817 if (foam->foamCast.type == type) {
818 foamFreeNode(foam);
819 return value;
820 }
821 else {
822 foam->foamCast.expr = value;
823 return foam;
824 }
825}