00001 # define DEBUG
00002
00003 # define TRACE
00004 # undef TRACE
00005 # include <stdio.h>
00006 # include "../pass5d/op_codes.h"
00007 # include "../parm.h"
00008 # include "RIC.h"
00009
00010 # define HASHT_SIZE 32
00011
00012 # define mod_sz(n) ((n) & 0x1f)
00013
00014 typedef struct RIC_instr * RICp;
00015
00016 # define NO_REG -2
00017
00018 char label_buf[MAXLABELSZ+1];
00019
00020 struct RIC_instr * cbb = RIC_nil;
00021
00022 struct RIC_instr * cbb_last = RIC_nil;
00023
00024
00025
00026
00027 void add_after(p, q)
00028 RICp p, q;
00029 {
00030 if (q == RIC_nil) {
00031 p -> next_instr = cbb;
00032
00033 cbb = p;
00034 } else {
00035 p -> next_instr = q -> next_instr;
00036 p -> prev_instr = q;
00037 q -> next_instr = p;
00038 }
00039 if (p -> next_instr == RIC_nil) {
00040 cbb_last = p;
00041 } else {
00042 p -> next_instr -> prev_instr = p;
00043 }
00044 }
00045
00046
00047
00048 void delete(p)
00049 register RICp p;
00050 {
00051 register RICp prev = p -> prev_instr;
00052 long hint_arg;
00053
00054
00055 while (prev != RIC_nil
00056 && (prev -> op_code == LBR
00057 || prev -> op_code == LBA
00058 || prev -> op_code == HINT
00059 && ((hint_arg = prev -> arg[0]) == NP
00060 || hint_arg == AL
00061 || hint_arg == NSC
00062 || hint_arg == STSZ
00063 || hint_arg == PT))) {
00064 delete(prev);
00065 prev = p -> prev_instr;
00066 }
00067 if (prev == RIC_nil) {
00068 cbb = p -> next_instr;
00069 } else {
00070 p -> prev_instr -> next_instr = p -> next_instr;
00071 }
00072 if (p -> next_instr == RIC_nil) {
00073 cbb_last = p -> prev_instr;
00074 } else {
00075 p -> next_instr -> prev_instr = p -> prev_instr;
00076 }
00077
00078 }
00079
00080
00081 void clear_block()
00082 {
00083 register RICp last, next;
00084
00085 last = cbb;
00086 while (last != RIC_nil) {
00087 next = last -> next_instr;
00088 GC_free(last);
00089 last = next;
00090 }
00091 cbb = RIC_nil;
00092 cbb_last = RIC_nil;
00093 }
00094
00095
00096 void write_block()
00097 {
00098 register RICp p;
00099 register int opc;
00100 register char * s;
00101
00102 p = cbb;
00103 while (p != RIC_nil) {
00104 opc = p -> op_code;
00105 putw(opc, stdout);
00106 if (p -> label_arg) {
00107 for (s = p -> label; *s != '\0'; s++) {
00108 putchar(*s);
00109 }
00110 putchar('\0');
00111 } else {
00112 putw(p -> arg[0], stdout);
00113 putw(p -> arg[1], stdout);
00114 putw(p -> arg[2], stdout);
00115 }
00116 p = p -> next_instr;
00117 }
00118 }
00119
00120
00121 RICp make_instr(opc, arg1, arg2, arg3)
00122 int opc, arg1, arg2, arg3;
00123 {
00124 RICp result = (RICp) GC_malloc(sizeof (struct RIC_instr));
00125
00126 result -> op_code = opc;
00127 result -> label_arg = FALSE;
00128 result -> arg[0] = arg1;
00129 result -> arg[1] = arg2;
00130 result -> arg[2] = arg3;
00131
00132
00133 return(result);
00134 }
00135
00136
00137 RICp make_lbl_instr(opc, lbl)
00138 int opc;
00139 char * lbl;
00140 {
00141 int len = strlen(lbl);
00142 RICp result = (RICp) GC_malloc(sizeof (struct RIC_instr) + len);
00143
00144 result -> op_code = opc;
00145 result -> label_arg = TRUE;
00146 strcpy(result -> label, lbl);
00147
00148 return(result);
00149 }
00150
00151
00152
00153 RICp read_instr()
00154 {
00155 int opc;
00156 int i;
00157 int arg;
00158
00159 opc = getw(stdin);
00160 if (feof(stdin)) {
00161 return(RIC_nil);
00162 }
00163 if (opc >= N_OP_CODES) {
00164 fprintf(stderr, "RICfilter: bad op code\n");
00165 exit(1);
00166 }
00167 if (opc <= MAX_LABEL_OP) {
00168 char *p = label_buf;
00169 int c;
00170 int i = 0;
00171
00172 while ((c = getchar()) != '\0' && c != EOF) {
00173 *p++ = c;
00174 if (++i >= MAXLABELSZ) {
00175 fprintf(stderr, "Label too long\n");
00176 p = label_buf;
00177 }
00178 }
00179 *p = '\0';
00180 return(make_lbl_instr(opc, label_buf));
00181 } else {
00182 int arg1, arg2, arg3;
00183
00184 arg1 = getw(stdin);
00185 arg2 = getw(stdin);
00186 arg3 = getw(stdin);
00187 if (opc == HINT && arg1 == OPT) {
00188 int cnt = arg2;
00189
00190
00191 for (; cnt > 0; cnt --) {
00192 GC_free(read_instr());
00193 }
00194 return(read_instr());
00195 } else {
00196 return(make_instr(opc, arg1, arg2, arg3));
00197 }
00198 }
00199 }
00200
00201
00202 # define is_real_reg(r) ((r) >= FIRST_AVAIL_LOC || (r) == TL \
00203 || (r) == RL || (r) == T2)
00204
00205
00206
00207
00208 void set_regs(p)
00209 RICp p;
00210 {
00211 register int result = NO_REG;
00212 register int op1 = NONE;
00213 register int op2 = NONE;
00214 int op1r, op2r;
00215 register boolean has_se = FALSE;
00216
00217 switch(p -> op_code) {
00218 case BR:
00219 case BRT:
00220 case BRF:
00221 case LBL:
00222 case EXT:
00223 case LBA:
00224 case BFN:
00225 case TFB:
00226 case TFE:
00227 case PRO:
00228 case ADT:
00229 case ERR:
00230 case BSF:
00231 case DCL:
00232 case UDC:
00233 case RTN:
00234 case IDT:
00235 case DDT:
00236 case FDT:
00237 case LBR:
00238 has_se = TRUE;
00239 break;
00240 case STI:
00241 op1 = 0;
00242 op2 = 2;
00243 has_se = TRUE;
00244 break;
00245 case TAR:
00246 op1 = 0;
00247 op2 = 1;
00248 has_se = TRUE;
00249 break;
00250 case HINT:
00251 switch(p -> arg[0]) {
00252 case DEA:
00253 case STSZ:
00254 case DEAD:
00255 case LIVE:
00256 op1 = 1;
00257 break;
00258 }
00259 has_se = TRUE;
00260 break;
00261 case ARG:
00262 op1 = 1;
00263 has_se = TRUE;
00264 break;
00265 case ALS:
00266 case PSH:
00267 op1 = 0;
00268 has_se = TRUE;
00269 break;
00270 case CLL:
00271 case CLC:
00272 has_se = TRUE;
00273 result = RL;
00274 break;
00275 case CLI:
00276 has_se = TRUE;
00277 op1 = 0;
00278 result = RL;
00279 break;
00280 case LDL:
00281 case TRU:
00282 case FLS:
00283 case LDS:
00284 result = p -> arg[0];
00285 break;
00286 case ALH:
00287 case ALA:
00288 has_se = TRUE;
00289 op1 = 0;
00290 case GAR:
00291 case LDN:
00292 result = p -> arg[1];
00293 break;
00294 case MOV:
00295 case NGI:
00296 case ABI:
00297 case NOT:
00298 case NGF:
00299 case EXF:
00300 op1 = 0;
00301 result = p -> arg[1];
00302 break;
00303 case LDI:
00304 case LDC:
00305 op1 = 0;
00306 result = p -> arg[2];
00307 break;
00308 case ADI:
00309 case SBI:
00310 case MLI:
00311 case DVI:
00312 case EQI:
00313 case LTI:
00314 case GTI:
00315 case NEI:
00316 case LEI:
00317 case GEI:
00318 case SHI:
00319 case AND:
00320 case OR:
00321 case ADP:
00322 case ADF:
00323 case SBF:
00324 case MLF:
00325 case DVF:
00326 case EQF:
00327 case LTF:
00328 case GTF:
00329 case NEF:
00330 case LEF:
00331 case GEF:
00332 case SHF:
00333 op1 = 0;
00334 op2 = 1;
00335 result = p -> arg[2];
00336 break;
00337 default:
00338 fprintf(stderr, "RICfilter: strange opcode: %d\n", p -> op_code);
00339 abort();
00340 break;
00341 }
00342 # ifdef DEBUG
00343 if (result == NO_REG && !has_se) {
00344 fprintf(stderr, "RICfilter: vacuous instruction: %d\n",
00345 p -> op_code);
00346 abort();
00347 }
00348 # endif
00349 if (result == SK) {
00350 result = NO_REG;
00351 } else if (result < FIRST_AVAIL_LOC && result != RL &&
00352 result != TL && result != T2) {
00353 result = NO_REG;
00354 has_se = TRUE;
00355 }
00356 op1r = p -> arg[op1];
00357 if (!is_real_reg(op1r)) {
00358 op1 = NONE;
00359 }
00360 op2r = p -> arg[op2];
00361 if (!is_real_reg(op2r)) {
00362 op2 = NONE;
00363 }
00364 p -> op1_reg = op1;
00365 p -> op2_reg = op2;
00366 p -> result_reg = result;
00367 p -> side_effect = has_se;
00368 }
00369
00370
00371
00372 struct reg_descr {
00373 struct reg_descr * next_reg;
00374 struct reg_descr * next_mapped_reg;
00375 int this_reg;
00376 int status;
00377 # define S_LIVE 0
00378 # define S_DEAD 1
00379 # define S_UDC 2
00380 int equiv_reg;
00381
00382
00383
00384
00385 struct reg_descr * mapped_regs;
00386
00387
00388 long const_val;
00389 # define NOT_CONSTANT 0x40000000
00390 };
00391
00392 typedef struct reg_descr * regp;
00393
00394 # define reg_nil ((regp) 0)
00395
00396 regp hasht[HASHT_SIZE];
00397
00398 regp lookup();
00399
00400
00401 void clear_equiv(r)
00402 regp r;
00403 {
00404 regp p, q, s;
00405 regp * t_ptr;
00406 int equiv;
00407 # ifdef DEBUG
00408 boolean foundit = FALSE;
00409 # endif
00410
00411 # ifdef TRACE
00412 fprintf(stderr, "Clear_equiv: %d\n", r -> this_reg);
00413 # endif
00414
00415 for (p = r -> mapped_regs; p != reg_nil; p = q) {
00416 # ifdef TRACE
00417 fprintf(stderr, "\tClearing mapping from %d\n", p -> this_reg);
00418 # endif
00419 q = p -> next_mapped_reg;
00420 # ifdef DEBUG
00421 if (p -> equiv_reg != r -> this_reg) {
00422 fprintf(stderr,
00423 "RICfilter: Register equivalence table messed up\n");
00424 abort(r,p);
00425 }
00426 # endif
00427 p -> equiv_reg = NO_REG;
00428 p -> next_mapped_reg = reg_nil;
00429 }
00430
00431 if ((equiv = r -> equiv_reg) != NO_REG && is_real_reg(equiv)) {
00432 s = lookup(equiv);
00433
00434 for (t_ptr = &(s -> mapped_regs); *t_ptr != reg_nil;
00435 t_ptr = &((*t_ptr) -> next_mapped_reg)) {
00436 # ifdef DEBUG
00437 if ((*t_ptr) -> equiv_reg != r -> equiv_reg) {
00438 fprintf(stderr, "RICfilter: bad reg on list\n");
00439 abort(*t_ptr, r);
00440 }
00441 # endif
00442
00443 if (*t_ptr == r) {
00444 *t_ptr = r -> next_mapped_reg;
00445 r -> next_mapped_reg = reg_nil;
00446 # ifdef DEBUG
00447 foundit = TRUE;
00448 # endif
00449 break;
00450 }
00451 }
00452 # ifdef DEBUG
00453 if (!foundit) {
00454 fprintf(stderr,
00455 "RICfilter: mapped register not on list\n");
00456 abort(r,s);
00457 }
00458 # endif
00459 }
00460 r -> equiv_reg = NO_REG;
00461 r -> mapped_regs = reg_nil;
00462 r -> const_val = NOT_CONSTANT;
00463 }
00464
00465
00466
00467 regp lookup(reg_no)
00468 int reg_no;
00469 {
00470 regp * he = &(hasht[mod_sz(reg_no)]);
00471 regp p;
00472
00473 for (p = *he; p != reg_nil; p = p -> next_reg) {
00474 if (p -> this_reg == reg_no) {
00475 return(p);
00476 }
00477 }
00478 p = (regp) GC_malloc(sizeof(struct reg_descr));
00479 p -> this_reg = reg_no;
00480 p -> next_reg = *he;
00481
00482
00483
00484 p -> equiv_reg = NO_REG;
00485 p -> const_val = NOT_CONSTANT;
00486 *he = p;
00487 return(p);
00488 }
00489
00490
00491
00492 void clear_hasht()
00493 {
00494 int i;
00495 regp p, q;
00496
00497 for (i = 0; i < HASHT_SIZE; i++) {
00498 for (p = hasht[i]; p != reg_nil;) {
00499 q = p -> next_reg;
00500 if (p -> status == S_UDC) {
00501 # ifdef TRACE
00502 fprintf(stderr, "Flushing UDC for register %d\n", p -> this_reg);
00503 # endif
00504 add_after(make_instr(UDC, p -> this_reg, SK, SK), RIC_nil);
00505 }
00506 GC_free(p);
00507 p = q;
00508 }
00509 hasht[i] = reg_nil;
00510 }
00511 }
00512
00513 long const_arg_table[3];
00514
00515
00516
00517 RICp arg_instrs[3];
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529 void propagate()
00530 {
00531 register RICp p;
00532 register int reg;
00533 register int reg2;
00534 regp q, r;
00535 int i;
00536
00537 for (p = cbb; p != RIC_nil; p = p -> next_instr) {
00538 switch(p -> op_code) {
00539 case MOV:
00540 reg = p -> arg[1];
00541 if (is_real_reg(reg)) {
00542 reg2 = p -> arg[0];
00543
00544 if (is_real_reg(reg2)) {
00545 q = lookup(reg2);
00546 if (q -> equiv_reg != NO_REG) {
00547 reg2 = q -> equiv_reg;
00548 }
00549 }
00550 q = lookup(reg);
00551 if (reg == TL || reg == RL) {
00552 q -> status = S_LIVE;
00553
00554 }
00555 if (reg == reg2) {
00556 # ifdef TRACE
00557 fprintf(stderr, "Deleting redundant MOV\n");
00558 # endif
00559 delete(p);
00560 } else {
00561 if (q -> equiv_reg != NO_REG
00562 && is_real_reg(q -> equiv_reg)
00563 || q -> mapped_regs != reg_nil) {
00564 clear_equiv(q);
00565 }
00566 if (reg2 != SP ) {
00567 q -> equiv_reg = reg2;
00568 }
00569 if (is_real_reg(reg2)) {
00570 r = lookup(reg2);
00571 q -> next_mapped_reg = r -> mapped_regs;
00572 r -> mapped_regs = q;
00573 q -> const_val = r -> const_val;
00574 } else {
00575
00576 switch(reg2) {
00577 case C0:
00578 q -> const_val = 0;
00579 break;
00580 case C1:
00581 q -> const_val = 1;
00582 break;
00583 case C2:
00584 q -> const_val = 2;
00585 break;
00586 case C3:
00587 q -> const_val = 3;
00588 break;
00589 case C4:
00590 q -> const_val = 4;
00591 break;
00592 default:
00593 q -> const_val = NOT_CONSTANT;
00594 break;
00595 }
00596 }
00597 # ifdef TRACE
00598 fprintf(stderr, "%d is a copy of %d\n", reg, reg2);
00599 # endif
00600 }
00601 }
00602 break;
00603
00604 case ARG:
00605 q = reg_nil;
00606 reg = p -> arg[1];
00607 if (is_real_reg(reg)) {
00608 q = lookup(reg);
00609 if (q -> equiv_reg != NO_REG) {
00610
00611 # ifdef TRACE
00612 fprintf(stderr,
00613 "Replacing reference to %d in ARG by one to %d\n",
00614 reg, q -> equiv_reg);
00615 # endif
00616 p -> arg[1] = q -> equiv_reg;
00617 }
00618 }
00619 i = p -> arg[0] - 1;
00620 if (i < 3) {
00621
00622 arg_instrs[i] = p;
00623 if (q != reg_nil ) {
00624 const_arg_table[i] = q -> const_val;
00625 } else {
00626 switch(reg) {
00627 case C0:
00628 const_arg_table[i] = 0;
00629 break;
00630 case C1:
00631 const_arg_table[i] = 1;
00632 break;
00633 case C2:
00634 const_arg_table[i] = 2;
00635 break;
00636 case C3:
00637 const_arg_table[i] = 3;
00638 break;
00639 case C4:
00640 const_arg_table[i] = 4;
00641 break;
00642 default:
00643 const_arg_table[i] = NOT_CONSTANT;
00644 }
00645 }
00646 }
00647 break;
00648
00649 case CLC:
00650 {
00651 # define DP_DOT "_Float_Dot"
00652 # define SP_DOT "_SFloat_Dot"
00653 # define SBFSZ 120
00654 RICp clc_instr = p;
00655 RICp lba_instr = p -> prev_instr;
00656 RICp next_i = p -> next_instr;
00657 RICp prev_i;
00658 RICp const_i;
00659 RICp q;
00660 char * routine_name = lba_instr -> label;
00661 boolean args_constant = TRUE;
00662 boolean is_dp_dot;
00663 boolean is_sp_dot;
00664 char buf[SBFSZ];
00665
00666 if (clc_instr -> arg[0] == 3) {
00667 for (i = 0; i < 3; i++) {
00668 args_constant &= (const_arg_table[i] != NOT_CONSTANT);
00669 }
00670 if (const_arg_table[2] > SBFSZ - 30) {
00671
00672
00673 args_constant = FALSE;
00674 }
00675 if (args_constant) {
00676 is_dp_dot = (strcmp(routine_name, DP_DOT) == 0);
00677 is_sp_dot = (strcmp(routine_name, SP_DOT) == 0);
00678 }
00679 if (args_constant &&
00680 (is_dp_dot || is_sp_dot)) {
00681
00682 for (i = 0; i < 3; i++) {
00683 delete(arg_instrs[i]);
00684 }
00685
00686 delete(clc_instr);
00687
00688 sprintf(buf, "%d.%0*d",
00689 const_arg_table[0],
00690 const_arg_table[2],
00691 const_arg_table[1]);
00692
00693 prev_i = next_i -> prev_instr;
00694 if (is_dp_dot) {
00695 const_i = make_lbl_instr(DDT, buf);
00696 } else {
00697 const_i = make_lbl_instr(FDT, buf);
00698 }
00699 set_regs(const_i);
00700 add_after(const_i, prev_i);
00701 q = make_lbl_instr(LBA, "1");
00702 set_regs(q);
00703 add_after(q, prev_i);
00704
00705 if (is_sp_dot) {
00706 q = make_instr(LDI, RL, 0, RL);
00707 set_regs(q);
00708 add_after(q, const_i);
00709 }
00710 q = make_instr(LDL, RL, SK, SK);
00711 set_regs(q);
00712 add_after(q, const_i);
00713 q = make_lbl_instr(LBA, "1b");
00714 set_regs(q);
00715 add_after(q, const_i);
00716 }
00717 }
00718
00719
00720 r = lookup(RL);
00721 clear_equiv(r);
00722 r -> status = S_LIVE;
00723 }
00724 break;
00725
00726 case UDC:
00727 if (is_real_reg(p -> arg[0])) {
00728 q = lookup(p -> arg[0]);
00729 q -> status = S_UDC;
00730 }
00731 break;
00732
00733 case DCL:
00734 q = lookup(p -> arg[0]);
00735 if (q -> status == S_UDC) {
00736
00737 p -> second_decl = TRUE;
00738 }
00739 q -> status = S_LIVE;
00740 break;
00741
00742 case LDN:
00743 reg = p -> arg[1];
00744 if (reg == SK) {
00745 delete(p);
00746 break;
00747 }
00748 # ifdef DEBUG
00749 if (!is_real_reg(reg)) {
00750 fprintf(stderr, "RICfilter: bad LDN arg\n");
00751 abort();
00752 }
00753 # endif
00754 q = lookup(reg);
00755 if (reg == TL || reg == RL) {
00756 q -> status = S_LIVE;
00757
00758 }
00759 if (q -> mapped_regs != reg_nil) {
00760 clear_equiv(q);
00761 }
00762 q -> const_val = p -> arg[0];
00763 switch(p -> arg[0]) {
00764 case 0:
00765 q -> equiv_reg = C0;
00766 break;
00767 case 1:
00768 q -> equiv_reg = C1;
00769 break;
00770 case 2:
00771 q -> equiv_reg = C2;
00772 break;
00773 case 3:
00774 q -> equiv_reg = C3;
00775 break;
00776 case 4:
00777 q -> equiv_reg = C4;
00778 break;
00779 default:
00780 q -> equiv_reg = NO_REG;
00781 break;
00782 }
00783 break;
00784
00785 case ALA:
00786 case ALH:
00787
00788 q = lookup(RL);
00789 clear_equiv(q);
00790
00791
00792 default:
00793 reg = p -> result_reg;
00794 if (reg != NO_REG) {
00795 q = lookup(reg);
00796 if (q -> equiv_reg != NO_REG || q -> mapped_regs != reg_nil) {
00797 clear_equiv(q);
00798 }
00799 if (reg == TL || reg == RL) {
00800 q -> status = S_LIVE;
00801
00802 }
00803 }
00804 if (p -> op1_reg != NONE) {
00805 reg = p -> arg[p -> op1_reg];
00806 q = lookup(reg);
00807 if (q -> equiv_reg != NO_REG) {
00808
00809 # ifdef TRACE
00810 fprintf(stderr,
00811 "Replacing reference to %d by one to %d\n",
00812 p -> arg[p -> op1_reg], q -> equiv_reg);
00813 # endif
00814 p -> arg[p -> op1_reg] = q -> equiv_reg;
00815 }
00816 }
00817 if (p -> op2_reg != NONE) {
00818 reg = p -> arg[p -> op2_reg];
00819 q = lookup(reg);
00820 if (q -> equiv_reg != NO_REG) {
00821
00822 # ifdef TRACE
00823 fprintf(stderr,
00824 "Replacing reference to %d by one to %d\n",
00825 p -> arg[p -> op2_reg], q -> equiv_reg);
00826 # endif
00827 p -> arg[p -> op2_reg] = q -> equiv_reg;
00828 }
00829 }
00830 }
00831 }
00832 }
00833
00834
00835
00836 void eliminate()
00837 {
00838 RICp p;
00839 regp q;
00840 boolean deleted;
00841
00842 for (p = cbb_last; p != RIC_nil; p = p -> prev_instr) {
00843 # ifdef DEBUG
00844 if (p -> result_reg == 0) {
00845 fprintf(stderr, "RICfilter: Missing result info\n");
00846 }
00847 # endif
00848 switch (p -> op_code) {
00849 case UDC:
00850
00851
00852 delete(p);
00853 break;
00854 case DCL:
00855 q = lookup(p -> arg[0]);
00856 if (q -> status == S_UDC) {
00857
00858 # ifdef TRACE
00859 fprintf(stderr, "Deleting DCL %d\n", p -> arg[0]);
00860 # endif
00861 delete(p);
00862 }
00863 if (p -> second_decl) {
00864 q -> status = S_UDC;
00865
00866 } else {
00867 q -> status = S_DEAD;
00868 }
00869 break;
00870 default:
00871 deleted = FALSE;
00872 if (!(p -> side_effect)) {
00873 if (p -> result_reg == NO_REG) {
00874 # ifdef TRACE
00875 fprintf(stderr,
00876 "deleting result-less instruction, opcode = %d\n",
00877 p -> op_code);
00878 # endif
00879 delete(p);
00880 deleted = TRUE;
00881 } else {
00882 q = lookup(p -> result_reg);
00883 if (q -> status == S_UDC
00884 || q -> status == S_DEAD) {
00885 # ifdef TRACE
00886 fprintf(stderr,
00887 "deleting dead instruction, opcode = %d, result = %d\n",
00888 p -> op_code, p -> result_reg);
00889 # endif
00890 delete(p);
00891 deleted = TRUE;
00892 }
00893 }
00894 }
00895 if (!deleted) {
00896 int opr1, opr2;
00897
00898
00899
00900 if (p -> result_reg != NO_REG) {
00901 q = lookup(p -> result_reg);
00902 if (q -> status == S_UDC) {
00903 add_after(make_instr(UDC, p -> result_reg,
00904 SK, SK), p);
00905 } else if (q -> status == S_DEAD) {
00906 add_after(make_instr(HINT, DEAD,
00907 p -> result_reg,
00908 SK), p);
00909 }
00910 q -> status = S_DEAD;
00911 }
00912
00913 if (p -> op1_reg != NONE) {
00914 opr1 = p -> arg[p -> op1_reg];
00915 q = lookup(opr1);
00916 if (q -> status == S_UDC) {
00917 add_after(make_instr(UDC, opr1, SK, SK), p);
00918 } else if (q -> status == S_DEAD
00919 && opr1 != p -> result_reg) {
00920 add_after(make_instr(HINT, DEAD, opr1, SK), p);
00921 }
00922 # ifdef TRACE
00923 fprintf(stderr,
00924 "Changing status of %d to S_LIVE\n",
00925 opr1);
00926 # endif
00927 q -> status = S_LIVE;
00928 }
00929 if (p -> op2_reg != NONE) {
00930 opr2 = p -> arg[p -> op2_reg];
00931 q = lookup(opr2);
00932 if (q -> status == S_UDC) {
00933 add_after(make_instr(UDC, opr2, SK, SK), p);
00934 } else if (q -> status == S_DEAD
00935 && opr2 != p -> result_reg) {
00936 add_after(make_instr(HINT, DEAD, opr2, SK), p);
00937 }
00938 # ifdef TRACE
00939 fprintf(stderr,
00940 "Changing status of %d to S_LIVE\n",
00941 opr2);
00942 # endif
00943 q -> status = S_LIVE;
00944 }
00945 }
00946 }
00947 }
00948 }
00949
00950
00951 void optimize_block()
00952 {
00953
00954 propagate();
00955
00956 eliminate();
00957
00958 clear_hasht();
00959 }
00960
00961 main(argc, argv)
00962 int argc;
00963 char ** argv;
00964 {
00965 RICp ci;
00966 RICp pi;
00967 int opc;
00968
00969 GC_init();
00970 if (argc != 1) {
00971 fprintf(stderr, "%s takes no arguments\n", argv[0]);
00972 exit(1);
00973 }
00974 pi = RIC_nil;
00975 while ((ci = read_instr()) != RIC_nil) {
00976 set_regs(ci);
00977 add_after(ci,pi);
00978 pi = ci;
00979 opc = ci -> op_code;
00980 if (opc == BSF || opc == BFN || opc == BRT || opc == BRF
00981 || opc == BR || opc == LBL) {
00982
00983 optimize_block();
00984 write_block();
00985 clear_block();
00986 pi = RIC_nil;
00987 }
00988 }
00989 optimize_block();
00990 write_block();
00991 clear_block();
00992 exit(0);
00993 }