| File: | src/of_retyp2.c |
| Warning: | line 693, column 3 Value stored to 'orig' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 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 | |
| 33 | Bool retDebug = false((int) 0); |
| 34 | |
| 35 | #define retDEBUGif (!retDebug) { } else afprintf DEBUG_IF(ret)if (!retDebug) { } else afprintf |
| 36 | |
| 37 | |
| 38 | |
| 39 | localstatic void rtcReplaceDecls(RetContext context); |
| 40 | localstatic void rtcRearrangeMultiAssign(RetContext context); |
| 41 | |
| 42 | localstatic FoamTag rtcFoamExprType(RetContext context, Foam foam, AInt *pfmt); |
| 43 | localstatic FoamList rtcMultiAssignVars(RetContext context, FoamBox tempLocals, Foam lhs); |
| 44 | localstatic Foam rtcMultiAssignValues(RetContext context, FoamList extraVars, Foam lhs); |
| 45 | localstatic FoamList rtcMultiAssignFollows(RetContext context, FoamList extraVars, Foam lhs); |
| 46 | |
| 47 | |
| 48 | localstatic Bool retCanConvert(FoamTag fromType, FoamTag toType); |
| 49 | localstatic Bool retIsCompatible(RetContext context, Foam currentDecl, FoamTag type, AInt fmt); |
| 50 | localstatic void retAddUse(RetContext context, FoamTag type, AInt fmt, Foam foam); |
| 51 | localstatic void retRetypeProg(RetContext context, Foam prog); |
| 52 | localstatic void retMarkCasts(RetContext context, Foam prog); |
| 53 | localstatic void retMarkExpr(RetContext context, Foam foam); |
| 54 | localstatic void retMarkPCallJava(RetContext context, Foam foam); |
| 55 | localstatic void retMarkPCall(RetContext context, Foam foam); |
| 56 | localstatic Bool retRearrangeProg(RetContext context); |
| 57 | localstatic Foam retRearrangeExpr(RetContext context, Foam expr, Bool isLhs); |
| 58 | localstatic Foam retRearrangeSet(RetContext context, Foam set); |
| 59 | localstatic Foam retRearrangeVar(RetContext context, Foam var); |
| 60 | localstatic Foam retCast(RetContext context, FoamTag type, Foam foam); |
| 61 | localstatic Foam retPeepCasts(Foam foam); |
| 62 | localstatic Bool retIsLocal(Foam foam); |
| 63 | localstatic Foam retLocal(Foam foam); |
| 64 | |
| 65 | |
| 66 | RetContext |
| 67 | rtcInit(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 | |
| 80 | RetContext |
| 81 | rtcNewProg(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 | |
| 107 | void |
| 108 | rtcFree(RetContext context) |
| 109 | { |
| 110 | stoFree(context->locDecls); |
| 111 | stoFree(context->parDecls); |
| 112 | stoFree(context->parLocs); |
| 113 | stoFree(context->nUses); |
| 114 | stoFree(context); |
| 115 | } |
| 116 | |
| 117 | FoamTag |
| 118 | rtcFoamExprType(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 | |
| 124 | Foam |
| 125 | rtcCurrentDecl(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 | |
| 136 | Foam |
| 137 | rtcOriginalDecl(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 | |
| 158 | Bool |
| 159 | rtcHasNewDecl(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 | |
| 168 | Foam |
| 169 | rtcNewDecl(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 | |
| 193 | void |
| 194 | rtcSetUnchanged(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 | |
| 215 | void |
| 216 | rtcAddUse(RetContext context, Foam foam) |
| 217 | { |
| 218 | if (foamTag(foam)((foam)->hdr.tag) == FOAM_Par) { |
| 219 | context->nUses[foam->foamPar.index]++; |
| 220 | } |
| 221 | } |
| 222 | |
| 223 | void |
| 224 | rtcSetType(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 | |
| 245 | localstatic void |
| 246 | retAddUse(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 | |
| 275 | localstatic Bool |
| 276 | retIsCompatible(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 | */ |
| 308 | localstatic Bool |
| 309 | retCanConvert(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 | |
| 330 | void |
| 331 | retypeUnit(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 | |
| 359 | localstatic void |
| 360 | retRetypeProg(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 | |
| 379 | localstatic void |
| 380 | retMarkCasts(RetContext context, Foam prog) |
| 381 | { |
| 382 | retMarkExpr(context, prog->foamProg.body); |
| 383 | } |
| 384 | |
| 385 | localstatic Foam |
| 386 | retLocal(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 | |
| 404 | localstatic Bool |
| 405 | retIsLocal(Foam foam) |
| 406 | { |
| 407 | return retLocal(foam) != NULL((void*)0); |
| 408 | } |
| 409 | |
| 410 | |
| 411 | localstatic void |
| 412 | retMarkExpr(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 | |
| 439 | localstatic void |
| 440 | retMarkPCall(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 | |
| 452 | localstatic void |
| 453 | retMarkPCallJava(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 | |
| 479 | Bool |
| 480 | rtcRearrangeProg(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 | |
| 592 | localstatic void |
| 593 | rtcRearrangeMultiAssign(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 | |
| 632 | localstatic FoamList |
| 633 | rtcMultiAssignVars(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 | |
| 650 | localstatic Foam |
| 651 | rtcMultiAssignValues(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 | |
| 666 | localstatic FoamList |
| 667 | rtcMultiAssignFollows(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 | |
| 684 | localstatic Foam |
| 685 | retRearrangeExpr(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 | |
| 724 | localstatic Bool |
| 725 | retIsVar(Foam foam) |
| 726 | { |
| 727 | return foamTag(foam)((foam)->hdr.tag) == FOAM_Loc || foamTag(foam)((foam)->hdr.tag) == FOAM_Par; |
| 728 | } |
| 729 | |
| 730 | localstatic Foam |
| 731 | retRearrangeSet(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 | |
| 753 | localstatic Foam |
| 754 | retRearrangeVar(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 | |
| 773 | localstatic Foam |
| 774 | retCast(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 | |
| 790 | localstatic Foam |
| 791 | retPeepCasts(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 | } |