00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #include "config.h"
00063 #include "system.h"
00064
00065 #include "rtl.h"
00066 #include "hard-reg-set.h"
00067 #include "basic-block.h"
00068 #include "ssa.h"
00069 #include "insn-config.h"
00070 #include "recog.h"
00071 #include "output.h"
00072 #include "errors.h"
00073 #include "ggc.h"
00074 #include "df.h"
00075 #include "function.h"
00076
00077
00078
00079 typedef enum
00080 {
00081 UNDEFINED,
00082 CONSTANT,
00083 VARYING
00084 } latticevalue;
00085
00086
00087
00088
00089
00090 typedef struct
00091 {
00092 latticevalue lattice_val;
00093 rtx const_value;
00094 } value;
00095
00096
00097 static value *values;
00098
00099
00100 static sbitmap executable_blocks;
00101
00102
00103 static sbitmap executable_edges;
00104
00105
00106 static edge *edge_info;
00107
00108
00109 static struct edge_list *edges;
00110
00111
00112 static struct df *df_analyzer;
00113
00114
00115 static edge flow_edges;
00116
00117
00118
00119 static sbitmap ssa_edges;
00120
00121
00122 #define SSA_NAME(x) REGNO (SET_DEST (x))
00123 #define EIE(x,y) EDGE_INDEX (edges, x, y)
00124
00125 static void visit_phi_node PARAMS ((rtx, basic_block));
00126 static void visit_expression PARAMS ((rtx, basic_block));
00127 static void defs_to_undefined PARAMS ((rtx));
00128 static void defs_to_varying PARAMS ((rtx));
00129 static void examine_flow_edges PARAMS ((void));
00130 static int mark_references PARAMS ((rtx *, void *));
00131 static void follow_def_use_chains PARAMS ((void));
00132 static void optimize_unexecutable_edges PARAMS ((struct edge_list *, sbitmap));
00133 static void ssa_ccp_substitute_constants PARAMS ((void));
00134 static void ssa_ccp_df_delete_unreachable_insns PARAMS ((void));
00135 static void ssa_fast_dce PARAMS ((struct df *));
00136
00137
00138
00139 static void
00140 visit_phi_node (phi_node, block)
00141 rtx phi_node;
00142 basic_block block;
00143 {
00144 unsigned int i;
00145 rtx phi_node_expr = NULL;
00146 unsigned int phi_node_name = SSA_NAME (PATTERN (phi_node));
00147 latticevalue phi_node_lattice_val = UNDEFINED;
00148 rtx pat = PATTERN (phi_node);
00149 rtvec phi_vec = XVEC (SET_SRC (pat), 0);
00150 unsigned int num_elem = GET_NUM_ELEM (phi_vec);
00151
00152 for (i = 0; i < num_elem; i += 2)
00153 {
00154 if (TEST_BIT (executable_edges,
00155 EIE (BASIC_BLOCK (INTVAL (RTVEC_ELT (phi_vec, i + 1))),
00156 block)))
00157 {
00158 unsigned int current_parm
00159 = REGNO (RTVEC_ELT (phi_vec, i));
00160
00161 latticevalue current_parm_lattice_val
00162 = values[current_parm].lattice_val;
00163
00164
00165
00166 if (current_parm_lattice_val == VARYING)
00167 {
00168 phi_node_lattice_val = VARYING;
00169 phi_node_expr = NULL;
00170 break;
00171 }
00172
00173
00174
00175 if (current_parm_lattice_val == CONSTANT
00176 && phi_node_lattice_val == CONSTANT
00177 && values[current_parm].const_value != phi_node_expr)
00178 {
00179 phi_node_lattice_val = VARYING;
00180 phi_node_expr = NULL;
00181 break;
00182 }
00183
00184
00185
00186
00187
00188 if (phi_node_lattice_val == UNDEFINED
00189 && phi_node_expr == NULL
00190 && current_parm_lattice_val == CONSTANT)
00191 {
00192 phi_node_expr = values[current_parm].const_value;
00193 phi_node_lattice_val = CONSTANT;
00194 continue;
00195 }
00196 }
00197 }
00198
00199
00200
00201 if (phi_node_lattice_val != values[phi_node_name].lattice_val)
00202 {
00203 values[phi_node_name].lattice_val = phi_node_lattice_val;
00204 values[phi_node_name].const_value = phi_node_expr;
00205 SET_BIT (ssa_edges, phi_node_name);
00206 }
00207 }
00208
00209
00210 static void
00211 defs_to_undefined (insn)
00212 rtx insn;
00213 {
00214 struct df_link *currdef;
00215 for (currdef = DF_INSN_DEFS (df_analyzer, insn); currdef;
00216 currdef = currdef->next)
00217 {
00218 if (values[DF_REF_REGNO (currdef->ref)].lattice_val != UNDEFINED)
00219 SET_BIT (ssa_edges, DF_REF_REGNO (currdef->ref));
00220 values[DF_REF_REGNO (currdef->ref)].lattice_val = UNDEFINED;
00221 }
00222 }
00223
00224
00225 static void
00226 defs_to_varying (insn)
00227 rtx insn;
00228 {
00229 struct df_link *currdef;
00230 for (currdef = DF_INSN_DEFS (df_analyzer, insn); currdef;
00231 currdef = currdef->next)
00232 {
00233 if (values[DF_REF_REGNO (currdef->ref)].lattice_val != VARYING)
00234 SET_BIT (ssa_edges, DF_REF_REGNO (currdef->ref));
00235 values[DF_REF_REGNO (currdef->ref)].lattice_val = VARYING;
00236 }
00237 }
00238
00239
00240
00241 static void
00242 visit_expression (insn, block)
00243 rtx insn;
00244 basic_block block;
00245 {
00246 rtx src, dest, set;
00247
00248
00249
00250
00251
00252
00253
00254 if (GET_CODE (insn) == CALL_INSN && block->end == insn)
00255 {
00256 edge curredge;
00257
00258 for (curredge = block->succ; curredge;
00259 curredge = curredge->succ_next)
00260 {
00261 int index = EIE (curredge->src, curredge->dest);
00262
00263 if (TEST_BIT (executable_edges, index))
00264 continue;
00265
00266 SET_BIT (executable_edges, index);
00267 edge_info[index] = flow_edges;
00268 flow_edges = curredge;
00269 }
00270 }
00271
00272 set = single_set (insn);
00273 if (! set)
00274 {
00275 defs_to_varying (insn);
00276 return;
00277 }
00278
00279 src = SET_SRC (set);
00280 dest = SET_DEST (set);
00281
00282
00283 if (GET_CODE (dest) != REG && dest != pc_rtx)
00284 {
00285 defs_to_varying (insn);
00286 return;
00287 }
00288
00289
00290
00291
00292 if (GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER)
00293 {
00294 defs_to_varying (insn);
00295 return;
00296 }
00297
00298
00299 if (GET_CODE (src) == CONST_INT && GET_CODE (insn) == INSN)
00300 {
00301 unsigned int resultreg = REGNO (dest);
00302
00303 values[resultreg].lattice_val = CONSTANT;
00304 values[resultreg].const_value = SET_SRC (PATTERN (insn));
00305 SET_BIT (ssa_edges, resultreg);
00306 }
00307
00308
00309 else if (GET_CODE (src) == REG && GET_CODE (dest) == REG)
00310 {
00311 unsigned int old_value = REGNO (src);
00312 latticevalue old_lattice_value = values[old_value].lattice_val;
00313 unsigned int new_value = REGNO (dest);
00314
00315
00316
00317 if (values[new_value].lattice_val != old_lattice_value
00318 || values[new_value].const_value != values[old_value].const_value)
00319 SET_BIT (ssa_edges, new_value);
00320
00321
00322 values[new_value].lattice_val = old_lattice_value;
00323 values[new_value].const_value = values[old_value].const_value;
00324 }
00325
00326
00327 else if (GET_CODE (insn) == JUMP_INSN)
00328 {
00329 rtx x = pc_set (insn);
00330 if (GET_CODE (src) != IF_THEN_ELSE)
00331 {
00332 edge curredge;
00333
00334
00335
00336
00337
00338
00339
00340
00341 for (curredge = block->succ; curredge;
00342 curredge = curredge->succ_next)
00343 {
00344 int index = EIE (curredge->src, curredge->dest);
00345
00346 if (TEST_BIT (executable_edges, index))
00347 continue;
00348
00349 SET_BIT (executable_edges, index);
00350 edge_info[index] = flow_edges;
00351 flow_edges = curredge;
00352 }
00353 }
00354 else
00355 {
00356 edge curredge;
00357 enum rtx_code comparison_code;
00358 rtx comparison_src0;
00359 rtx comparison_src1;
00360
00361 comparison_code = GET_CODE (XEXP (src, 0));
00362 comparison_src0 = XEXP (XEXP (src, 0), 0);
00363 comparison_src1 = XEXP (XEXP (src, 0), 1);
00364
00365
00366
00367
00368 if ((GET_CODE (comparison_src0) == REG
00369 && values[REGNO (comparison_src0)].lattice_val == UNDEFINED)
00370 || (GET_CODE (comparison_src1) == REG
00371 && values[REGNO (comparison_src1)].lattice_val == UNDEFINED))
00372 return;
00373
00374
00375
00376 if ((GET_CODE (comparison_src0) == REG
00377 && values[REGNO (comparison_src0)].lattice_val == VARYING)
00378 || (GET_CODE (comparison_src1) == REG
00379 && values[REGNO (comparison_src1)].lattice_val == VARYING))
00380 {
00381 for (curredge = block->succ; curredge;
00382 curredge = curredge->succ_next)
00383 {
00384 int index = EIE (curredge->src, curredge->dest);
00385
00386 if (TEST_BIT (executable_edges, index))
00387 continue;
00388
00389 SET_BIT (executable_edges, index);
00390 edge_info[index] = flow_edges;
00391 flow_edges = curredge;
00392 }
00393 return;
00394 }
00395
00396
00397 if (GET_CODE (comparison_src0) == REG
00398 && values[REGNO (comparison_src0)].lattice_val == CONSTANT)
00399 comparison_src0 = values[REGNO (comparison_src0)].const_value;
00400
00401 if (GET_CODE (comparison_src1) == REG
00402 && values[REGNO (comparison_src1)].lattice_val == CONSTANT)
00403 comparison_src1 = values[REGNO (comparison_src1)].const_value;
00404
00405 x = simplify_ternary_operation (IF_THEN_ELSE,
00406 VOIDmode,
00407 GET_MODE (XEXP (src, 0)),
00408 gen_rtx (comparison_code,
00409 GET_MODE (XEXP (src, 0)),
00410 comparison_src0,
00411 comparison_src1),
00412 XEXP (src, 1),
00413 XEXP (src, 2));
00414
00415
00416
00417 for (curredge = block->succ; curredge;
00418 curredge = curredge->succ_next)
00419 {
00420 int index = EIE (curredge->src, curredge->dest);
00421
00422 if (TEST_BIT (executable_edges, index))
00423 continue;
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 if (!x
00436 || (x == pc_rtx
00437 && (curredge->flags & EDGE_FALLTHRU))
00438 || (GET_CODE (x) == LABEL_REF
00439 && ! (curredge->flags & EDGE_FALLTHRU)))
00440 {
00441 SET_BIT (executable_edges, index);
00442 edge_info[index] = flow_edges;
00443 flow_edges = curredge;
00444 }
00445 }
00446 }
00447 }
00448 else if (!PHI_NODE_P (insn))
00449 {
00450 rtx simplified = NULL;
00451
00452
00453
00454
00455
00456
00457
00458
00459 switch (GET_RTX_CLASS (GET_CODE (src)))
00460 {
00461 case '<':
00462 {
00463 rtx src0 = XEXP (src, 0);
00464 rtx src1 = XEXP (src, 1);
00465 enum machine_mode mode;
00466
00467
00468 if ((GET_CODE (src0) == REG
00469 && values[REGNO (src0)].lattice_val == UNDEFINED)
00470 || (GET_CODE (src1) == REG
00471 && values[REGNO (src1)].lattice_val == UNDEFINED))
00472 {
00473 defs_to_undefined (insn);
00474 break;
00475 }
00476
00477
00478
00479 mode = GET_MODE (src0);
00480 if (mode == VOIDmode)
00481 mode = GET_MODE (src1);
00482
00483
00484
00485 if (GET_CODE (src0) == REG
00486 && values[REGNO (src0)].lattice_val == CONSTANT)
00487 src0 = values[REGNO (src0)].const_value;
00488
00489 if (GET_CODE (src1) == REG
00490 && values[REGNO (src1)].lattice_val == CONSTANT)
00491 src1 = values[REGNO (src1)].const_value;
00492
00493
00494
00495 simplified = simplify_relational_operation (GET_CODE (src),
00496 mode, src0, src1);
00497 break;
00498
00499 }
00500
00501 case '1':
00502 {
00503 rtx src0 = XEXP (src, 0);
00504 enum machine_mode mode0 = GET_MODE (src0);
00505
00506
00507 if (GET_CODE (src0) == REG
00508 && values[REGNO (src0)].lattice_val == UNDEFINED)
00509 {
00510 defs_to_undefined (insn);
00511 break;
00512 }
00513
00514
00515
00516 if (GET_CODE (src0) == REG
00517 && values[REGNO (src0)].lattice_val == CONSTANT)
00518 src0 = values[REGNO (src0)].const_value;
00519
00520
00521
00522 simplified = simplify_unary_operation (GET_CODE (src),
00523 GET_MODE (src),
00524 src0,
00525 mode0);
00526 break;
00527 }
00528
00529 case '2':
00530 case 'c':
00531 {
00532 rtx src0 = XEXP (src, 0);
00533 rtx src1 = XEXP (src, 1);
00534
00535
00536 if ((GET_CODE (src0) == REG
00537 && values[REGNO (src0)].lattice_val == UNDEFINED)
00538 || (GET_CODE (src1) == REG
00539 && values[REGNO (src1)].lattice_val == UNDEFINED))
00540 {
00541 defs_to_undefined (insn);
00542 break;
00543 }
00544
00545
00546
00547 if (GET_CODE (src0) == REG
00548 && values[REGNO (src0)].lattice_val == CONSTANT)
00549 src0 = values[REGNO (src0)].const_value;
00550
00551 if (GET_CODE (src1) == REG
00552 && values[REGNO (src1)].lattice_val == CONSTANT)
00553 src1 = values[REGNO (src1)].const_value;
00554
00555
00556
00557 simplified = simplify_binary_operation (GET_CODE (src),
00558 GET_MODE (src),
00559 src0, src1);
00560 break;
00561 }
00562
00563 case '3':
00564 case 'b':
00565 {
00566 rtx src0 = XEXP (src, 0);
00567 rtx src1 = XEXP (src, 1);
00568 rtx src2 = XEXP (src, 2);
00569
00570
00571 if ((GET_CODE (src0) == REG
00572 && values[REGNO (src0)].lattice_val == UNDEFINED)
00573 || (GET_CODE (src1) == REG
00574 && values[REGNO (src1)].lattice_val == UNDEFINED)
00575 || (GET_CODE (src2) == REG
00576 && values[REGNO (src2)].lattice_val == UNDEFINED))
00577 {
00578 defs_to_undefined (insn);
00579 break;
00580 }
00581
00582
00583
00584 if (GET_CODE (src0) == REG
00585 && values[REGNO (src0)].lattice_val == CONSTANT)
00586 src0 = values[REGNO (src0)].const_value;
00587
00588 if (GET_CODE (src1) == REG
00589 && values[REGNO (src1)].lattice_val == CONSTANT)
00590 src1 = values[REGNO (src1)].const_value;
00591
00592 if (GET_CODE (src2) == REG
00593 && values[REGNO (src2)].lattice_val == CONSTANT)
00594 src2 = values[REGNO (src2)].const_value;
00595
00596
00597
00598 simplified = simplify_ternary_operation (GET_CODE (src),
00599 GET_MODE (src),
00600 GET_MODE (src),
00601 src0, src1, src2);
00602 break;
00603 }
00604
00605 default:
00606 defs_to_varying (insn);
00607 }
00608
00609 if (simplified && GET_CODE (simplified) == CONST_INT)
00610 {
00611 if (values[REGNO (dest)].lattice_val != CONSTANT
00612 || values[REGNO (dest)].const_value != simplified)
00613 SET_BIT (ssa_edges, REGNO (dest));
00614
00615 values[REGNO (dest)].lattice_val = CONSTANT;
00616 values[REGNO (dest)].const_value = simplified;
00617 }
00618 else
00619 defs_to_varying (insn);
00620 }
00621 }
00622
00623
00624
00625 static void
00626 examine_flow_edges ()
00627 {
00628 while (flow_edges != NULL)
00629 {
00630 basic_block succ_block;
00631 rtx curr_phi_node;
00632
00633
00634 succ_block = flow_edges->dest;
00635 flow_edges = edge_info[EIE (flow_edges->src, flow_edges->dest)];
00636
00637
00638 if (succ_block == EXIT_BLOCK_PTR)
00639 continue;
00640
00641
00642
00643 for (curr_phi_node = first_insn_after_basic_block_note (succ_block);
00644 PHI_NODE_P (curr_phi_node);
00645 curr_phi_node = NEXT_INSN (curr_phi_node))
00646 visit_phi_node (curr_phi_node, succ_block);
00647
00648
00649
00650 if (!TEST_BIT (executable_blocks, succ_block->index))
00651 {
00652 rtx currinsn;
00653 edge succ_edge = succ_block->succ;
00654
00655
00656 SET_BIT (executable_blocks, succ_block->index);
00657
00658
00659 currinsn = succ_block->head;
00660 while (currinsn != succ_block->end)
00661 {
00662 if (INSN_P (currinsn))
00663 visit_expression (currinsn, succ_block);
00664
00665 currinsn = NEXT_INSN (currinsn);
00666 }
00667
00668
00669 if (INSN_P (currinsn))
00670 visit_expression (currinsn, succ_block);
00671
00672
00673
00674
00675
00676 if (succ_edge != NULL
00677 && succ_edge->succ_next == NULL
00678 && !TEST_BIT (executable_edges,
00679 EIE (succ_edge->src, succ_edge->dest)))
00680 {
00681 SET_BIT (executable_edges,
00682 EIE (succ_edge->src, succ_edge->dest));
00683 edge_info[EIE (succ_edge->src, succ_edge->dest)] = flow_edges;
00684 flow_edges = succ_edge;
00685 }
00686 }
00687 }
00688 }
00689
00690
00691
00692
00693 static void
00694 follow_def_use_chains ()
00695 {
00696
00697 while (sbitmap_first_set_bit (ssa_edges) >= 0)
00698 {
00699 int member;
00700 struct df_link *curruse;
00701
00702
00703
00704 member = sbitmap_first_set_bit (ssa_edges);
00705 RESET_BIT (ssa_edges, member);
00706
00707
00708 for (curruse = df_analyzer->regs[member].uses; curruse;
00709 curruse = curruse->next)
00710 {
00711 rtx useinsn;
00712
00713 useinsn = DF_REF_INSN (curruse->ref);
00714 if (PHI_NODE_P (useinsn))
00715 {
00716 if (TEST_BIT (executable_blocks, BLOCK_NUM (useinsn)))
00717 visit_phi_node (useinsn, BLOCK_FOR_INSN (useinsn));
00718 }
00719 else
00720 {
00721 if (TEST_BIT (executable_blocks, BLOCK_NUM (useinsn)))
00722 visit_expression (useinsn, BLOCK_FOR_INSN (useinsn));
00723 }
00724 }
00725 }
00726 }
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736 static void
00737 optimize_unexecutable_edges (edges, executable_edges)
00738 struct edge_list *edges;
00739 sbitmap executable_edges;
00740 {
00741 int i;
00742 basic_block bb;
00743
00744 for (i = 0; i < NUM_EDGES (edges); i++)
00745 {
00746 if (!TEST_BIT (executable_edges, i))
00747 {
00748 edge edge = INDEX_EDGE (edges, i);
00749
00750 if (edge->flags & EDGE_ABNORMAL)
00751 continue;
00752
00753
00754
00755 if (edge->dest != EXIT_BLOCK_PTR)
00756 {
00757 rtx insn = first_insn_after_basic_block_note (edge->dest);
00758
00759 while (PHI_NODE_P (insn))
00760 {
00761 remove_phi_alternative (PATTERN (insn), edge->src);
00762 if (rtl_dump_file)
00763 fprintf (rtl_dump_file,
00764 "Removing alternative for bb %d of phi %d\n",
00765 edge->src->index, SSA_NAME (PATTERN (insn)));
00766 insn = NEXT_INSN (insn);
00767 }
00768 }
00769 if (rtl_dump_file)
00770 fprintf (rtl_dump_file,
00771 "Removing unexecutable edge from %d to %d\n",
00772 edge->src->index, edge->dest->index);
00773
00774 remove_edge (edge);
00775 }
00776 }
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800 FOR_EACH_BB (bb)
00801 {
00802 rtx insn = bb->end;
00803 edge edge = bb->succ;
00804
00805
00806
00807 if (bb->pred == NULL || GET_CODE (insn) != JUMP_INSN)
00808 continue;
00809
00810
00811
00812 if (condjump_p (insn) && ! simplejump_p (insn)
00813 && bb->succ && bb->succ->succ_next == NULL)
00814 {
00815
00816
00817
00818 if (edge->flags & EDGE_FALLTHRU)
00819 {
00820 PUT_CODE (insn, NOTE);
00821 NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
00822 }
00823 else
00824 {
00825 SET_SRC (PATTERN (insn)) = gen_rtx_LABEL_REF (Pmode,
00826 JUMP_LABEL (insn));
00827 emit_barrier_after (insn);
00828 INSN_CODE (insn) = -1;
00829 }
00830
00831
00832 df_insn_modify (df_analyzer, BLOCK_FOR_INSN (insn), insn);
00833 }
00834 }
00835 }
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 static void
00850 ssa_ccp_substitute_constants ()
00851 {
00852 unsigned int i;
00853
00854 for (i = FIRST_PSEUDO_REGISTER; i < VARRAY_SIZE (ssa_definition); i++)
00855 {
00856 if (values[i].lattice_val == CONSTANT)
00857 {
00858 rtx def = VARRAY_RTX (ssa_definition, i);
00859 rtx set = single_set (def);
00860 struct df_link *curruse;
00861
00862 if (! set)
00863 continue;
00864
00865
00866
00867
00868
00869
00870
00871
00872 if (! PHI_NODE_P (def)
00873 && ! ((GET_CODE (def) == INSN
00874 && GET_CODE (SET_SRC (set)) == CONST_INT)))
00875 {
00876 if (rtl_dump_file)
00877 fprintf (rtl_dump_file,
00878 "Register %d is now set to a constant\n",
00879 SSA_NAME (PATTERN (def)));
00880 SET_SRC (set) = values[i].const_value;
00881 INSN_CODE (def) = -1;
00882 df_insn_modify (df_analyzer, BLOCK_FOR_INSN (def), def);
00883 }
00884
00885
00886
00887
00888
00889 for (curruse = df_analyzer->regs[i].uses;
00890 curruse;
00891 curruse = curruse->next)
00892 {
00893 rtx useinsn;
00894
00895 useinsn = DF_REF_INSN (curruse->ref);
00896
00897 if (!INSN_DELETED_P (useinsn)
00898 && ! (GET_CODE (useinsn) == NOTE
00899 && NOTE_LINE_NUMBER (useinsn) == NOTE_INSN_DELETED)
00900 && (GET_CODE (useinsn) == INSN
00901 || GET_CODE (useinsn) == JUMP_INSN))
00902 {
00903
00904 if (validate_replace_src (regno_reg_rtx [i],
00905 values[i].const_value,
00906 useinsn))
00907 {
00908 if (rtl_dump_file)
00909 fprintf (rtl_dump_file,
00910 "Register %d in insn %d replaced with constant\n",
00911 i, INSN_UID (useinsn));
00912 INSN_CODE (useinsn) = -1;
00913 df_insn_modify (df_analyzer,
00914 BLOCK_FOR_INSN (useinsn),
00915 useinsn);
00916 }
00917
00918 }
00919 }
00920 }
00921 }
00922 }
00923
00924
00925
00926
00927
00928 static void
00929 ssa_ccp_df_delete_unreachable_insns ()
00930 {
00931 basic_block b;
00932
00933
00934 find_unreachable_blocks ();
00935
00936
00937
00938
00939 FOR_EACH_BB_REVERSE (b)
00940 {
00941 if (!(b->flags & BB_REACHABLE))
00942 {
00943 rtx start = b->head;
00944 rtx end = b->end;
00945 rtx tmp;
00946
00947
00948 end = b->end;
00949 if (GET_CODE (end) == JUMP_INSN
00950 && (tmp = JUMP_LABEL (end)) != NULL_RTX
00951 && (tmp = NEXT_INSN (tmp)) != NULL_RTX
00952 && GET_CODE (tmp) == JUMP_INSN
00953 && (GET_CODE (PATTERN (tmp)) == ADDR_VEC
00954 || GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC))
00955 end = tmp;
00956
00957 while (1)
00958 {
00959 rtx next = NEXT_INSN (start);
00960
00961 if (GET_CODE (start) == INSN
00962 || GET_CODE (start) == CALL_INSN
00963 || GET_CODE (start) == JUMP_INSN)
00964 df_insn_delete (df_analyzer, BLOCK_FOR_INSN (start), start);
00965
00966 if (start == end)
00967 break;
00968 start = next;
00969 }
00970 }
00971 }
00972 }
00973
00974
00975
00976
00977
00978
00979
00980 void
00981 ssa_const_prop ()
00982 {
00983 unsigned int i;
00984 edge curredge;
00985
00986
00987 init_alias_analysis ();
00988
00989 df_analyzer = df_init ();
00990 df_analyse (df_analyzer, 0,
00991 DF_RD_CHAIN | DF_RU_CHAIN | DF_REG_INFO | DF_HARD_REGS);
00992
00993
00994
00995
00996 ssa_fast_dce (df_analyzer);
00997
00998
00999 edges = create_edge_list ();
01000
01001
01002 values = (value *) xmalloc (VARRAY_SIZE (ssa_definition) * sizeof (value));
01003 for (i = 0; i < VARRAY_SIZE (ssa_definition); i++)
01004 {
01005 if (i < FIRST_PSEUDO_REGISTER)
01006 values[i].lattice_val = VARYING;
01007 else
01008 values[i].lattice_val = UNDEFINED;
01009 values[i].const_value = NULL;
01010 }
01011
01012 ssa_edges = sbitmap_alloc (VARRAY_SIZE (ssa_definition));
01013 sbitmap_zero (ssa_edges);
01014
01015 executable_blocks = sbitmap_alloc (last_basic_block);
01016 sbitmap_zero (executable_blocks);
01017
01018 executable_edges = sbitmap_alloc (NUM_EDGES (edges));
01019 sbitmap_zero (executable_edges);
01020
01021 edge_info = (edge *) xmalloc (NUM_EDGES (edges) * sizeof (edge));
01022 flow_edges = ENTRY_BLOCK_PTR->succ;
01023
01024
01025
01026 for (curredge = ENTRY_BLOCK_PTR->succ; curredge;
01027 curredge = curredge->succ_next)
01028 {
01029 int index = EIE (curredge->src, curredge->dest);
01030 SET_BIT (executable_edges, index);
01031 edge_info[index] = curredge->succ_next;
01032 }
01033
01034
01035 do
01036 {
01037 examine_flow_edges ();
01038 follow_def_use_chains ();
01039 }
01040 while (flow_edges != NULL);
01041
01042
01043 ssa_ccp_substitute_constants ();
01044
01045
01046
01047 optimize_unexecutable_edges (edges, executable_edges);
01048
01049
01050
01051 ssa_ccp_df_delete_unreachable_insns ();
01052
01053 #if 0
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063 df_analyse (df_analyzer, 0,
01064 DF_RD_CHAIN | DF_RU_CHAIN | DF_REG_INFO | DF_HARD_REGS);
01065 #endif
01066
01067
01068
01069 ssa_fast_dce (df_analyzer);
01070
01071 free (values);
01072 values = NULL;
01073
01074 free (edge_info);
01075 edge_info = NULL;
01076
01077 sbitmap_free (executable_blocks);
01078 executable_blocks = NULL;
01079
01080 sbitmap_free (ssa_edges);
01081 ssa_edges = NULL;
01082
01083 free_edge_list (edges);
01084 edges = NULL;
01085
01086 sbitmap_free (executable_edges);
01087 executable_edges = NULL;
01088
01089 df_finish (df_analyzer);
01090 end_alias_analysis ();
01091 }
01092
01093 static int
01094 mark_references (current_rtx, data)
01095 rtx *current_rtx;
01096 void *data;
01097 {
01098 rtx x = *current_rtx;
01099 sbitmap worklist = (sbitmap) data;
01100
01101 if (x == NULL_RTX)
01102 return 0;
01103
01104 if (GET_CODE (x) == SET)
01105 {
01106 rtx dest = SET_DEST (x);
01107
01108 if (GET_CODE (dest) == STRICT_LOW_PART
01109 || GET_CODE (dest) == SUBREG
01110 || GET_CODE (dest) == SIGN_EXTRACT
01111 || GET_CODE (dest) == ZERO_EXTRACT)
01112 {
01113 rtx reg;
01114
01115 reg = dest;
01116
01117 while (GET_CODE (reg) == STRICT_LOW_PART
01118 || GET_CODE (reg) == SUBREG
01119 || GET_CODE (reg) == SIGN_EXTRACT
01120 || GET_CODE (reg) == ZERO_EXTRACT)
01121 reg = XEXP (reg, 0);
01122
01123 if (GET_CODE (reg) == REG)
01124 SET_BIT (worklist, REGNO (reg));
01125 }
01126
01127 if (GET_CODE (dest) == REG)
01128 {
01129 for_each_rtx (&SET_SRC (x), mark_references, data);
01130 return -1;
01131 }
01132
01133 return 0;
01134 }
01135 else if (GET_CODE (x) == REG)
01136 {
01137 SET_BIT (worklist, REGNO (x));
01138 return -1;
01139 }
01140 else if (GET_CODE (x) == CLOBBER)
01141 return -1;
01142 else
01143 return 0;
01144 }
01145
01146 static void
01147 ssa_fast_dce (df)
01148 struct df *df;
01149 {
01150 sbitmap worklist = sbitmap_alloc (VARRAY_SIZE (ssa_definition));
01151 sbitmap_ones (worklist);
01152
01153
01154
01155 while (sbitmap_first_set_bit (worklist) >= 0)
01156 {
01157 struct df_link *curruse;
01158 int reg, found_use;
01159
01160
01161 reg = sbitmap_first_set_bit (worklist);
01162 RESET_BIT (worklist, reg);
01163
01164
01165
01166
01167 if (reg < FIRST_PSEUDO_REGISTER
01168 || ! VARRAY_RTX (ssa_definition, reg)
01169 || INSN_DELETED_P (VARRAY_RTX (ssa_definition, reg))
01170 || (GET_CODE (VARRAY_RTX (ssa_definition, reg)) == NOTE
01171 && (NOTE_LINE_NUMBER (VARRAY_RTX (ssa_definition, reg))
01172 == NOTE_INSN_DELETED))
01173 || side_effects_p (PATTERN (VARRAY_RTX (ssa_definition, reg))))
01174 continue;
01175
01176
01177
01178
01179 found_use = 0;
01180 for (curruse = df->regs[reg].uses; curruse; curruse = curruse->next)
01181 {
01182 if (curruse->ref
01183 && DF_REF_INSN (curruse->ref)
01184 && ! INSN_DELETED_P (DF_REF_INSN (curruse->ref))
01185 && ! (GET_CODE (DF_REF_INSN (curruse->ref)) == NOTE
01186 && (NOTE_LINE_NUMBER (DF_REF_INSN (curruse->ref))
01187 == NOTE_INSN_DELETED))
01188 && DF_REF_INSN (curruse->ref) != VARRAY_RTX (ssa_definition, reg))
01189 {
01190 found_use = 1;
01191 break;
01192 }
01193 }
01194
01195
01196
01197
01198 if (! found_use)
01199 {
01200 rtx def = VARRAY_RTX (ssa_definition, reg);
01201
01202
01203
01204 for_each_rtx (&PATTERN (def), mark_references, worklist);
01205
01206
01207
01208 df_insn_delete (df, BLOCK_FOR_INSN (def), def);
01209
01210 VARRAY_RTX (ssa_definition, reg) = NULL;
01211 }
01212 }
01213
01214 sbitmap_free (worklist);
01215
01216
01217 df_analyse (df_analyzer, 0,
01218 DF_RD_CHAIN | DF_RU_CHAIN | DF_REG_INFO | DF_HARD_REGS);
01219 }