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 #include "config.h"
00027 #include "system.h"
00028 #include "coretypes.h"
00029 #include "tm.h"
00030 #include "rtl.h"
00031 #include "tm_p.h"
00032 #include "insn-config.h"
00033 #include "recog.h"
00034 #include "function.h"
00035 #include "regs.h"
00036 #include "output.h"
00037 #include "alloc-pool.h"
00038 #include "flags.h"
00039 #include "hard-reg-set.h"
00040 #include "basic-block.h"
00041 #include "sbitmap.h"
00042 #include "bitmap.h"
00043 #include "timevar.h"
00044 #include "df.h"
00045 #include "vecprim.h"
00046 #include "except.h"
00047
00048 #if 0
00049 #define REG_DEAD_DEBUGGING
00050 #endif
00051
00052 #define DF_SPARSE_THRESHOLD 32
00053
00054 static bitmap seen_in_block = NULL;
00055 static bitmap seen_in_insn = NULL;
00056 static void df_ri_dump (struct dataflow *, FILE *);
00057
00058
00059
00060
00061
00062
00063
00064
00065 struct df_link *
00066 df_chain_create (struct dataflow *dflow, struct df_ref *src, struct df_ref *dst)
00067 {
00068 struct df_link *head = DF_REF_CHAIN (src);
00069 struct df_link *link = pool_alloc (dflow->block_pool);;
00070
00071 DF_REF_CHAIN (src) = link;
00072 link->next = head;
00073 link->ref = dst;
00074 return link;
00075 }
00076
00077
00078
00079
00080
00081
00082
00083 void
00084 df_chain_unlink (struct dataflow *dflow, struct df_ref *ref, struct df_link *link)
00085 {
00086 struct df_link *chain = DF_REF_CHAIN (ref);
00087 if (link)
00088 {
00089
00090 if (chain == link)
00091 DF_REF_CHAIN (ref) = link->next;
00092 else
00093 {
00094
00095 struct df_link *prev = chain;
00096 while (chain)
00097 {
00098 if (chain == link)
00099 {
00100 prev->next = chain->next;
00101 break;
00102 }
00103 prev = chain;
00104 chain = chain->next;
00105 }
00106 }
00107 pool_free (dflow->block_pool, link);
00108 }
00109 else
00110 {
00111
00112
00113
00114
00115 while (chain)
00116 {
00117 struct df_link *next = chain->next;
00118
00119 df_chain_unlink (dflow, chain->ref, chain);
00120 chain = next;
00121 }
00122 }
00123 }
00124
00125
00126
00127
00128
00129 void
00130 df_chain_copy (struct dataflow *dflow,
00131 struct df_ref *to_ref,
00132 struct df_link *from_ref)
00133 {
00134 while (from_ref)
00135 {
00136 df_chain_create (dflow, to_ref, from_ref->ref);
00137 from_ref = from_ref->next;
00138 }
00139 }
00140
00141
00142
00143
00144
00145 bitmap
00146 df_get_live_in (struct df *df, basic_block bb)
00147 {
00148 gcc_assert (df->problems_by_index[DF_LR]);
00149
00150 if (df->problems_by_index[DF_UREC])
00151 return DF_RA_LIVE_IN (df, bb);
00152 else if (df->problems_by_index[DF_UR])
00153 return DF_LIVE_IN (df, bb);
00154 else
00155 return DF_UPWARD_LIVE_IN (df, bb);
00156 }
00157
00158
00159
00160
00161
00162 bitmap
00163 df_get_live_out (struct df *df, basic_block bb)
00164 {
00165 gcc_assert (df->problems_by_index[DF_LR]);
00166
00167 if (df->problems_by_index[DF_UREC])
00168 return DF_RA_LIVE_OUT (df, bb);
00169 else if (df->problems_by_index[DF_UR])
00170 return DF_LIVE_OUT (df, bb);
00171 else
00172 return DF_UPWARD_LIVE_OUT (df, bb);
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 void
00186 df_grow_bb_info (struct dataflow *dflow)
00187 {
00188 unsigned int new_size = last_basic_block + 1;
00189 if (dflow->block_info_size < new_size)
00190 {
00191 new_size += new_size / 4;
00192 dflow->block_info = xrealloc (dflow->block_info,
00193 new_size *sizeof (void*));
00194 memset (dflow->block_info + dflow->block_info_size, 0,
00195 (new_size - dflow->block_info_size) *sizeof (void *));
00196 dflow->block_info_size = new_size;
00197 }
00198 }
00199
00200
00201
00202 void
00203 df_chain_dump (struct df_link *link, FILE *file)
00204 {
00205 fprintf (file, "{ ");
00206 for (; link; link = link->next)
00207 {
00208 fprintf (file, "%c%d(bb %d insn %d) ",
00209 DF_REF_REG_DEF_P (link->ref) ? 'd' : 'u',
00210 DF_REF_ID (link->ref),
00211 DF_REF_BBNO (link->ref),
00212 DF_REF_INSN (link->ref) ? DF_REF_INSN_UID (link->ref) : -1);
00213 }
00214 fprintf (file, "}");
00215 }
00216
00217
00218
00219
00220 void
00221 df_print_bb_index (basic_block bb, FILE *file)
00222 {
00223 edge e;
00224 edge_iterator ei;
00225
00226 fprintf (file, "( ");
00227 FOR_EACH_EDGE (e, ei, bb->preds)
00228 {
00229 basic_block pred = e->src;
00230 fprintf (file, "%d ", pred->index);
00231 }
00232 fprintf (file, ")->[%d]->( ", bb->index);
00233 FOR_EACH_EDGE (e, ei, bb->succs)
00234 {
00235 basic_block succ = e->dest;
00236 fprintf (file, "%d ", succ->index);
00237 }
00238 fprintf (file, ")\n");
00239 }
00240
00241
00242
00243
00244
00245
00246 static inline bitmap
00247 df_ref_bitmap (bitmap *maps, unsigned int regno, int start, int count)
00248 {
00249 bitmap ids = maps[regno];
00250 if (!ids)
00251 {
00252 unsigned int i;
00253 unsigned int end = start + count;;
00254 ids = BITMAP_ALLOC (NULL);
00255 maps[regno] = ids;
00256 for (i = start; i < end; i++)
00257 bitmap_set_bit (ids, i);
00258 }
00259 return ids;
00260 }
00261
00262
00263
00264
00265
00266 static void
00267 df_set_seen (void)
00268 {
00269 seen_in_block = BITMAP_ALLOC (NULL);
00270 seen_in_insn = BITMAP_ALLOC (NULL);
00271 }
00272
00273
00274 static void
00275 df_unset_seen (void)
00276 {
00277 BITMAP_FREE (seen_in_block);
00278 BITMAP_FREE (seen_in_insn);
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 struct df_ru_problem_data
00320 {
00321
00322 bitmap *use_sites;
00323 unsigned int use_sites_size;
00324
00325 bitmap sparse_invalidated_by_call;
00326
00327 bitmap dense_invalidated_by_call;
00328 };
00329
00330
00331
00332 struct df_ru_bb_info *
00333 df_ru_get_bb_info (struct dataflow *dflow, unsigned int index)
00334 {
00335 return (struct df_ru_bb_info *) dflow->block_info[index];
00336 }
00337
00338
00339
00340
00341 static void
00342 df_ru_set_bb_info (struct dataflow *dflow, unsigned int index,
00343 struct df_ru_bb_info *bb_info)
00344 {
00345 dflow->block_info[index] = bb_info;
00346 }
00347
00348
00349
00350
00351 static void
00352 df_ru_free_bb_info (struct dataflow *dflow,
00353 basic_block bb ATTRIBUTE_UNUSED,
00354 void *vbb_info)
00355 {
00356 struct df_ru_bb_info *bb_info = (struct df_ru_bb_info *) vbb_info;
00357 if (bb_info)
00358 {
00359 BITMAP_FREE (bb_info->kill);
00360 BITMAP_FREE (bb_info->sparse_kill);
00361 BITMAP_FREE (bb_info->gen);
00362 BITMAP_FREE (bb_info->in);
00363 BITMAP_FREE (bb_info->out);
00364 pool_free (dflow->block_pool, bb_info);
00365 }
00366 }
00367
00368
00369
00370
00371
00372 static void
00373 df_ru_alloc (struct dataflow *dflow,
00374 bitmap blocks_to_rescan ATTRIBUTE_UNUSED,
00375 bitmap all_blocks)
00376 {
00377 unsigned int bb_index;
00378 bitmap_iterator bi;
00379 unsigned int reg_size = max_reg_num ();
00380
00381 if (!dflow->block_pool)
00382 dflow->block_pool = create_alloc_pool ("df_ru_block pool",
00383 sizeof (struct df_ru_bb_info), 50);
00384
00385 if (dflow->problem_data)
00386 {
00387 unsigned int i;
00388 struct df_ru_problem_data *problem_data
00389 = (struct df_ru_problem_data *) dflow->problem_data;
00390
00391 for (i = 0; i < problem_data->use_sites_size; i++)
00392 {
00393 bitmap bm = problem_data->use_sites[i];
00394 if (bm)
00395 {
00396 BITMAP_FREE (bm);
00397 problem_data->use_sites[i] = NULL;
00398 }
00399 }
00400
00401 if (problem_data->use_sites_size < reg_size)
00402 {
00403 problem_data->use_sites
00404 = xrealloc (problem_data->use_sites, reg_size * sizeof (bitmap));
00405 memset (problem_data->use_sites + problem_data->use_sites_size, 0,
00406 (reg_size - problem_data->use_sites_size) * sizeof (bitmap));
00407 problem_data->use_sites_size = reg_size;
00408 }
00409
00410 bitmap_clear (problem_data->sparse_invalidated_by_call);
00411 bitmap_clear (problem_data->dense_invalidated_by_call);
00412 }
00413 else
00414 {
00415 struct df_ru_problem_data *problem_data = XNEW (struct df_ru_problem_data);
00416 dflow->problem_data = problem_data;
00417
00418 problem_data->use_sites = XCNEWVEC (bitmap, reg_size);
00419 problem_data->use_sites_size = reg_size;
00420 problem_data->sparse_invalidated_by_call = BITMAP_ALLOC (NULL);
00421 problem_data->dense_invalidated_by_call = BITMAP_ALLOC (NULL);
00422 }
00423
00424 df_grow_bb_info (dflow);
00425
00426
00427
00428
00429
00430 EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
00431 {
00432 struct df_ru_bb_info *bb_info = df_ru_get_bb_info (dflow, bb_index);
00433 if (bb_info)
00434 {
00435 bitmap_clear (bb_info->kill);
00436 bitmap_clear (bb_info->sparse_kill);
00437 bitmap_clear (bb_info->gen);
00438 }
00439 else
00440 {
00441 bb_info = (struct df_ru_bb_info *) pool_alloc (dflow->block_pool);
00442 df_ru_set_bb_info (dflow, bb_index, bb_info);
00443 bb_info->kill = BITMAP_ALLOC (NULL);
00444 bb_info->sparse_kill = BITMAP_ALLOC (NULL);
00445 bb_info->gen = BITMAP_ALLOC (NULL);
00446 bb_info->in = BITMAP_ALLOC (NULL);
00447 bb_info->out = BITMAP_ALLOC (NULL);
00448 }
00449 }
00450 }
00451
00452
00453
00454
00455 static void
00456 df_ru_bb_local_compute_process_def (struct dataflow *dflow,
00457 struct df_ru_bb_info *bb_info,
00458 struct df_ref *def,
00459 enum df_ref_flags top_flag)
00460 {
00461 struct df *df = dflow->df;
00462 while (def)
00463 {
00464 if ((top_flag == (DF_REF_FLAGS (def) & DF_REF_AT_TOP))
00465
00466
00467 && (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL)))
00468 {
00469 unsigned int regno = DF_REF_REGNO (def);
00470 unsigned int begin = DF_REG_USE_GET (df, regno)->begin;
00471 unsigned int n_uses = DF_REG_USE_GET (df, regno)->n_refs;
00472 if (!bitmap_bit_p (seen_in_block, regno))
00473 {
00474
00475
00476
00477
00478
00479 if (!bitmap_bit_p (seen_in_insn, regno))
00480 {
00481 if (n_uses > DF_SPARSE_THRESHOLD)
00482 bitmap_set_bit (bb_info->sparse_kill, regno);
00483 else
00484 {
00485 struct df_ru_problem_data * problem_data
00486 = (struct df_ru_problem_data *)dflow->problem_data;
00487 bitmap uses
00488 = df_ref_bitmap (problem_data->use_sites, regno,
00489 begin, n_uses);
00490 bitmap_ior_into (bb_info->kill, uses);
00491 }
00492 }
00493 bitmap_set_bit (seen_in_insn, regno);
00494 }
00495 }
00496 def = def->next_ref;
00497 }
00498 }
00499
00500
00501
00502
00503 static void
00504 df_ru_bb_local_compute_process_use (struct df_ru_bb_info *bb_info,
00505 struct df_ref *use,
00506 enum df_ref_flags top_flag)
00507 {
00508 while (use)
00509 {
00510 if (top_flag == (DF_REF_FLAGS (use) & DF_REF_AT_TOP))
00511 {
00512
00513
00514 unsigned int regno = DF_REF_REGNO (use);
00515 if (!bitmap_bit_p (seen_in_block, regno))
00516 bitmap_set_bit (bb_info->gen, DF_REF_ID (use));
00517 }
00518 use = use->next_ref;
00519 }
00520 }
00521
00522
00523
00524 static void
00525 df_ru_bb_local_compute (struct dataflow *dflow, unsigned int bb_index)
00526 {
00527 struct df *df = dflow->df;
00528 basic_block bb = BASIC_BLOCK (bb_index);
00529 struct df_ru_bb_info *bb_info = df_ru_get_bb_info (dflow, bb_index);
00530 rtx insn;
00531
00532
00533 bitmap_clear (seen_in_block);
00534 bitmap_clear (seen_in_insn);
00535
00536 #ifdef EH_USES
00537
00538
00539 df_ru_bb_local_compute_process_use (bb_info,
00540 df_get_artificial_uses (df, bb_index),
00541 DF_REF_AT_TOP);
00542 #endif
00543 df_ru_bb_local_compute_process_def (dflow, bb_info,
00544 df_get_artificial_defs (df, bb_index),
00545 DF_REF_AT_TOP);
00546
00547 FOR_BB_INSNS (bb, insn)
00548 {
00549 unsigned int uid = INSN_UID (insn);
00550 if (!INSN_P (insn))
00551 continue;
00552
00553 df_ru_bb_local_compute_process_use (bb_info,
00554 DF_INSN_UID_USES (df, uid), 0);
00555
00556 df_ru_bb_local_compute_process_def (dflow, bb_info,
00557 DF_INSN_UID_DEFS (df, uid), 0);
00558
00559 bitmap_ior_into (seen_in_block, seen_in_insn);
00560 bitmap_clear (seen_in_insn);
00561 }
00562
00563
00564 df_ru_bb_local_compute_process_use (bb_info,
00565 df_get_artificial_uses (df, bb_index), 0);
00566
00567 df_ru_bb_local_compute_process_def (dflow, bb_info,
00568 df_get_artificial_defs (df, bb_index), 0);
00569 }
00570
00571
00572
00573
00574 static void
00575 df_ru_local_compute (struct dataflow *dflow,
00576 bitmap all_blocks,
00577 bitmap rescan_blocks ATTRIBUTE_UNUSED)
00578 {
00579 struct df *df = dflow->df;
00580 unsigned int bb_index;
00581 bitmap_iterator bi;
00582 unsigned int regno;
00583 struct df_ru_problem_data *problem_data
00584 = (struct df_ru_problem_data *) dflow->problem_data;
00585 bitmap sparse_invalidated = problem_data->sparse_invalidated_by_call;
00586 bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
00587
00588 df_set_seen ();
00589
00590 if (!df->use_info.refs_organized)
00591 df_reorganize_refs (&df->use_info);
00592
00593 EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
00594 {
00595 df_ru_bb_local_compute (dflow, bb_index);
00596 }
00597
00598
00599 EXECUTE_IF_SET_IN_BITMAP (df_invalidated_by_call, 0, regno, bi)
00600 {
00601 struct df_reg_info *reg_info = DF_REG_USE_GET (df, regno);
00602 if (reg_info->n_refs > DF_SPARSE_THRESHOLD)
00603 bitmap_set_bit (sparse_invalidated, regno);
00604 else
00605 {
00606 bitmap defs = df_ref_bitmap (problem_data->use_sites, regno,
00607 reg_info->begin, reg_info->n_refs);
00608 bitmap_ior_into (dense_invalidated, defs);
00609 }
00610 }
00611
00612 df_unset_seen ();
00613 }
00614
00615
00616
00617
00618 static void
00619 df_ru_init_solution (struct dataflow *dflow, bitmap all_blocks)
00620 {
00621 unsigned int bb_index;
00622 bitmap_iterator bi;
00623
00624 EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
00625 {
00626 struct df_ru_bb_info *bb_info = df_ru_get_bb_info (dflow, bb_index);
00627 bitmap_copy (bb_info->in, bb_info->gen);
00628 bitmap_clear (bb_info->out);
00629 }
00630 }
00631
00632
00633
00634
00635 static void
00636 df_ru_confluence_n (struct dataflow *dflow, edge e)
00637 {
00638 bitmap op1 = df_ru_get_bb_info (dflow, e->src->index)->out;
00639 bitmap op2 = df_ru_get_bb_info (dflow, e->dest->index)->in;
00640
00641 if (e->flags & EDGE_EH)
00642 {
00643 struct df_ru_problem_data *problem_data
00644 = (struct df_ru_problem_data *) dflow->problem_data;
00645 bitmap sparse_invalidated = problem_data->sparse_invalidated_by_call;
00646 bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
00647 struct df *df = dflow->df;
00648 bitmap_iterator bi;
00649 unsigned int regno;
00650 bitmap tmp = BITMAP_ALLOC (NULL);
00651
00652 bitmap_copy (tmp, op2);
00653 bitmap_and_compl_into (tmp, dense_invalidated);
00654
00655 EXECUTE_IF_SET_IN_BITMAP (sparse_invalidated, 0, regno, bi)
00656 {
00657 bitmap_clear_range (tmp,
00658 DF_REG_USE_GET (df, regno)->begin,
00659 DF_REG_USE_GET (df, regno)->n_refs);
00660 }
00661 bitmap_ior_into (op1, tmp);
00662 BITMAP_FREE (tmp);
00663 }
00664 else
00665 bitmap_ior_into (op1, op2);
00666 }
00667
00668
00669
00670
00671 static bool
00672 df_ru_transfer_function (struct dataflow *dflow, int bb_index)
00673 {
00674 struct df_ru_bb_info *bb_info = df_ru_get_bb_info (dflow, bb_index);
00675 unsigned int regno;
00676 bitmap_iterator bi;
00677 bitmap in = bb_info->in;
00678 bitmap out = bb_info->out;
00679 bitmap gen = bb_info->gen;
00680 bitmap kill = bb_info->kill;
00681 bitmap sparse_kill = bb_info->sparse_kill;
00682
00683 if (bitmap_empty_p (sparse_kill))
00684 return bitmap_ior_and_compl (in, gen, out, kill);
00685 else
00686 {
00687 struct df *df = dflow->df;
00688 bool changed = false;
00689 bitmap tmp = BITMAP_ALLOC (NULL);
00690 bitmap_copy (tmp, out);
00691 EXECUTE_IF_SET_IN_BITMAP (sparse_kill, 0, regno, bi)
00692 {
00693 bitmap_clear_range (tmp,
00694 DF_REG_USE_GET (df, regno)->begin,
00695 DF_REG_USE_GET (df, regno)->n_refs);
00696 }
00697 bitmap_and_compl_into (tmp, kill);
00698 bitmap_ior_into (tmp, gen);
00699 changed = !bitmap_equal_p (tmp, in);
00700 if (changed)
00701 {
00702 BITMAP_FREE (in);
00703 bb_info->in = tmp;
00704 }
00705 else
00706 BITMAP_FREE (tmp);
00707 return changed;
00708 }
00709 }
00710
00711
00712
00713
00714 static void
00715 df_ru_free (struct dataflow *dflow)
00716 {
00717 unsigned int i;
00718 struct df_ru_problem_data *problem_data
00719 = (struct df_ru_problem_data *) dflow->problem_data;
00720
00721 if (problem_data)
00722 {
00723 for (i = 0; i < dflow->block_info_size; i++)
00724 {
00725 struct df_ru_bb_info *bb_info = df_ru_get_bb_info (dflow, i);
00726 if (bb_info)
00727 {
00728 BITMAP_FREE (bb_info->kill);
00729 BITMAP_FREE (bb_info->sparse_kill);
00730 BITMAP_FREE (bb_info->gen);
00731 BITMAP_FREE (bb_info->in);
00732 BITMAP_FREE (bb_info->out);
00733 }
00734 }
00735
00736 free_alloc_pool (dflow->block_pool);
00737
00738 for (i = 0; i < problem_data->use_sites_size; i++)
00739 {
00740 bitmap bm = problem_data->use_sites[i];
00741 if (bm)
00742 BITMAP_FREE (bm);
00743 }
00744
00745 free (problem_data->use_sites);
00746 BITMAP_FREE (problem_data->sparse_invalidated_by_call);
00747 BITMAP_FREE (problem_data->dense_invalidated_by_call);
00748
00749 dflow->block_info_size = 0;
00750 free (dflow->block_info);
00751 free (dflow->problem_data);
00752 }
00753 free (dflow);
00754 }
00755
00756
00757
00758
00759 static void
00760 df_ru_dump (struct dataflow *dflow, FILE *file)
00761 {
00762 basic_block bb;
00763 struct df *df = dflow->df;
00764 struct df_ru_problem_data *problem_data
00765 = (struct df_ru_problem_data *) dflow->problem_data;
00766 unsigned int m = max_reg_num ();
00767 unsigned int regno;
00768
00769 if (!dflow->block_info)
00770 return;
00771
00772 fprintf (file, "Reaching uses:\n");
00773
00774 fprintf (file, " sparse invalidated \t");
00775 dump_bitmap (file, problem_data->sparse_invalidated_by_call);
00776 fprintf (file, " dense invalidated \t");
00777 dump_bitmap (file, problem_data->dense_invalidated_by_call);
00778
00779 for (regno = 0; regno < m; regno++)
00780 if (DF_REG_USE_GET (df, regno)->n_refs)
00781 fprintf (file, "%d[%d,%d] ", regno,
00782 DF_REG_USE_GET (df, regno)->begin,
00783 DF_REG_USE_GET (df, regno)->n_refs);
00784 fprintf (file, "\n");
00785
00786 FOR_ALL_BB (bb)
00787 {
00788 struct df_ru_bb_info *bb_info = df_ru_get_bb_info (dflow, bb->index);
00789 df_print_bb_index (bb, file);
00790
00791 if (!bb_info->in)
00792 continue;
00793
00794 fprintf (file, " in \t(%d)\n", (int) bitmap_count_bits (bb_info->in));
00795 dump_bitmap (file, bb_info->in);
00796 fprintf (file, " gen \t(%d)\n", (int) bitmap_count_bits (bb_info->gen));
00797 dump_bitmap (file, bb_info->gen);
00798 fprintf (file, " kill\t(%d)\n", (int) bitmap_count_bits (bb_info->kill));
00799 dump_bitmap (file, bb_info->kill);
00800 fprintf (file, " out \t(%d)\n", (int) bitmap_count_bits (bb_info->out));
00801 dump_bitmap (file, bb_info->out);
00802 }
00803 }
00804
00805
00806
00807 static struct df_problem problem_RU =
00808 {
00809 DF_RU,
00810 DF_BACKWARD,
00811 df_ru_alloc,
00812 NULL,
00813 df_ru_free_bb_info,
00814 df_ru_local_compute,
00815 df_ru_init_solution,
00816 df_iterative_dataflow,
00817 NULL,
00818 df_ru_confluence_n,
00819 df_ru_transfer_function,
00820 NULL,
00821 df_ru_free,
00822 df_ru_dump,
00823 NULL,
00824 0
00825 };
00826
00827
00828
00829
00830
00831
00832
00833 struct dataflow *
00834 df_ru_add_problem (struct df *df, int flags)
00835 {
00836 return df_add_problem (df, &problem_RU, flags);
00837 }
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855 struct df_rd_problem_data
00856 {
00857
00858
00859
00860
00861
00862 bitmap *def_sites;
00863 unsigned int def_sites_size;
00864
00865 bitmap sparse_invalidated_by_call;
00866
00867 bitmap dense_invalidated_by_call;
00868 };
00869
00870
00871
00872 struct df_rd_bb_info *
00873 df_rd_get_bb_info (struct dataflow *dflow, unsigned int index)
00874 {
00875 return (struct df_rd_bb_info *) dflow->block_info[index];
00876 }
00877
00878
00879
00880
00881 static void
00882 df_rd_set_bb_info (struct dataflow *dflow, unsigned int index,
00883 struct df_rd_bb_info *bb_info)
00884 {
00885 dflow->block_info[index] = bb_info;
00886 }
00887
00888
00889
00890
00891 static void
00892 df_rd_free_bb_info (struct dataflow *dflow,
00893 basic_block bb ATTRIBUTE_UNUSED,
00894 void *vbb_info)
00895 {
00896 struct df_rd_bb_info *bb_info = (struct df_rd_bb_info *) vbb_info;
00897 if (bb_info)
00898 {
00899 BITMAP_FREE (bb_info->kill);
00900 BITMAP_FREE (bb_info->sparse_kill);
00901 BITMAP_FREE (bb_info->gen);
00902 BITMAP_FREE (bb_info->in);
00903 BITMAP_FREE (bb_info->out);
00904 pool_free (dflow->block_pool, bb_info);
00905 }
00906 }
00907
00908
00909
00910
00911
00912 static void
00913 df_rd_alloc (struct dataflow *dflow,
00914 bitmap blocks_to_rescan ATTRIBUTE_UNUSED,
00915 bitmap all_blocks)
00916 {
00917 unsigned int bb_index;
00918 bitmap_iterator bi;
00919 unsigned int reg_size = max_reg_num ();
00920
00921 if (!dflow->block_pool)
00922 dflow->block_pool = create_alloc_pool ("df_rd_block pool",
00923 sizeof (struct df_rd_bb_info), 50);
00924
00925 if (dflow->problem_data)
00926 {
00927 unsigned int i;
00928 struct df_rd_problem_data *problem_data
00929 = (struct df_rd_problem_data *) dflow->problem_data;
00930
00931 for (i = 0; i < problem_data->def_sites_size; i++)
00932 {
00933 bitmap bm = problem_data->def_sites[i];
00934 if (bm)
00935 {
00936 BITMAP_FREE (bm);
00937 problem_data->def_sites[i] = NULL;
00938 }
00939 }
00940
00941 if (problem_data->def_sites_size < reg_size)
00942 {
00943 problem_data->def_sites
00944 = xrealloc (problem_data->def_sites, reg_size *sizeof (bitmap));
00945 memset (problem_data->def_sites + problem_data->def_sites_size, 0,
00946 (reg_size - problem_data->def_sites_size) *sizeof (bitmap));
00947 problem_data->def_sites_size = reg_size;
00948 }
00949
00950 bitmap_clear (problem_data->sparse_invalidated_by_call);
00951 bitmap_clear (problem_data->dense_invalidated_by_call);
00952 }
00953 else
00954 {
00955 struct df_rd_problem_data *problem_data = XNEW (struct df_rd_problem_data);
00956 dflow->problem_data = problem_data;
00957
00958 problem_data->def_sites = XCNEWVEC (bitmap, reg_size);
00959 problem_data->def_sites_size = reg_size;
00960 problem_data->sparse_invalidated_by_call = BITMAP_ALLOC (NULL);
00961 problem_data->dense_invalidated_by_call = BITMAP_ALLOC (NULL);
00962 }
00963
00964 df_grow_bb_info (dflow);
00965
00966
00967
00968
00969
00970 EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
00971 {
00972 struct df_rd_bb_info *bb_info = df_rd_get_bb_info (dflow, bb_index);
00973 if (bb_info)
00974 {
00975 bitmap_clear (bb_info->kill);
00976 bitmap_clear (bb_info->sparse_kill);
00977 bitmap_clear (bb_info->gen);
00978 }
00979 else
00980 {
00981 bb_info = (struct df_rd_bb_info *) pool_alloc (dflow->block_pool);
00982 df_rd_set_bb_info (dflow, bb_index, bb_info);
00983 bb_info->kill = BITMAP_ALLOC (NULL);
00984 bb_info->sparse_kill = BITMAP_ALLOC (NULL);
00985 bb_info->gen = BITMAP_ALLOC (NULL);
00986 bb_info->in = BITMAP_ALLOC (NULL);
00987 bb_info->out = BITMAP_ALLOC (NULL);
00988 }
00989 }
00990 }
00991
00992
00993
00994
00995 static void
00996 df_rd_bb_local_compute_process_def (struct dataflow *dflow,
00997 struct df_rd_bb_info *bb_info,
00998 struct df_ref *def,
00999 enum df_ref_flags top_flag)
01000 {
01001 struct df *df = dflow->df;
01002 while (def)
01003 {
01004 if (top_flag == (DF_REF_FLAGS (def) & DF_REF_AT_TOP))
01005 {
01006 unsigned int regno = DF_REF_REGNO (def);
01007 unsigned int begin = DF_REG_DEF_GET (df, regno)->begin;
01008 unsigned int n_defs = DF_REG_DEF_GET (df, regno)->n_refs;
01009
01010
01011
01012 if (!bitmap_bit_p (seen_in_block, regno))
01013 {
01014
01015
01016 if ((!bitmap_bit_p (seen_in_insn, regno))
01017
01018
01019 && (!((DF_REF_FLAGS (def) & DF_REF_PARTIAL)
01020 || (DF_REF_FLAGS (def) & DF_REF_MAY_CLOBBER))))
01021 {
01022 if (n_defs > DF_SPARSE_THRESHOLD)
01023 {
01024 bitmap_set_bit (bb_info->sparse_kill, regno);
01025 bitmap_clear_range(bb_info->gen, begin, n_defs);
01026 }
01027 else
01028 {
01029 struct df_rd_problem_data * problem_data
01030 = (struct df_rd_problem_data *)dflow->problem_data;
01031 bitmap defs = df_ref_bitmap (problem_data->def_sites,
01032 regno, begin, n_defs);
01033 bitmap_ior_into (bb_info->kill, defs);
01034 bitmap_and_compl_into (bb_info->gen, defs);
01035 }
01036 }
01037
01038 bitmap_set_bit (seen_in_insn, regno);
01039
01040
01041 if (!(DF_REF_FLAGS (def)
01042 & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
01043 bitmap_set_bit (bb_info->gen, DF_REF_ID (def));
01044 }
01045 }
01046 def = def->next_ref;
01047 }
01048 }
01049
01050
01051
01052 static void
01053 df_rd_bb_local_compute (struct dataflow *dflow, unsigned int bb_index)
01054 {
01055 struct df *df = dflow->df;
01056 basic_block bb = BASIC_BLOCK (bb_index);
01057 struct df_rd_bb_info *bb_info = df_rd_get_bb_info (dflow, bb_index);
01058 rtx insn;
01059
01060 bitmap_clear (seen_in_block);
01061 bitmap_clear (seen_in_insn);
01062
01063 df_rd_bb_local_compute_process_def (dflow, bb_info,
01064 df_get_artificial_defs (df, bb_index), 0);
01065
01066 FOR_BB_INSNS_REVERSE (bb, insn)
01067 {
01068 unsigned int uid = INSN_UID (insn);
01069
01070 if (!INSN_P (insn))
01071 continue;
01072
01073 df_rd_bb_local_compute_process_def (dflow, bb_info,
01074 DF_INSN_UID_DEFS (df, uid), 0);
01075
01076
01077
01078
01079
01080
01081
01082 bitmap_ior_into (seen_in_block, seen_in_insn);
01083 bitmap_clear (seen_in_insn);
01084 }
01085
01086
01087
01088
01089 df_rd_bb_local_compute_process_def (dflow, bb_info,
01090 df_get_artificial_defs (df, bb_index),
01091 DF_REF_AT_TOP);
01092 }
01093
01094
01095
01096
01097 static void
01098 df_rd_local_compute (struct dataflow *dflow,
01099 bitmap all_blocks,
01100 bitmap rescan_blocks ATTRIBUTE_UNUSED)
01101 {
01102 struct df *df = dflow->df;
01103 unsigned int bb_index;
01104 bitmap_iterator bi;
01105 unsigned int regno;
01106 struct df_rd_problem_data *problem_data
01107 = (struct df_rd_problem_data *) dflow->problem_data;
01108 bitmap sparse_invalidated = problem_data->sparse_invalidated_by_call;
01109 bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
01110
01111 df_set_seen ();
01112
01113 if (!df->def_info.refs_organized)
01114 df_reorganize_refs (&df->def_info);
01115
01116 EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
01117 {
01118 df_rd_bb_local_compute (dflow, bb_index);
01119 }
01120
01121
01122 EXECUTE_IF_SET_IN_BITMAP (df_invalidated_by_call, 0, regno, bi)
01123 {
01124 struct df_reg_info *reg_info = DF_REG_DEF_GET (df, regno);
01125 if (reg_info->n_refs > DF_SPARSE_THRESHOLD)
01126 {
01127 bitmap_set_bit (sparse_invalidated, regno);
01128 }
01129 else
01130 {
01131 bitmap defs = df_ref_bitmap (problem_data->def_sites, regno,
01132 reg_info->begin, reg_info->n_refs);
01133 bitmap_ior_into (dense_invalidated, defs);
01134 }
01135 }
01136 df_unset_seen ();
01137 }
01138
01139
01140
01141
01142 static void
01143 df_rd_init_solution (struct dataflow *dflow, bitmap all_blocks)
01144 {
01145 unsigned int bb_index;
01146 bitmap_iterator bi;
01147
01148 EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
01149 {
01150 struct df_rd_bb_info *bb_info = df_rd_get_bb_info (dflow, bb_index);
01151
01152 bitmap_copy (bb_info->out, bb_info->gen);
01153 bitmap_clear (bb_info->in);
01154 }
01155 }
01156
01157
01158
01159 static void
01160 df_rd_confluence_n (struct dataflow *dflow, edge e)
01161 {
01162 bitmap op1 = df_rd_get_bb_info (dflow, e->dest->index)->in;
01163 bitmap op2 = df_rd_get_bb_info (dflow, e->src->index)->out;
01164
01165 if (e->flags & EDGE_EH)
01166 {
01167 struct df_rd_problem_data *problem_data
01168 = (struct df_rd_problem_data *) dflow->problem_data;
01169 bitmap sparse_invalidated = problem_data->sparse_invalidated_by_call;
01170 bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
01171 struct df *df = dflow->df;
01172 bitmap_iterator bi;
01173 unsigned int regno;
01174 bitmap tmp = BITMAP_ALLOC (NULL);
01175
01176 bitmap_copy (tmp, op2);
01177 bitmap_and_compl_into (tmp, dense_invalidated);
01178
01179 EXECUTE_IF_SET_IN_BITMAP (sparse_invalidated, 0, regno, bi)
01180 {
01181 bitmap_clear_range (tmp,
01182 DF_REG_DEF_GET (df, regno)->begin,
01183 DF_REG_DEF_GET (df, regno)->n_refs);
01184 }
01185 bitmap_ior_into (op1, tmp);
01186 BITMAP_FREE (tmp);
01187 }
01188 else
01189 bitmap_ior_into (op1, op2);
01190 }
01191
01192
01193
01194
01195 static bool
01196 df_rd_transfer_function (struct dataflow *dflow, int bb_index)
01197 {
01198 struct df_rd_bb_info *bb_info = df_rd_get_bb_info (dflow, bb_index);
01199 unsigned int regno;
01200 bitmap_iterator bi;
01201 bitmap in = bb_info->in;
01202 bitmap out = bb_info->out;
01203 bitmap gen = bb_info->gen;
01204 bitmap kill = bb_info->kill;
01205 bitmap sparse_kill = bb_info->sparse_kill;
01206
01207 if (bitmap_empty_p (sparse_kill))
01208 return bitmap_ior_and_compl (out, gen, in, kill);
01209 else
01210 {
01211 struct df *df = dflow->df;
01212 bool changed = false;
01213 bitmap tmp = BITMAP_ALLOC (NULL);
01214 bitmap_copy (tmp, in);
01215 EXECUTE_IF_SET_IN_BITMAP (sparse_kill, 0, regno, bi)
01216 {
01217 bitmap_clear_range (tmp,
01218 DF_REG_DEF_GET (df, regno)->begin,
01219 DF_REG_DEF_GET (df, regno)->n_refs);
01220 }
01221 bitmap_and_compl_into (tmp, kill);
01222 bitmap_ior_into (tmp, gen);
01223 changed = !bitmap_equal_p (tmp, out);
01224 if (changed)
01225 {
01226 BITMAP_FREE (out);
01227 bb_info->out = tmp;
01228 }
01229 else
01230 BITMAP_FREE (tmp);
01231 return changed;
01232 }
01233 }
01234
01235
01236
01237
01238 static void
01239 df_rd_free (struct dataflow *dflow)
01240 {
01241 unsigned int i;
01242 struct df_rd_problem_data *problem_data
01243 = (struct df_rd_problem_data *) dflow->problem_data;
01244
01245 if (problem_data)
01246 {
01247 for (i = 0; i < dflow->block_info_size; i++)
01248 {
01249 struct df_rd_bb_info *bb_info = df_rd_get_bb_info (dflow, i);
01250 if (bb_info)
01251 {
01252 BITMAP_FREE (bb_info->kill);
01253 BITMAP_FREE (bb_info->sparse_kill);
01254 BITMAP_FREE (bb_info->gen);
01255 BITMAP_FREE (bb_info->in);
01256 BITMAP_FREE (bb_info->out);
01257 }
01258 }
01259
01260 free_alloc_pool (dflow->block_pool);
01261
01262 for (i = 0; i < problem_data->def_sites_size; i++)
01263 {
01264 bitmap bm = problem_data->def_sites[i];
01265 if (bm)
01266 BITMAP_FREE (bm);
01267 }
01268
01269 free (problem_data->def_sites);
01270 BITMAP_FREE (problem_data->sparse_invalidated_by_call);
01271 BITMAP_FREE (problem_data->dense_invalidated_by_call);
01272
01273 dflow->block_info_size = 0;
01274 free (dflow->block_info);
01275 free (dflow->problem_data);
01276 }
01277 free (dflow);
01278 }
01279
01280
01281
01282
01283 static void
01284 df_rd_dump (struct dataflow *dflow, FILE *file)
01285 {
01286 struct df *df = dflow->df;
01287 basic_block bb;
01288 struct df_rd_problem_data *problem_data
01289 = (struct df_rd_problem_data *) dflow->problem_data;
01290 unsigned int m = max_reg_num ();
01291 unsigned int regno;
01292
01293 if (!dflow->block_info)
01294 return;
01295
01296 fprintf (file, "Reaching defs:\n\n");
01297
01298 fprintf (file, " sparse invalidated \t");
01299 dump_bitmap (file, problem_data->sparse_invalidated_by_call);
01300 fprintf (file, " dense invalidated \t");
01301 dump_bitmap (file, problem_data->dense_invalidated_by_call);
01302
01303 for (regno = 0; regno < m; regno++)
01304 if (DF_REG_DEF_GET (df, regno)->n_refs)
01305 fprintf (file, "%d[%d,%d] ", regno,
01306 DF_REG_DEF_GET (df, regno)->begin,
01307 DF_REG_DEF_GET (df, regno)->n_refs);
01308 fprintf (file, "\n");
01309
01310 FOR_ALL_BB (bb)
01311 {
01312 struct df_rd_bb_info *bb_info = df_rd_get_bb_info (dflow, bb->index);
01313 df_print_bb_index (bb, file);
01314
01315 if (!bb_info->in)
01316 continue;
01317
01318 fprintf (file, " in \t(%d)\n", (int) bitmap_count_bits (bb_info->in));
01319 dump_bitmap (file, bb_info->in);
01320 fprintf (file, " gen \t(%d)\n", (int) bitmap_count_bits (bb_info->gen));
01321 dump_bitmap (file, bb_info->gen);
01322 fprintf (file, " kill\t(%d)\n", (int) bitmap_count_bits (bb_info->kill));
01323 dump_bitmap (file, bb_info->kill);
01324 fprintf (file, " out \t(%d)\n", (int) bitmap_count_bits (bb_info->out));
01325 dump_bitmap (file, bb_info->out);
01326 }
01327 }
01328
01329
01330
01331 static struct df_problem problem_RD =
01332 {
01333 DF_RD,
01334 DF_FORWARD,
01335 df_rd_alloc,
01336 NULL,
01337 df_rd_free_bb_info,
01338 df_rd_local_compute,
01339 df_rd_init_solution,
01340 df_iterative_dataflow,
01341 NULL,
01342 df_rd_confluence_n,
01343 df_rd_transfer_function,
01344 NULL,
01345 df_rd_free,
01346 df_rd_dump,
01347 NULL,
01348 0
01349 };
01350
01351
01352
01353
01354
01355
01356
01357 struct dataflow *
01358 df_rd_add_problem (struct df *df, int flags)
01359 {
01360 return df_add_problem (df, &problem_RD, flags);
01361 }
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376 struct df_lr_bb_info *
01377 df_lr_get_bb_info (struct dataflow *dflow, unsigned int index)
01378 {
01379 return (struct df_lr_bb_info *) dflow->block_info[index];
01380 }
01381
01382
01383
01384
01385 static void
01386 df_lr_set_bb_info (struct dataflow *dflow, unsigned int index,
01387 struct df_lr_bb_info *bb_info)
01388 {
01389 dflow->block_info[index] = bb_info;
01390 }
01391
01392
01393
01394
01395 static void
01396 df_lr_free_bb_info (struct dataflow *dflow,
01397 basic_block bb ATTRIBUTE_UNUSED,
01398 void *vbb_info)
01399 {
01400 struct df_lr_bb_info *bb_info = (struct df_lr_bb_info *) vbb_info;
01401 if (bb_info)
01402 {
01403 BITMAP_FREE (bb_info->use);
01404 BITMAP_FREE (bb_info->def);
01405 BITMAP_FREE (bb_info->in);
01406 BITMAP_FREE (bb_info->out);
01407 pool_free (dflow->block_pool, bb_info);
01408 }
01409 }
01410
01411
01412
01413
01414
01415 static void
01416 df_lr_alloc (struct dataflow *dflow, bitmap blocks_to_rescan,
01417 bitmap all_blocks ATTRIBUTE_UNUSED)
01418 {
01419 unsigned int bb_index;
01420 bitmap_iterator bi;
01421
01422 if (!dflow->block_pool)
01423 dflow->block_pool = create_alloc_pool ("df_lr_block pool",
01424 sizeof (struct df_lr_bb_info), 50);
01425
01426 df_grow_bb_info (dflow);
01427
01428 EXECUTE_IF_SET_IN_BITMAP (blocks_to_rescan, 0, bb_index, bi)
01429 {
01430 struct df_lr_bb_info *bb_info = df_lr_get_bb_info (dflow, bb_index);
01431 if (bb_info)
01432 {
01433 bitmap_clear (bb_info->def);
01434 bitmap_clear (bb_info->use);
01435 }
01436 else
01437 {
01438 bb_info = (struct df_lr_bb_info *) pool_alloc (dflow->block_pool);
01439 df_lr_set_bb_info (dflow, bb_index, bb_info);
01440 bb_info->use = BITMAP_ALLOC (NULL);
01441 bb_info->def = BITMAP_ALLOC (NULL);
01442 bb_info->in = BITMAP_ALLOC (NULL);
01443 bb_info->out = BITMAP_ALLOC (NULL);
01444 }
01445 }
01446 }
01447
01448
01449
01450
01451 static void
01452 df_lr_bb_local_compute (struct dataflow *dflow,
01453 struct df *df, unsigned int bb_index)
01454 {
01455 basic_block bb = BASIC_BLOCK (bb_index);
01456 struct df_lr_bb_info *bb_info = df_lr_get_bb_info (dflow, bb_index);
01457 rtx insn;
01458 struct df_ref *def;
01459 struct df_ref *use;
01460
01461
01462 for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
01463 if (((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
01464 && (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL)))
01465 {
01466 unsigned int dregno = DF_REF_REGNO (def);
01467 bitmap_set_bit (bb_info->def, dregno);
01468 bitmap_clear_bit (bb_info->use, dregno);
01469 }
01470
01471
01472 for (use = df_get_artificial_uses (df, bb_index); use; use = use->next_ref)
01473
01474 if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
01475 bitmap_set_bit (bb_info->use, DF_REF_REGNO (use));
01476
01477 FOR_BB_INSNS_REVERSE (bb, insn)
01478 {
01479 unsigned int uid = INSN_UID (insn);
01480
01481 if (!INSN_P (insn))
01482 continue;
01483
01484 if (CALL_P (insn))
01485 {
01486 for (def = DF_INSN_UID_DEFS (df, uid); def; def = def->next_ref)
01487 {
01488 unsigned int dregno = DF_REF_REGNO (def);
01489
01490 if (dregno >= FIRST_PSEUDO_REGISTER
01491 || !(SIBLING_CALL_P (insn)
01492 && bitmap_bit_p (df->exit_block_uses, dregno)
01493 && !refers_to_regno_p (dregno, dregno+1,
01494 current_function_return_rtx,
01495 (rtx *)0)))
01496 {
01497
01498
01499 if (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL))
01500 {
01501 bitmap_set_bit (bb_info->def, dregno);
01502 bitmap_clear_bit (bb_info->use, dregno);
01503 }
01504 }
01505 }
01506 }
01507 else
01508 {
01509 for (def = DF_INSN_UID_DEFS (df, uid); def; def = def->next_ref)
01510 {
01511 unsigned int dregno = DF_REF_REGNO (def);
01512
01513 if (DF_INSN_CONTAINS_ASM (df, insn)
01514 && dregno < FIRST_PSEUDO_REGISTER)
01515 {
01516 unsigned int i;
01517 unsigned int end = dregno
01518 + hard_regno_nregs[dregno][GET_MODE (DF_REF_REG (def))] - 1;
01519 for (i = dregno; i <= end; ++i)
01520 regs_asm_clobbered[i] = 1;
01521 }
01522
01523
01524 if (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL))
01525 {
01526 bitmap_set_bit (bb_info->def, dregno);
01527 bitmap_clear_bit (bb_info->use, dregno);
01528 }
01529 }
01530 }
01531
01532 for (use = DF_INSN_UID_USES (df, uid); use; use = use->next_ref)
01533
01534 bitmap_set_bit (bb_info->use, DF_REF_REGNO (use));
01535 }
01536
01537
01538 for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
01539 if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP)
01540 && (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL)))
01541 {
01542 unsigned int dregno = DF_REF_REGNO (def);
01543 bitmap_set_bit (bb_info->def, dregno);
01544 bitmap_clear_bit (bb_info->use, dregno);
01545 }
01546
01547 #ifdef EH_USES
01548
01549 for (use = df_get_artificial_uses (df, bb_index); use; use = use->next_ref)
01550
01551 if (DF_REF_FLAGS (use) & DF_REF_AT_TOP)
01552 bitmap_set_bit (bb_info->use, DF_REF_REGNO (use));
01553 #endif
01554 }
01555
01556
01557
01558
01559 static void
01560 df_lr_local_compute (struct dataflow *dflow,
01561 bitmap all_blocks,
01562 bitmap rescan_blocks)
01563 {
01564 struct df *df = dflow->df;
01565 unsigned int bb_index;
01566 bitmap_iterator bi;
01567
01568
01569
01570 if (bitmap_equal_p (all_blocks, rescan_blocks))
01571 memset (regs_asm_clobbered, 0, sizeof (regs_asm_clobbered));
01572
01573 bitmap_clear (df->hardware_regs_used);
01574
01575
01576 bitmap_set_bit (df->hardware_regs_used, STACK_POINTER_REGNUM);
01577
01578
01579
01580
01581 if (!reload_completed)
01582 {
01583
01584
01585 bitmap_set_bit (df->hardware_regs_used, FRAME_POINTER_REGNUM);
01586
01587 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
01588
01589
01590 if (fixed_regs[ARG_POINTER_REGNUM])
01591 bitmap_set_bit (df->hardware_regs_used, ARG_POINTER_REGNUM);
01592 #endif
01593
01594
01595
01596 if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
01597 && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
01598 bitmap_set_bit (df->hardware_regs_used, PIC_OFFSET_TABLE_REGNUM);
01599 }
01600
01601 if (bitmap_bit_p (rescan_blocks, EXIT_BLOCK))
01602 {
01603
01604
01605 struct df_lr_bb_info *bb_info = df_lr_get_bb_info (dflow, EXIT_BLOCK);
01606 bitmap_copy (bb_info->use, df->exit_block_uses);
01607 }
01608
01609 EXECUTE_IF_SET_IN_BITMAP (rescan_blocks, 0, bb_index, bi)
01610 {
01611 if (bb_index == EXIT_BLOCK)
01612 continue;
01613 df_lr_bb_local_compute (dflow, df, bb_index);
01614 }
01615 }
01616
01617
01618
01619
01620 static void
01621 df_lr_init (struct dataflow *dflow, bitmap all_blocks)
01622 {
01623 unsigned int bb_index;
01624 bitmap_iterator bi;
01625
01626 EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
01627 {
01628 struct df_lr_bb_info *bb_info = df_lr_get_bb_info (dflow, bb_index);
01629 bitmap_copy (bb_info->in, bb_info->use);
01630 bitmap_clear (bb_info->out);
01631 }
01632 }
01633
01634
01635
01636
01637
01638 static void
01639 df_lr_confluence_0 (struct dataflow *dflow, basic_block bb)
01640 {
01641 struct df *df = dflow->df;
01642
01643 bitmap op1 = df_lr_get_bb_info (dflow, bb->index)->out;
01644 if (bb != EXIT_BLOCK_PTR)
01645 bitmap_copy (op1, df->hardware_regs_used);
01646 }
01647
01648
01649
01650
01651 static void
01652 df_lr_confluence_n (struct dataflow *dflow, edge e)
01653 {
01654 bitmap op1 = df_lr_get_bb_info (dflow, e->src->index)->out;
01655 bitmap op2 = df_lr_get_bb_info (dflow, e->dest->index)->in;
01656
01657
01658
01659
01660 if (e->flags & EDGE_EH)
01661 bitmap_ior_and_compl_into (op1, op2, df_invalidated_by_call);
01662 else
01663 bitmap_ior_into (op1, op2);
01664
01665 bitmap_ior_into (op1, dflow->df->hardware_regs_used);
01666 }
01667
01668
01669
01670
01671 static bool
01672 df_lr_transfer_function (struct dataflow *dflow, int bb_index)
01673 {
01674 struct df_lr_bb_info *bb_info = df_lr_get_bb_info (dflow, bb_index);
01675 bitmap in = bb_info->in;
01676 bitmap out = bb_info->out;
01677 bitmap use = bb_info->use;
01678 bitmap def = bb_info->def;
01679
01680 return bitmap_ior_and_compl (in, use, out, def);
01681 }
01682
01683
01684
01685
01686 static void
01687 df_lr_free (struct dataflow *dflow)
01688 {
01689 if (dflow->block_info)
01690 {
01691 unsigned int i;
01692 for (i = 0; i < dflow->block_info_size; i++)
01693 {
01694 struct df_lr_bb_info *bb_info = df_lr_get_bb_info (dflow, i);
01695 if (bb_info)
01696 {
01697 BITMAP_FREE (bb_info->use);
01698 BITMAP_FREE (bb_info->def);
01699 BITMAP_FREE (bb_info->in);
01700 BITMAP_FREE (bb_info->out);
01701 }
01702 }
01703 free_alloc_pool (dflow->block_pool);
01704
01705 dflow->block_info_size = 0;
01706 free (dflow->block_info);
01707 }
01708
01709 free (dflow->problem_data);
01710 free (dflow);
01711 }
01712
01713
01714
01715
01716 static void
01717 df_lr_dump (struct dataflow *dflow, FILE *file)
01718 {
01719 basic_block bb;
01720
01721 if (!dflow->block_info)
01722 return;
01723
01724 fprintf (file, "Live Registers:\n");
01725 FOR_ALL_BB (bb)
01726 {
01727 struct df_lr_bb_info *bb_info = df_lr_get_bb_info (dflow, bb->index);
01728 df_print_bb_index (bb, file);
01729
01730 if (!bb_info->in)
01731 continue;
01732
01733 fprintf (file, " in \t");
01734 dump_bitmap (file, bb_info->in);
01735 fprintf (file, " use \t");
01736 dump_bitmap (file, bb_info->use);
01737 fprintf (file, " def \t");
01738 dump_bitmap (file, bb_info->def);
01739 fprintf (file, " out \t");
01740 dump_bitmap (file, bb_info->out);
01741 }
01742 }
01743
01744
01745
01746 static struct df_problem problem_LR =
01747 {
01748 DF_LR,
01749 DF_BACKWARD,
01750 df_lr_alloc,
01751 NULL,
01752 df_lr_free_bb_info,
01753 df_lr_local_compute,
01754 df_lr_init,
01755 df_iterative_dataflow,
01756 df_lr_confluence_0,
01757 df_lr_confluence_n,
01758 df_lr_transfer_function,
01759 NULL,
01760 df_lr_free,
01761 df_lr_dump,
01762 NULL,
01763 0
01764 };
01765
01766
01767
01768
01769
01770
01771 struct dataflow *
01772 df_lr_add_problem (struct df *df, int flags)
01773 {
01774 return df_add_problem (df, &problem_LR, flags);
01775 }
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790 struct df_ur_bb_info *
01791 df_ur_get_bb_info (struct dataflow *dflow, unsigned int index)
01792 {
01793 return (struct df_ur_bb_info *) dflow->block_info[index];
01794 }
01795
01796
01797
01798
01799 static void
01800 df_ur_set_bb_info (struct dataflow *dflow, unsigned int index,
01801 struct df_ur_bb_info *bb_info)
01802 {
01803 dflow->block_info[index] = bb_info;
01804 }
01805
01806
01807
01808
01809 static void
01810 df_ur_free_bb_info (struct dataflow *dflow,
01811 basic_block bb ATTRIBUTE_UNUSED,
01812 void *vbb_info)
01813 {
01814 struct df_ur_bb_info *bb_info = (struct df_ur_bb_info *) vbb_info;
01815 if (bb_info)
01816 {
01817 BITMAP_FREE (bb_info->gen);
01818 BITMAP_FREE (bb_info->kill);
01819 BITMAP_FREE (bb_info->in);
01820 BITMAP_FREE (bb_info->out);
01821 pool_free (dflow->block_pool, bb_info);
01822 }
01823 }
01824
01825
01826
01827
01828
01829 static void
01830 df_ur_alloc (struct dataflow *dflow, bitmap blocks_to_rescan,
01831 bitmap all_blocks ATTRIBUTE_UNUSED)
01832 {
01833 unsigned int bb_index;
01834 bitmap_iterator bi;
01835
01836 if (!dflow->block_pool)
01837 dflow->block_pool = create_alloc_pool ("df_ur_block pool",
01838 sizeof (struct df_ur_bb_info), 100);
01839
01840 df_grow_bb_info (dflow);
01841
01842 EXECUTE_IF_SET_IN_BITMAP (blocks_to_rescan, 0, bb_index, bi)
01843 {
01844 struct df_ur_bb_info *bb_info = df_ur_get_bb_info (dflow, bb_index);
01845 if (bb_info)
01846 {
01847 bitmap_clear (bb_info->kill);
01848 bitmap_clear (bb_info->gen);
01849 }
01850 else
01851 {
01852 bb_info = (struct df_ur_bb_info *) pool_alloc (dflow->block_pool);
01853 df_ur_set_bb_info (dflow, bb_index, bb_info);
01854 bb_info->kill = BITMAP_ALLOC (NULL);
01855 bb_info->gen = BITMAP_ALLOC (NULL);
01856 bb_info->in = BITMAP_ALLOC (NULL);
01857 bb_info->out = BITMAP_ALLOC (NULL);
01858 }
01859 }
01860 }
01861
01862
01863
01864
01865 static void
01866 df_ur_bb_local_compute (struct dataflow *dflow, unsigned int bb_index)
01867 {
01868 struct df *df = dflow->df;
01869 basic_block bb = BASIC_BLOCK (bb_index);
01870 struct df_ur_bb_info *bb_info = df_ur_get_bb_info (dflow, bb_index);
01871 rtx insn;
01872 struct df_ref *def;
01873
01874 bitmap_clear (seen_in_block);
01875 bitmap_clear (seen_in_insn);
01876
01877 for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
01878 if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
01879 {
01880 unsigned int regno = DF_REF_REGNO (def);
01881 if (!bitmap_bit_p (seen_in_block, regno))
01882 {
01883 bitmap_set_bit (seen_in_block, regno);
01884 bitmap_set_bit (bb_info->gen, regno);
01885 }
01886 }
01887
01888 FOR_BB_INSNS_REVERSE (bb, insn)
01889 {
01890 unsigned int uid = INSN_UID (insn);
01891 if (!INSN_P (insn))
01892 continue;
01893
01894 for (def = DF_INSN_UID_DEFS (df, uid); def; def = def->next_ref)
01895 {
01896 unsigned int regno = DF_REF_REGNO (def);
01897
01898 if (!bitmap_bit_p (seen_in_block, regno))
01899 {
01900 bitmap_set_bit (seen_in_insn, regno);
01901
01902 if (DF_REF_FLAGS (def)
01903 & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))
01904 {
01905
01906
01907 if ((DF_REF_FLAGS (def) & DF_REF_MUST_CLOBBER)
01908 && (!DF_REF_FLAGS (def) & DF_REF_PARTIAL))
01909 bitmap_set_bit (bb_info->kill, regno);
01910 }
01911 else
01912 bitmap_set_bit (bb_info->gen, regno);
01913 }
01914 }
01915 bitmap_ior_into (seen_in_block, seen_in_insn);
01916 bitmap_clear (seen_in_insn);
01917 }
01918
01919 for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
01920 if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
01921 {
01922 unsigned int regno = DF_REF_REGNO (def);
01923 if (!bitmap_bit_p (seen_in_block, regno))
01924 {
01925 bitmap_set_bit (seen_in_block, regno);
01926 bitmap_set_bit (bb_info->gen, regno);
01927 }
01928 }
01929 }
01930
01931
01932
01933
01934 static void
01935 df_ur_local_compute (struct dataflow *dflow,
01936 bitmap all_blocks ATTRIBUTE_UNUSED,
01937 bitmap rescan_blocks)
01938 {
01939 unsigned int bb_index;
01940 bitmap_iterator bi;
01941
01942 df_set_seen ();
01943
01944 EXECUTE_IF_SET_IN_BITMAP (rescan_blocks, 0, bb_index, bi)
01945 {
01946 df_ur_bb_local_compute (dflow, bb_index);
01947 }
01948
01949 df_unset_seen ();
01950 }
01951
01952
01953
01954
01955 static void
01956 df_ur_init (struct dataflow *dflow, bitmap all_blocks)
01957 {
01958 unsigned int bb_index;
01959 bitmap_iterator bi;
01960
01961 EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
01962 {
01963 struct df_ur_bb_info *bb_info = df_ur_get_bb_info (dflow, bb_index);
01964
01965 bitmap_copy (bb_info->out, bb_info->gen);
01966 bitmap_clear (bb_info->in);
01967 }
01968 }
01969
01970
01971
01972
01973
01974 static void
01975 df_ur_local_finalize (struct dataflow *dflow, bitmap all_blocks)
01976 {
01977 struct df *df = dflow->df;
01978 struct dataflow *lr_dflow = df->problems_by_index[DF_LR];
01979 bitmap tmp = BITMAP_ALLOC (NULL);
01980 bitmap_iterator bi;
01981 unsigned int bb_index;
01982
01983 EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
01984 {
01985 struct df_ur_bb_info *bb_info = df_ur_get_bb_info (dflow, bb_index);
01986 struct df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (lr_dflow, bb_index);
01987
01988
01989
01990 bitmap_and_into (bb_info->in, bb_lr_info->in);
01991 bitmap_and_into (bb_info->out, bb_lr_info->out);
01992
01993 #if 1
01994
01995
01996
01997
01998
01999
02000 bitmap_ior_and_compl (tmp, bb_info->gen, bb_lr_info->in,
02001 bb_info->kill);
02002 bitmap_and_into (bb_info->out, tmp);
02003 #endif
02004 }
02005
02006 BITMAP_FREE (tmp);
02007 }
02008
02009
02010
02011
02012 static void
02013 df_ur_confluence_n (struct dataflow *dflow, edge e)
02014 {
02015 bitmap op1 = df_ur_get_bb_info (dflow, e->dest->index)->in;
02016 bitmap op2 = df_ur_get_bb_info (dflow, e->src->index)->out;
02017
02018 if (e->flags & EDGE_FAKE)
02019 return;
02020
02021 bitmap_ior_into (op1, op2);
02022 }
02023
02024
02025
02026
02027 static bool
02028 df_ur_transfer_function (struct dataflow *dflow, int bb_index)
02029 {
02030 struct df_ur_bb_info *bb_info = df_ur_get_bb_info (dflow, bb_index);
02031 bitmap in = bb_info->in;
02032 bitmap out = bb_info->out;
02033 bitmap gen = bb_info->gen;
02034 bitmap kill = bb_info->kill;
02035
02036 return bitmap_ior_and_compl (out, gen, in, kill);
02037 }
02038
02039
02040
02041
02042 static void
02043 df_ur_free (struct dataflow *dflow)
02044 {
02045 if (dflow->block_info)
02046 {
02047 unsigned int i;
02048
02049 for (i = 0; i < dflow->block_info_size; i++)
02050 {
02051 struct df_ur_bb_info *bb_info = df_ur_get_bb_info (dflow, i);
02052 if (bb_info)
02053 {
02054 BITMAP_FREE (bb_info->gen);
02055 BITMAP_FREE (bb_info->kill);
02056 BITMAP_FREE (bb_info->in);
02057 BITMAP_FREE (bb_info->out);
02058 }
02059 }
02060
02061 free_alloc_pool (dflow->block_pool);
02062 dflow->block_info_size = 0;
02063 free (dflow->block_info);
02064 }
02065 free (dflow);
02066 }
02067
02068
02069
02070
02071 static void
02072 df_ur_dump (struct dataflow *dflow, FILE *file)
02073 {
02074 basic_block bb;
02075
02076 if (!dflow->block_info)
02077 return;
02078
02079 fprintf (file, "Undefined regs:\n");
02080
02081 FOR_ALL_BB (bb)
02082 {
02083 struct df_ur_bb_info *bb_info = df_ur_get_bb_info (dflow, bb->index);
02084 df_print_bb_index (bb, file);
02085
02086 if (!bb_info->in)
02087 continue;
02088
02089 fprintf (file, " in \t");
02090 dump_bitmap (file, bb_info->in);
02091 fprintf (file, " gen \t");
02092 dump_bitmap (file, bb_info->gen);
02093 fprintf (file, " kill\t");
02094 dump_bitmap (file, bb_info->kill);
02095 fprintf (file, " out \t");
02096 dump_bitmap (file, bb_info->out);
02097 }
02098 }
02099
02100
02101
02102 static struct df_problem problem_UR =
02103 {
02104 DF_UR,
02105 DF_FORWARD,
02106 df_ur_alloc,
02107 NULL,
02108 df_ur_free_bb_info,
02109 df_ur_local_compute,
02110 df_ur_init,
02111 df_iterative_dataflow,
02112 NULL,
02113 df_ur_confluence_n,
02114 df_ur_transfer_function,
02115 df_ur_local_finalize,
02116 df_ur_free,
02117 df_ur_dump,
02118 df_lr_add_problem,
02119 0
02120 };
02121
02122
02123
02124
02125
02126
02127 struct dataflow *
02128 df_ur_add_problem (struct df *df, int flags)
02129 {
02130 return df_add_problem (df, &problem_UR, flags);
02131 }
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151 struct df_urec_problem_data
02152 {
02153 bool earlyclobbers_found;
02154
02155 #ifdef STACK_REGS
02156 bitmap stack_regs;
02157 #endif
02158 };
02159
02160
02161
02162
02163 struct df_urec_bb_info *
02164 df_urec_get_bb_info (struct dataflow *dflow, unsigned int index)
02165 {
02166 return (struct df_urec_bb_info *) dflow->block_info[index];
02167 }
02168
02169
02170
02171
02172 static void
02173 df_urec_set_bb_info (struct dataflow *dflow, unsigned int index,
02174 struct df_urec_bb_info *bb_info)
02175 {
02176 dflow->block_info[index] = bb_info;
02177 }
02178
02179
02180
02181
02182 static void
02183 df_urec_free_bb_info (struct dataflow *dflow,
02184 basic_block bb ATTRIBUTE_UNUSED,
02185 void *vbb_info)
02186 {
02187 struct df_urec_bb_info *bb_info = (struct df_urec_bb_info *) vbb_info;
02188 if (bb_info)
02189 {
02190 BITMAP_FREE (bb_info->gen);
02191 BITMAP_FREE (bb_info->kill);
02192 BITMAP_FREE (bb_info->in);
02193 BITMAP_FREE (bb_info->out);
02194 BITMAP_FREE (bb_info->earlyclobber);
02195 pool_free (dflow->block_pool, bb_info);
02196 }
02197 }
02198
02199
02200
02201
02202
02203 static void
02204 df_urec_alloc (struct dataflow *dflow, bitmap blocks_to_rescan,
02205 bitmap all_blocks ATTRIBUTE_UNUSED)
02206
02207 {
02208 unsigned int bb_index;
02209 bitmap_iterator bi;
02210 struct df_urec_problem_data *problem_data
02211 = (struct df_urec_problem_data *) dflow->problem_data;
02212
02213 if (!dflow->block_pool)
02214 dflow->block_pool = create_alloc_pool ("df_urec_block pool",
02215 sizeof (struct df_urec_bb_info), 50);
02216
02217 if (!dflow->problem_data)
02218 {
02219 problem_data = XNEW (struct df_urec_problem_data);
02220 dflow->problem_data = problem_data;
02221 }
02222 problem_data->earlyclobbers_found = false;
02223
02224 df_grow_bb_info (dflow);
02225
02226 EXECUTE_IF_SET_IN_BITMAP (blocks_to_rescan, 0, bb_index, bi)
02227 {
02228 struct df_urec_bb_info *bb_info = df_urec_get_bb_info (dflow, bb_index);
02229 if (bb_info)
02230 {
02231 bitmap_clear (bb_info->kill);
02232 bitmap_clear (bb_info->gen);
02233 bitmap_clear (bb_info->earlyclobber);
02234 }
02235 else
02236 {
02237 bb_info = (struct df_urec_bb_info *) pool_alloc (dflow->block_pool);
02238 df_urec_set_bb_info (dflow, bb_index, bb_info);
02239 bb_info->kill = BITMAP_ALLOC (NULL);
02240 bb_info->gen = BITMAP_ALLOC (NULL);
02241 bb_info->in = BITMAP_ALLOC (NULL);
02242 bb_info->out = BITMAP_ALLOC (NULL);
02243 bb_info->earlyclobber = BITMAP_ALLOC (NULL);
02244 }
02245 }
02246 }
02247
02248
02249
02250
02251
02252 static void
02253 df_urec_mark_reg_change (rtx reg, rtx setter, void *data)
02254 {
02255 int regno;
02256 int endregno;
02257 int i;
02258 struct df_urec_bb_info *bb_info = (struct df_urec_bb_info*) data;
02259
02260 if (GET_CODE (reg) == SUBREG)
02261 reg = SUBREG_REG (reg);
02262
02263 if (!REG_P (reg))
02264 return;
02265
02266
02267 endregno = regno = REGNO (reg);
02268 if (regno < FIRST_PSEUDO_REGISTER)
02269 {
02270 endregno +=hard_regno_nregs[regno][GET_MODE (reg)];
02271
02272 for (i = regno; i < endregno; i++)
02273 {
02274 bitmap_set_bit (bb_info->kill, i);
02275
02276 if (GET_CODE (setter) != CLOBBER)
02277 bitmap_set_bit (bb_info->gen, i);
02278 else
02279 bitmap_clear_bit (bb_info->gen, i);
02280 }
02281 }
02282 else
02283 {
02284 bitmap_set_bit (bb_info->kill, regno);
02285
02286 if (GET_CODE (setter) != CLOBBER)
02287 bitmap_set_bit (bb_info->gen, regno);
02288 else
02289 bitmap_clear_bit (bb_info->gen, regno);
02290 }
02291 }
02292
02293
02294
02295 static VEC(int,heap) *earlyclobber_regclass;
02296
02297
02298
02299
02300
02301 static bool
02302 df_urec_check_earlyclobber (rtx insn)
02303 {
02304 int opno;
02305 bool found = false;
02306
02307 extract_insn (insn);
02308
02309 VEC_truncate (int, earlyclobber_regclass, 0);
02310 for (opno = 0; opno < recog_data.n_operands; opno++)
02311 {
02312 char c;
02313 bool amp_p;
02314 int i;
02315 enum reg_class class;
02316 const char *p = recog_data.constraints[opno];
02317
02318 class = NO_REGS;
02319 amp_p = false;
02320 for (;;)
02321 {
02322 c = *p;
02323 switch (c)
02324 {
02325 case '=': case '+': case '?':
02326 case '#': case '!':
02327 case '*': case '%':
02328 case 'm': case '<': case '>': case 'V': case 'o':
02329 case 'E': case 'F': case 'G': case 'H':
02330 case 's': case 'i': case 'n':
02331 case 'I': case 'J': case 'K': case 'L':
02332 case 'M': case 'N': case 'O': case 'P':
02333 case 'X':
02334 case '0': case '1': case '2': case '3': case '4':
02335 case '5': case '6': case '7': case '8': case '9':
02336
02337 break;
02338
02339 case '&':
02340 amp_p = true;
02341 break;
02342 case '\0':
02343 case ',':
02344 if (amp_p && class != NO_REGS)
02345 {
02346 int rc;
02347
02348 found = true;
02349 for (i = 0;
02350 VEC_iterate (int, earlyclobber_regclass, i, rc);
02351 i++)
02352 {
02353 if (rc == (int) class)
02354 goto found_rc;
02355 }
02356
02357
02358
02359
02360 VEC_quick_push (int, earlyclobber_regclass, (int) class);
02361 found_rc:
02362 ;
02363 }
02364
02365 amp_p = false;
02366 class = NO_REGS;
02367 break;
02368
02369 case 'r':
02370 class = GENERAL_REGS;
02371 break;
02372
02373 default:
02374 class = REG_CLASS_FROM_CONSTRAINT (c, p);
02375 break;
02376 }
02377 if (c == '\0')
02378 break;
02379 p += CONSTRAINT_LEN (c, p);
02380 }
02381 }
02382
02383 return found;
02384 }
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398 static int
02399 df_urec_mark_reg_use_for_earlyclobber (rtx *x, void *data)
02400 {
02401 enum reg_class pref_class, alt_class;
02402 int i, regno;
02403 struct df_urec_bb_info *bb_info = (struct df_urec_bb_info*) data;
02404
02405 if (REG_P (*x) && REGNO (*x) >= FIRST_PSEUDO_REGISTER)
02406 {
02407 int rc;
02408
02409 regno = REGNO (*x);
02410 if (bitmap_bit_p (bb_info->kill, regno)
02411 || bitmap_bit_p (bb_info->gen, regno))
02412 return 0;
02413 pref_class = reg_preferred_class (regno);
02414 alt_class = reg_alternate_class (regno);
02415 for (i = 0; VEC_iterate (int, earlyclobber_regclass, i, rc); i++)
02416 {
02417 if (reg_classes_intersect_p (rc, pref_class)
02418 || (rc != NO_REGS
02419 && reg_classes_intersect_p (rc, alt_class)))
02420 {
02421 bitmap_set_bit (bb_info->earlyclobber, regno);
02422 break;
02423 }
02424 }
02425 }
02426 return 0;
02427 }
02428
02429
02430
02431
02432 static void
02433 df_urec_mark_reg_use_for_earlyclobber_1 (rtx *x, void *data)
02434 {
02435 for_each_rtx (x, df_urec_mark_reg_use_for_earlyclobber, data);
02436 }
02437
02438
02439
02440
02441 static void
02442 df_urec_bb_local_compute (struct dataflow *dflow, unsigned int bb_index)
02443 {
02444 struct df *df = dflow->df;
02445 basic_block bb = BASIC_BLOCK (bb_index);
02446 struct df_urec_bb_info *bb_info = df_urec_get_bb_info (dflow, bb_index);
02447 rtx insn;
02448 struct df_ref *def;
02449
02450 for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
02451 if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
02452 {
02453 unsigned int regno = DF_REF_REGNO (def);
02454 bitmap_set_bit (bb_info->gen, regno);
02455 }
02456
02457 FOR_BB_INSNS (bb, insn)
02458 {
02459 if (INSN_P (insn))
02460 {
02461 note_stores (PATTERN (insn), df_urec_mark_reg_change, bb_info);
02462 if (df_urec_check_earlyclobber (insn))
02463 {
02464 struct df_urec_problem_data *problem_data
02465 = (struct df_urec_problem_data *) dflow->problem_data;
02466 problem_data->earlyclobbers_found = true;
02467 note_uses (&PATTERN (insn),
02468 df_urec_mark_reg_use_for_earlyclobber_1, bb_info);
02469 }
02470 }
02471 }
02472
02473 for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
02474 if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
02475 {
02476 unsigned int regno = DF_REF_REGNO (def);
02477 bitmap_set_bit (bb_info->gen, regno);
02478 }
02479
02480 }
02481
02482
02483
02484
02485 static void
02486 df_urec_local_compute (struct dataflow *dflow,
02487 bitmap all_blocks ATTRIBUTE_UNUSED,
02488 bitmap rescan_blocks)
02489 {
02490 unsigned int bb_index;
02491 bitmap_iterator bi;
02492 #ifdef STACK_REGS
02493 int i;
02494 HARD_REG_SET zero, stack_hard_regs, used;
02495 struct df_urec_problem_data *problem_data
02496 = (struct df_urec_problem_data *) dflow->problem_data;
02497
02498
02499
02500
02501
02502
02503
02504
02505 CLEAR_HARD_REG_SET (zero);
02506 CLEAR_HARD_REG_SET (stack_hard_regs);
02507 for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
02508 SET_HARD_REG_BIT (stack_hard_regs, i);
02509 problem_data->stack_regs = BITMAP_ALLOC (NULL);
02510 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
02511 {
02512 COPY_HARD_REG_SET (used, reg_class_contents[reg_preferred_class (i)]);
02513 IOR_HARD_REG_SET (used, reg_class_contents[reg_alternate_class (i)]);
02514 AND_HARD_REG_SET (used, stack_hard_regs);
02515 GO_IF_HARD_REG_EQUAL (used, zero, skip);
02516 bitmap_set_bit (problem_data->stack_regs, i);
02517 skip:
02518 ;
02519 }
02520 #endif
02521
02522
02523
02524 earlyclobber_regclass = VEC_alloc (int, heap, N_REG_CLASSES);
02525
02526 EXECUTE_IF_SET_IN_BITMAP (rescan_blocks, 0, bb_index, bi)
02527 {
02528 df_urec_bb_local_compute (dflow, bb_index);
02529 }
02530
02531 VEC_free (int, heap, earlyclobber_regclass);
02532 }
02533
02534
02535
02536
02537 static void
02538 df_urec_init (struct dataflow *dflow, bitmap all_blocks)
02539 {
02540 unsigned int bb_index;
02541 bitmap_iterator bi;
02542
02543 EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
02544 {
02545 struct df_urec_bb_info *bb_info = df_urec_get_bb_info (dflow, bb_index);
02546
02547 bitmap_copy (bb_info->out, bb_info->gen);
02548 bitmap_clear (bb_info->in);
02549 }
02550 }
02551
02552
02553
02554
02555
02556 static void
02557 df_urec_local_finalize (struct dataflow *dflow, bitmap all_blocks)
02558 {
02559 struct df *df = dflow->df;
02560 struct dataflow *lr_dflow = df->problems_by_index[DF_LR];
02561 bitmap tmp = BITMAP_ALLOC (NULL);
02562 bitmap_iterator bi;
02563 unsigned int bb_index;
02564 struct df_urec_problem_data *problem_data
02565 = (struct df_urec_problem_data *) dflow->problem_data;
02566
02567 EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
02568 {
02569 struct df_urec_bb_info *bb_info = df_urec_get_bb_info (dflow, bb_index);
02570 struct df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (lr_dflow, bb_index);
02571
02572 if (bb_index != ENTRY_BLOCK && bb_index != EXIT_BLOCK)
02573 {
02574 if (problem_data->earlyclobbers_found)
02575 bitmap_ior_into (bb_info->in, bb_info->earlyclobber);
02576
02577 #ifdef STACK_REGS
02578
02579
02580
02581
02582
02583 bitmap_ior_into (bb_info->in, problem_data->stack_regs);
02584 bitmap_ior_into (bb_info->out, problem_data->stack_regs);
02585 #endif
02586 }
02587
02588
02589
02590 bitmap_and_into (bb_info->in, bb_lr_info->in);
02591 bitmap_and_into (bb_info->out, bb_lr_info->out);
02592
02593 #if 1
02594
02595
02596
02597
02598
02599
02600 bitmap_ior_and_compl (tmp, bb_info->gen, bb_lr_info->in,
02601 bb_info->kill);
02602 bitmap_and_into (bb_info->out, tmp);
02603 #endif
02604 }
02605
02606 #ifdef STACK_REGS
02607 BITMAP_FREE (problem_data->stack_regs);
02608 #endif
02609 BITMAP_FREE (tmp);
02610 }
02611
02612
02613
02614
02615 static void
02616 df_urec_confluence_n (struct dataflow *dflow, edge e)
02617 {
02618 bitmap op1 = df_urec_get_bb_info (dflow, e->dest->index)->in;
02619 bitmap op2 = df_urec_get_bb_info (dflow, e->src->index)->out;
02620
02621 if (e->flags & EDGE_FAKE)
02622 return;
02623
02624 bitmap_ior_into (op1, op2);
02625 }
02626
02627
02628
02629
02630 static bool
02631 df_urec_transfer_function (struct dataflow *dflow, int bb_index)
02632 {
02633 struct df_urec_bb_info *bb_info = df_urec_get_bb_info (dflow, bb_index);
02634 bitmap in = bb_info->in;
02635 bitmap out = bb_info->out;
02636 bitmap gen = bb_info->gen;
02637 bitmap kill = bb_info->kill;
02638
02639 return bitmap_ior_and_compl (out, gen, in, kill);
02640 }
02641
02642
02643
02644
02645 static void
02646 df_urec_free (struct dataflow *dflow)
02647 {
02648 if (dflow->block_info)
02649 {
02650 unsigned int i;
02651
02652 for (i = 0; i < dflow->block_info_size; i++)
02653 {
02654 struct df_urec_bb_info *bb_info = df_urec_get_bb_info (dflow, i);
02655 if (bb_info)
02656 {
02657 BITMAP_FREE (bb_info->gen);
02658 BITMAP_FREE (bb_info->kill);
02659 BITMAP_FREE (bb_info->in);
02660 BITMAP_FREE (bb_info->out);
02661 BITMAP_FREE (bb_info->earlyclobber);
02662 }
02663 }
02664
02665 free_alloc_pool (dflow->block_pool);
02666
02667 dflow->block_info_size = 0;
02668 free (dflow->block_info);
02669 free (dflow->problem_data);
02670 }
02671 free (dflow);
02672 }
02673
02674
02675
02676
02677 static void
02678 df_urec_dump (struct dataflow *dflow, FILE *file)
02679 {
02680 basic_block bb;
02681
02682 if (!dflow->block_info)
02683 return;
02684
02685 fprintf (file, "Undefined regs:\n");
02686
02687 FOR_ALL_BB (bb)
02688 {
02689 struct df_urec_bb_info *bb_info = df_urec_get_bb_info (dflow, bb->index);
02690 df_print_bb_index (bb, file);
02691
02692 if (!bb_info->in)
02693 continue;
02694
02695 fprintf (file, " in \t");
02696 dump_bitmap (file, bb_info->in);
02697 fprintf (file, " gen \t");
02698 dump_bitmap (file, bb_info->gen);
02699 fprintf (file, " kill\t");
02700 dump_bitmap (file, bb_info->kill);
02701 fprintf (file, " ec\t");
02702 dump_bitmap (file, bb_info->earlyclobber);
02703 fprintf (file, " out \t");
02704 dump_bitmap (file, bb_info->out);
02705 }
02706 }
02707
02708
02709
02710 static struct df_problem problem_UREC =
02711 {
02712 DF_UREC,
02713 DF_FORWARD,
02714 df_urec_alloc,
02715 NULL,
02716 df_urec_free_bb_info,
02717 df_urec_local_compute,
02718 df_urec_init,
02719 df_iterative_dataflow,
02720 NULL,
02721 df_urec_confluence_n,
02722 df_urec_transfer_function,
02723 df_urec_local_finalize,
02724 df_urec_free,
02725 df_urec_dump,
02726 df_lr_add_problem,
02727 0
02728 };
02729
02730
02731
02732
02733
02734
02735 struct dataflow *
02736 df_urec_add_problem (struct df *df, int flags)
02737 {
02738 return df_add_problem (df, &problem_UREC, flags);
02739 }
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750
02751
02752
02753
02754
02755
02756 static void
02757 df_chain_alloc (struct dataflow *dflow,
02758 bitmap blocks_to_rescan ATTRIBUTE_UNUSED,
02759 bitmap all_blocks ATTRIBUTE_UNUSED)
02760
02761 {
02762 struct df *df = dflow->df;
02763 unsigned int i;
02764
02765
02766 if (dflow->block_pool)
02767 free_alloc_pool (dflow->block_pool);
02768
02769 dflow->block_pool = create_alloc_pool ("df_chain_chain_block pool",
02770 sizeof (struct df_link), 100);
02771
02772 if (dflow->flags & DF_DU_CHAIN)
02773 {
02774 if (!df->def_info.refs_organized)
02775 df_reorganize_refs (&df->def_info);
02776
02777
02778 for (i = 0; i < DF_DEFS_SIZE (df); i++)
02779 {
02780 struct df_ref *ref = df->def_info.refs[i];
02781 DF_REF_CHAIN (ref) = NULL;
02782 }
02783 }
02784
02785 if (dflow->flags & DF_UD_CHAIN)
02786 {
02787 if (!df->use_info.refs_organized)
02788 df_reorganize_refs (&df->use_info);
02789 for (i = 0; i < DF_USES_SIZE (df); i++)
02790 {
02791 struct df_ref *ref = df->use_info.refs[i];
02792 DF_REF_CHAIN (ref) = NULL;
02793 }
02794 }
02795 }
02796
02797
02798
02799
02800 static void
02801 df_chain_insn_reset (struct dataflow *dflow, rtx insn)
02802 {
02803 struct df *df = dflow->df;
02804 unsigned int uid = INSN_UID (insn);
02805 struct df_insn_info *insn_info = NULL;
02806 struct df_ref *ref;
02807
02808 if (uid < df->insns_size)
02809 insn_info = DF_INSN_UID_GET (df, uid);
02810
02811 if (insn_info)
02812 {
02813 if (dflow->flags & DF_DU_CHAIN)
02814 {
02815 ref = insn_info->defs;
02816 while (ref)
02817 {
02818 ref->chain = NULL;
02819 ref = ref->next_ref;
02820 }
02821 }
02822
02823 if (dflow->flags & DF_UD_CHAIN)
02824 {
02825 ref = insn_info->uses;
02826 while (ref)
02827 {
02828 ref->chain = NULL;
02829 ref = ref->next_ref;
02830 }
02831 }
02832 }
02833 }
02834
02835
02836
02837
02838 static void
02839 df_chain_bb_reset (struct dataflow *dflow, unsigned int bb_index)
02840 {
02841 struct df *df = dflow->df;
02842 rtx insn;
02843 basic_block bb = BASIC_BLOCK (bb_index);
02844
02845
02846 if (!bb)
02847 return;
02848
02849 FOR_BB_INSNS (bb, insn)
02850 {
02851 if (INSN_P (insn))
02852 {
02853
02854 df_chain_insn_reset (dflow, insn);
02855 }
02856 }
02857
02858
02859 if (dflow->flags & DF_DU_CHAIN)
02860 {
02861 struct df_ref *def;
02862 def = df_get_artificial_defs (df, bb_index);
02863 while (def)
02864 {
02865 def->chain = NULL;
02866 def = def->next_ref;
02867 }
02868 }
02869
02870 if (dflow->flags & DF_UD_CHAIN)
02871 {
02872 struct df_ref *use;
02873 use = df_get_artificial_uses (df, bb_index);
02874 while (use)
02875 {
02876 use->chain = NULL;
02877 use = use->next_ref;
02878 }
02879 }
02880 }
02881
02882
02883
02884
02885
02886 static void
02887 df_chain_reset (struct dataflow *dflow, bitmap blocks_to_clear)
02888 {
02889 bitmap_iterator bi;
02890 unsigned int bb_index;
02891
02892 EXECUTE_IF_SET_IN_BITMAP (blocks_to_clear, 0, bb_index, bi)
02893 {
02894 df_chain_bb_reset (dflow, bb_index);
02895 }
02896
02897 free_alloc_pool (dflow->block_pool);
02898 dflow->block_pool = NULL;
02899 }
02900
02901
02902
02903
02904 static void
02905 df_chain_create_bb_process_use (struct dataflow *dflow,
02906 bitmap local_rd,
02907 struct df_ref *use,
02908 enum df_ref_flags top_flag)
02909 {
02910 struct df *df = dflow->df;
02911 bitmap_iterator bi;
02912 unsigned int def_index;
02913
02914 while (use)
02915 {
02916
02917 unsigned int uregno = DF_REF_REGNO (use);
02918 int count = DF_REG_DEF_GET (df, uregno)->n_refs;
02919 if (count)
02920 {
02921 if (top_flag == (DF_REF_FLAGS (use) & DF_REF_AT_TOP))
02922 {
02923 unsigned int first_index = DF_REG_DEF_GET (df, uregno)->begin;
02924 unsigned int last_index = first_index + count - 1;
02925
02926 EXECUTE_IF_SET_IN_BITMAP (local_rd, first_index, def_index, bi)
02927 {
02928 struct df_ref *def;
02929 if (def_index > last_index)
02930 break;
02931
02932 def = DF_DEFS_GET (df, def_index);
02933 if (dflow->flags & DF_DU_CHAIN)
02934 df_chain_create (dflow, def, use);
02935 if (dflow->flags & DF_UD_CHAIN)
02936 df_chain_create (dflow, use, def);
02937 }
02938 }
02939 }
02940 use = use->next_ref;
02941 }
02942 }
02943
02944
02945
02946
02947
02948
02949 static void
02950 df_chain_create_bb (struct dataflow *dflow,
02951 struct dataflow *rd_dflow,
02952 unsigned int bb_index)
02953 {
02954 basic_block bb = BASIC_BLOCK (bb_index);
02955 struct df_rd_bb_info *bb_info = df_rd_get_bb_info (rd_dflow, bb_index);
02956 rtx insn;
02957 bitmap cpy = BITMAP_ALLOC (NULL);
02958 struct df *df = dflow->df;
02959 struct df_ref *def;
02960
02961 bitmap_copy (cpy, bb_info->in);
02962
02963
02964
02965
02966 #ifdef EH_USES
02967
02968
02969 df_chain_create_bb_process_use (dflow, cpy,
02970 df_get_artificial_uses (df, bb->index),
02971 DF_REF_AT_TOP);
02972 #endif
02973
02974 for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
02975 if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
02976 {
02977 unsigned int dregno = DF_REF_REGNO (def);
02978 if (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL))
02979 bitmap_clear_range (cpy,
02980 DF_REG_DEF_GET (df, dregno)->begin,
02981 DF_REG_DEF_GET (df, dregno)->n_refs);
02982 bitmap_set_bit (cpy, DF_REF_ID (def));
02983 }
02984
02985
02986 FOR_BB_INSNS (bb, insn)
02987 {
02988 struct df_ref *def;
02989 unsigned int uid = INSN_UID (insn);
02990
02991 if (!INSN_P (insn))
02992 continue;
02993
02994
02995
02996
02997 df_chain_create_bb_process_use (dflow, cpy,
02998 DF_INSN_UID_USES (df, uid), 0);
02999
03000
03001
03002 for (def = DF_INSN_UID_DEFS (df, uid); def; def = def->next_ref)
03003 {
03004 unsigned int dregno = DF_REF_REGNO (def);
03005 if (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL))
03006 bitmap_clear_range (cpy,
03007 DF_REG_DEF_GET (df, dregno)->begin,
03008 DF_REG_DEF_GET (df, dregno)->n_refs);
03009 if (!(DF_REF_FLAGS (def)
03010 & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
03011 bitmap_set_bit (cpy, DF_REF_ID (def));
03012 }
03013 }
03014
03015
03016
03017 df_chain_create_bb_process_use (dflow, cpy,
03018 df_get_artificial_uses (df, bb->index), 0);
03019 }
03020
03021
03022
03023
03024 static void
03025 df_chain_finalize (struct dataflow *dflow, bitmap all_blocks)
03026 {
03027 unsigned int bb_index;
03028 bitmap_iterator bi;
03029 struct df *df = dflow->df;
03030 struct dataflow *rd_dflow = df->problems_by_index [DF_RD];
03031
03032 EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
03033 {
03034 df_chain_create_bb (dflow, rd_dflow, bb_index);
03035 }
03036 }
03037
03038
03039
03040
03041 static void
03042 df_chain_free (struct dataflow *dflow)
03043 {
03044 free_alloc_pool (dflow->block_pool);
03045 free (dflow);
03046 }
03047
03048
03049
03050
03051 static void
03052 df_chains_dump (struct dataflow *dflow, FILE *file)
03053 {
03054 struct df *df = dflow->df;
03055 unsigned int j;
03056
03057 if (dflow->flags & DF_DU_CHAIN)
03058 {
03059 fprintf (file, "Def-use chains:\n");
03060 for (j = 0; j < df->def_info.bitmap_size; j++)
03061 {
03062 struct df_ref *def = DF_DEFS_GET (df, j);
03063 if (def)
03064 {
03065 fprintf (file, "d%d bb %d luid %d insn %d reg %d ",
03066 j, DF_REF_BBNO (def),
03067 DF_REF_INSN (def) ?
03068 DF_INSN_LUID (df, DF_REF_INSN (def)):
03069 -1,
03070 DF_REF_INSN (def) ? DF_REF_INSN_UID (def) : -1,
03071 DF_REF_REGNO (def));
03072 if (def->flags & DF_REF_READ_WRITE)
03073 fprintf (file, "read/write ");
03074 df_chain_dump (DF_REF_CHAIN (def), file);
03075 fprintf (file, "\n");
03076 }
03077 }
03078 }
03079
03080 if (dflow->flags & DF_UD_CHAIN)
03081 {
03082 fprintf (file, "Use-def chains:\n");
03083 for (j = 0; j < df->use_info.bitmap_size; j++)
03084 {
03085 struct df_ref *use = DF_USES_GET (df, j);
03086 if (use)
03087 {
03088 fprintf (file, "u%d bb %d luid %d insn %d reg %d ",
03089 j, DF_REF_BBNO (use),
03090 DF_REF_INSN (use) ?
03091 DF_INSN_LUID (df, DF_REF_INSN (use))
03092 : -1,
03093 DF_REF_INSN (DF_USES_GET (df, j)) ?
03094 DF_REF_INSN_UID (DF_USES_GET (df,j))
03095 : -1,
03096 DF_REF_REGNO (use));
03097 if (use->flags & DF_REF_READ_WRITE)
03098 fprintf (file, "read/write ");
03099 if (use->flags & DF_REF_STRIPPED)
03100 fprintf (file, "stripped ");
03101 if (use->flags & DF_REF_IN_NOTE)
03102 fprintf (file, "note ");
03103 df_chain_dump (DF_REF_CHAIN (use), file);
03104 fprintf (file, "\n");
03105 }
03106 }
03107 }
03108 }
03109
03110
03111 static struct df_problem problem_CHAIN =
03112 {
03113 DF_CHAIN,
03114 DF_NONE,
03115 df_chain_alloc,
03116 df_chain_reset,
03117 NULL,
03118 NULL,
03119 NULL,
03120 NULL,
03121 NULL,
03122 NULL,
03123 NULL,
03124 df_chain_finalize,
03125 df_chain_free,
03126 df_chains_dump,
03127 df_rd_add_problem,
03128 0
03129 };
03130
03131
03132
03133
03134
03135
03136 struct dataflow *
03137 df_chain_add_problem (struct df *df, int flags)
03138 {
03139 return df_add_problem (df, &problem_CHAIN, flags);
03140 }
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155 #ifdef REG_DEAD_DEBUGGING
03156 static void
03157 print_note (char *prefix, rtx insn, rtx note)
03158 {
03159 fprintf (stderr, "%s %d ", prefix, INSN_UID (insn));
03160 print_rtl (stderr, note);
03161 fprintf (stderr, "\n");
03162 }
03163 #endif
03164
03165
03166
03167 static void
03168 df_ri_alloc (struct dataflow *dflow,
03169 bitmap blocks_to_rescan ATTRIBUTE_UNUSED,
03170 bitmap all_blocks ATTRIBUTE_UNUSED)
03171 {
03172 int i;
03173 struct df *df = dflow->df;
03174
03175 if (dflow->flags & DF_RI_LIFE)
03176 {
03177 max_regno = max_reg_num ();
03178 allocate_reg_info (max_regno, FALSE, FALSE);
03179
03180
03181 for (i = 0; i < max_regno; i++)
03182 {
03183 REG_N_SETS (i) = DF_REG_DEF_COUNT (df, i);
03184 REG_N_REFS (i) = DF_REG_USE_COUNT (df, i) + REG_N_SETS (i);
03185 REG_N_DEATHS (i) = 0;
03186 REG_N_CALLS_CROSSED (i) = 0;
03187 REG_N_THROWING_CALLS_CROSSED (i) = 0;
03188 REG_LIVE_LENGTH (i) = 0;
03189 REG_FREQ (i) = 0;
03190 REG_BASIC_BLOCK (i) = REG_BLOCK_UNKNOWN;
03191 }
03192 }
03193 }
03194
03195
03196
03197
03198
03199
03200 static inline bool
03201 df_ignore_stack_reg (int regno ATTRIBUTE_UNUSED)
03202 {
03203 #ifdef STACK_REGS
03204 return (regstack_completed
03205 && IN_RANGE (regno, FIRST_STACK_REG, LAST_STACK_REG));
03206 #else
03207 return false;
03208 #endif
03209 }
03210
03211
03212
03213
03214 static void
03215 df_kill_notes (rtx insn, int flags)
03216 {
03217 rtx *pprev = ®_NOTES (insn);
03218 rtx link = *pprev;
03219
03220 while (link)
03221 {
03222 switch (REG_NOTE_KIND (link))
03223 {
03224 case REG_DEAD:
03225 if (flags & DF_RI_LIFE)
03226 if (df_ignore_stack_reg (REGNO (XEXP (link, 0))))
03227 REG_N_DEATHS (REGNO (XEXP (link, 0)))++;
03228
03229
03230 case REG_UNUSED:
03231 if (!df_ignore_stack_reg (REGNO (XEXP (link, 0))))
03232 {
03233 rtx next = XEXP (link, 1);
03234 #ifdef REG_DEAD_DEBUGGING
03235 print_note ("deleting: ", insn, link);
03236 #endif
03237 free_EXPR_LIST_node (link);
03238 *pprev = link = next;
03239 }
03240 break;
03241
03242 default:
03243 pprev = &XEXP (link, 1);
03244 link = *pprev;
03245 break;
03246 }
03247 }
03248 }
03249
03250
03251
03252
03253
03254
03255
03256
03257
03258 static void
03259 df_set_unused_notes_for_mw (rtx insn, struct df_mw_hardreg *mws,
03260 bitmap live, bitmap do_not_gen,
03261 bitmap artificial_uses, int flags)
03262 {
03263 bool all_dead = true;
03264 struct df_link *regs = mws->regs;
03265 unsigned int regno = DF_REF_REGNO (regs->ref);
03266
03267 #ifdef REG_DEAD_DEBUGGING
03268 fprintf (stderr, "mw unused looking at %d\n", DF_REF_REGNO (regs->ref));
03269 df_ref_debug (regs->ref, stderr);
03270 #endif
03271 while (regs)
03272 {
03273 unsigned int regno = DF_REF_REGNO (regs->ref);
03274 if ((bitmap_bit_p (live, regno))
03275 || bitmap_bit_p (artificial_uses, regno))
03276 {
03277 all_dead = false;
03278 break;
03279 }
03280 regs = regs->next;
03281 }
03282
03283 if (all_dead)
03284 {
03285 struct df_link *regs = mws->regs;
03286 rtx note = alloc_EXPR_LIST (REG_UNUSED, *DF_REF_LOC (regs->ref),
03287 REG_NOTES (insn));
03288 REG_NOTES (insn) = note;
03289 #ifdef REG_DEAD_DEBUGGING
03290 print_note ("adding 1: ", insn, note);
03291 #endif
03292 bitmap_set_bit (do_not_gen, regno);
03293
03294 if (flags & DF_RI_LIFE)
03295 {
03296 REG_N_DEATHS (regno) ++;
03297 REG_LIVE_LENGTH (regno)++;
03298 }
03299 }
03300 else
03301 {
03302 struct df_link *regs = mws->regs;
03303 while (regs)
03304 {
03305 struct df_ref *ref = regs->ref;
03306
03307 regno = DF_REF_REGNO (ref);
03308 if ((!bitmap_bit_p (live, regno))
03309 && (!bitmap_bit_p (artificial_uses, regno)))
03310 {
03311 rtx note = alloc_EXPR_LIST (REG_UNUSED, regno_reg_rtx[regno],
03312 REG_NOTES (insn));
03313 REG_NOTES (insn) = note;
03314 #ifdef REG_DEAD_DEBUGGING
03315 print_note ("adding 2: ", insn, note);
03316 #endif
03317 }
03318 bitmap_set_bit (do_not_gen, regno);
03319 regs = regs->next;
03320 }
03321 }
03322 }
03323
03324
03325
03326
03327
03328
03329
03330 static void
03331 df_set_dead_notes_for_mw (rtx insn, struct df_mw_hardreg *mws,
03332 bitmap live, bitmap do_not_gen,
03333 bitmap artificial_uses, int flags)
03334 {
03335 bool all_dead = true;
03336 struct df_link *regs = mws->regs;
03337 unsigned int regno = DF_REF_REGNO (regs->ref);
03338
03339 #ifdef REG_DEAD_DEBUGGING
03340 fprintf (stderr, "mw looking at %d\n", DF_REF_REGNO (regs->ref));
03341 df_ref_debug (regs->ref, stderr);
03342 #endif
03343 while (regs)
03344 {
03345 unsigned int regno = DF_REF_REGNO (regs->ref);
03346 if ((bitmap_bit_p (live, regno))
03347 || bitmap_bit_p (artificial_uses, regno))
03348 {
03349 all_dead = false;
03350 break;
03351 }
03352 regs = regs->next;
03353 }
03354
03355 if (all_dead)
03356 {
03357 if (!bitmap_bit_p (do_not_gen, regno))
03358 {
03359
03360 struct df_link *regs = mws->regs;
03361 rtx note = alloc_EXPR_LIST (REG_DEAD, *DF_REF_LOC (regs->ref),
03362 REG_NOTES (insn));
03363 REG_NOTES (insn) = note;
03364 #ifdef REG_DEAD_DEBUGGING
03365 print_note ("adding 1: ", insn, note);
03366 #endif
03367
03368 if (flags & DF_RI_LIFE)
03369 {
03370 struct df_link *regs = mws->regs;
03371 while (regs)
03372 {
03373 struct df_ref *ref = regs->ref;
03374 regno = DF_REF_REGNO (ref);
03375 REG_N_DEATHS (regno)++;
03376 regs = regs->next;
03377 }
03378 }
03379 }
03380 }
03381 else
03382 {
03383 struct df_link *regs = mws->regs;
03384 while (regs)
03385 {
03386 struct df_ref *ref = regs->ref;
03387
03388 regno = DF_REF_REGNO (ref);
03389 if ((!bitmap_bit_p (live, regno))
03390 && (!bitmap_bit_p (artificial_uses, regno))
03391 && (!bitmap_bit_p (do_not_gen, regno)))
03392 {
03393 rtx note = alloc_EXPR_LIST (REG_DEAD, regno_reg_rtx[regno],
03394 REG_NOTES (insn));
03395 REG_NOTES (insn) = note;
03396 if (flags & DF_RI_LIFE)
03397 REG_N_DEATHS (regno)++;
03398 #ifdef REG_DEAD_DEBUGGING
03399 print_note ("adding 2: ", insn, note);
03400 #endif
03401 }
03402
03403 regs = regs->next;
03404 }
03405 }
03406 }
03407
03408
03409
03410
03411
03412
03413 static void
03414 df_create_unused_note (basic_block bb, rtx insn, struct df_ref *def,
03415 bitmap live, bitmap do_not_gen, bitmap artificial_uses,
03416 bitmap local_live, bitmap local_processed,
03417 int flags, int luid)
03418 {
03419 unsigned int dregno = DF_REF_REGNO (def);
03420
03421 #ifdef REG_DEAD_DEBUGGING
03422 fprintf (stderr, " regular looking at def ");
03423 df_ref_debug (def, stderr);
03424 #endif
03425
03426 if (bitmap_bit_p (live, dregno))
03427 {
03428 if (flags & DF_RI_LIFE)
03429 {
03430
03431
03432
03433
03434 if (bitmap_bit_p (local_processed, dregno))
03435 {
03436 if (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL))
03437 bitmap_clear_bit (local_live, dregno);
03438 }
03439 else
03440 {
03441 bitmap_set_bit (local_processed, dregno);
03442 REG_LIVE_LENGTH (dregno) += luid;
03443 }
03444 }
03445 }
03446 else if ((!(DF_REF_FLAGS (def) & DF_REF_MW_HARDREG))
03447 && (!bitmap_bit_p (artificial_uses, dregno))
03448 && (!df_ignore_stack_reg (dregno)))
03449 {
03450 rtx reg = GET_CODE (*DF_REF_LOC (def)) == SUBREG ?
03451 SUBREG_REG (*DF_REF_LOC (def)) : *DF_REF_LOC (def);
03452 rtx note = alloc_EXPR_LIST (REG_UNUSED, reg, REG_NOTES (insn));
03453 REG_NOTES (insn) = note;
03454 #ifdef REG_DEAD_DEBUGGING
03455 print_note ("adding 3: ", insn, note);
03456 #endif
03457 if (flags & DF_RI_LIFE)
03458 {
03459 REG_N_DEATHS (dregno) ++;
03460 REG_LIVE_LENGTH (dregno)++;
03461 }
03462 }
03463
03464 if ((flags & DF_RI_LIFE) && (dregno >= FIRST_PSEUDO_REGISTER))
03465 {
03466 REG_FREQ (dregno) += REG_FREQ_FROM_BB (bb);
03467 if (REG_BASIC_BLOCK (dregno) == REG_BLOCK_UNKNOWN)
03468 REG_BASIC_BLOCK (dregno) = bb->index;
03469 else if (REG_BASIC_BLOCK (dregno) != bb->index)
03470 REG_BASIC_BLOCK (dregno) = REG_BLOCK_GLOBAL;
03471 }
03472
03473 if (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER + DF_REF_MAY_CLOBBER)))
03474 bitmap_set_bit (do_not_gen, dregno);
03475
03476
03477 if (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL))
03478 bitmap_clear_bit (live, dregno);
03479 }
03480
03481
03482
03483
03484
03485
03486 static void
03487 df_ri_bb_compute (struct dataflow *dflow, unsigned int bb_index,
03488 bitmap live, bitmap do_not_gen, bitmap artificial_uses,
03489 bitmap local_live, bitmap local_processed, bitmap setjumps_crossed)
03490 {
03491 struct df *df = dflow->df;
03492 basic_block bb = BASIC_BLOCK (bb_index);
03493 rtx insn;
03494 struct df_ref *def;
03495 struct df_ref *use;
03496 int luid = 0;
03497
03498 bitmap_copy (live, df_get_live_out (df, bb));
03499 bitmap_clear (artificial_uses);
03500
03501 if (dflow->flags & DF_RI_LIFE)
03502 {
03503
03504
03505 bitmap_iterator bi;
03506 unsigned int regno;
03507 EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
03508 REG_BASIC_BLOCK (regno) = REG_BLOCK_GLOBAL;
03509 }
03510
03511
03512
03513 for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
03514 if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
03515 bitmap_clear_bit (live, DF_REF_REGNO (def));
03516
03517 for (use = df_get_artificial_uses (df, bb_index); use; use = use->next_ref)
03518 if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
03519 {
03520 unsigned int regno = DF_REF_REGNO (use);
03521 bitmap_set_bit (live, regno);
03522
03523
03524
03525 bitmap_set_bit (artificial_uses, regno);
03526 }
03527
03528 FOR_BB_INSNS_REVERSE (bb, insn)
03529 {
03530 unsigned int uid = INSN_UID (insn);
03531 unsigned int regno;
03532 bitmap_iterator bi;
03533 struct df_mw_hardreg *mws;
03534
03535 if (!INSN_P (insn))
03536 continue;
03537
03538 if (dflow->flags & DF_RI_LIFE)
03539 {
03540
03541
03542
03543 bitmap_iterator bi;
03544 unsigned int regno;
03545 EXECUTE_IF_SET_IN_BITMAP (local_live, 0, regno, bi)
03546 {
03547 REG_LIVE_LENGTH (regno)++;
03548 }
03549 luid++;
03550 }
03551
03552 bitmap_clear (do_not_gen);
03553 df_kill_notes (insn, dflow->flags);
03554
03555
03556 if (CALL_P (insn))
03557 {
03558 if (dflow->flags & DF_RI_LIFE)
03559 {
03560 bool can_throw = can_throw_internal (insn);
03561 bool set_jump = (find_reg_note (insn, REG_SETJMP, NULL) != NULL);
03562 EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
03563 {
03564 REG_N_CALLS_CROSSED (regno)++;
03565 if (can_throw)
03566 REG_N_THROWING_CALLS_CROSSED (regno)++;
03567
03568
03569
03570
03571
03572
03573
03574
03575
03576
03577
03578
03579 if (set_jump && regno >= FIRST_PSEUDO_REGISTER)
03580 bitmap_set_bit (setjumps_crossed, regno);
03581 }
03582 }
03583
03584
03585
03586 for (mws = DF_INSN_UID_MWS (df, uid); mws; mws = mws->next)
03587 {
03588 if ((mws->type == DF_REF_REG_DEF)
03589 && !df_ignore_stack_reg (REGNO (mws->mw_reg)))
03590 df_set_unused_notes_for_mw (insn, mws, live, do_not_gen,
03591 artificial_uses, dflow->flags);
03592 }
03593
03594
03595
03596 for (def = DF_INSN_UID_DEFS (df, uid); def; def = def->next_ref)
03597 if (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
03598 df_create_unused_note (bb, insn, def, live, do_not_gen,
03599 artificial_uses, local_live,
03600 local_processed, dflow->flags, luid);
03601
03602 }
03603 else
03604 {
03605
03606 for (mws = DF_INSN_UID_MWS (df, uid); mws; mws = mws->next)
03607 {
03608 if (mws->type == DF_REF_REG_DEF)
03609 df_set_unused_notes_for_mw (insn, mws, live, do_not_gen,
03610 artificial_uses, dflow->flags);
03611 }
03612
03613 for (def = DF_INSN_UID_DEFS (df, uid); def; def = def->next_ref)
03614 df_create_unused_note (bb, insn, def, live, do_not_gen,
03615 artificial_uses, local_live,
03616 local_processed, dflow->flags, luid);
03617 }
03618
03619
03620 for (mws = DF_INSN_UID_MWS (df, uid); mws; mws = mws->next)
03621 {
03622 if ((mws->type != DF_REF_REG_DEF)
03623 && !df_ignore_stack_reg (REGNO (mws->mw_reg)))
03624 df_set_dead_notes_for_mw (insn, mws, live, do_not_gen,
03625 artificial_uses, dflow->flags);
03626 }
03627
03628 for (use = DF_INSN_UID_USES (df, uid); use; use = use->next_ref)
03629 {
03630 unsigned int uregno = DF_REF_REGNO (use);
03631
03632 if ((dflow->flags & DF_RI_LIFE) && (uregno >= FIRST_PSEUDO_REGISTER))
03633 {
03634 REG_FREQ (uregno) += REG_FREQ_FROM_BB (bb);
03635 if (REG_BASIC_BLOCK (uregno) == REG_BLOCK_UNKNOWN)
03636 REG_BASIC_BLOCK (uregno) = bb->index;
03637 else if (REG_BASIC_BLOCK (uregno) != bb->index)
03638 REG_BASIC_BLOCK (uregno) = REG_BLOCK_GLOBAL;
03639 }
03640
03641 #ifdef REG_DEAD_DEBUGGING
03642 fprintf (stderr, " regular looking at use ");
03643 df_ref_debug (use, stderr);
03644 #endif
03645 if (!bitmap_bit_p (live, uregno))
03646 {
03647 if ( (!(DF_REF_FLAGS (use) & DF_REF_MW_HARDREG))
03648 && (!bitmap_bit_p (do_not_gen, uregno))
03649 && (!bitmap_bit_p (artificial_uses, uregno))
03650 && (!(DF_REF_FLAGS (use) & DF_REF_READ_WRITE))
03651 && (!df_ignore_stack_reg (uregno)))
03652 {
03653 rtx reg = GET_CODE (*DF_REF_LOC (use)) == SUBREG ?
03654 SUBREG_REG (*DF_REF_LOC (use)) : *DF_REF_LOC (use);
03655 rtx note = alloc_EXPR_LIST (REG_DEAD, reg, REG_NOTES (insn));
03656 REG_NOTES (insn) = note;
03657 if (dflow->flags & DF_RI_LIFE)
03658 REG_N_DEATHS (uregno)++;
03659
03660 #ifdef REG_DEAD_DEBUGGING
03661 print_note ("adding 4: ", insn, note);
03662 #endif
03663 }
03664
03665 bitmap_set_bit (live, uregno);
03666
03667 if (dflow->flags & DF_RI_LIFE)
03668 {
03669
03670
03671
03672
03673
03674
03675
03676
03677 REG_LIVE_LENGTH (uregno) ++;
03678 bitmap_set_bit (local_live, uregno);
03679 bitmap_set_bit (local_processed, uregno);
03680 }
03681 }
03682 }
03683 }
03684
03685 if (dflow->flags & DF_RI_LIFE)
03686 {
03687
03688
03689 bitmap_iterator bi;
03690 unsigned int regno;
03691 bitmap_and_compl_into (live, local_processed);
03692 EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
03693 {
03694 REG_LIVE_LENGTH (regno) += luid;
03695 }
03696 bitmap_clear (local_processed);
03697 bitmap_clear (local_live);
03698 }
03699 }
03700
03701
03702
03703 static void
03704 df_ri_compute (struct dataflow *dflow, bitmap all_blocks ATTRIBUTE_UNUSED,
03705 bitmap blocks_to_scan)
03706 {
03707 unsigned int bb_index;
03708 bitmap_iterator bi;
03709 bitmap live = BITMAP_ALLOC (NULL);
03710 bitmap do_not_gen = BITMAP_ALLOC (NULL);
03711 bitmap artificial_uses = BITMAP_ALLOC (NULL);
03712 bitmap local_live = NULL;
03713 bitmap local_processed = NULL;
03714 bitmap setjumps_crossed = NULL;
03715
03716 if (dflow->flags & DF_RI_LIFE)
03717 {
03718 local_live = BITMAP_ALLOC (NULL);
03719 local_processed = BITMAP_ALLOC (NULL);
03720 setjumps_crossed = BITMAP_ALLOC (NULL);
03721 }
03722
03723
03724 #ifdef REG_DEAD_DEBUGGING
03725 df_lr_dump (dflow->df->problems_by_index [DF_LR], stderr);
03726 print_rtl_with_bb (stderr, get_insns());
03727 #endif
03728
03729 EXECUTE_IF_SET_IN_BITMAP (blocks_to_scan, 0, bb_index, bi)
03730 {
03731 df_ri_bb_compute (dflow, bb_index, live, do_not_gen, artificial_uses,
03732 local_live, local_processed, setjumps_crossed);
03733 }
03734
03735 BITMAP_FREE (live);
03736 BITMAP_FREE (do_not_gen);
03737 BITMAP_FREE (artificial_uses);
03738 if (dflow->flags & DF_RI_LIFE)
03739 {
03740 bitmap_iterator bi;
03741 unsigned int regno;
03742
03743 EXECUTE_IF_SET_IN_BITMAP (setjumps_crossed, 0, regno, bi)
03744 {
03745 REG_BASIC_BLOCK (regno) = REG_BLOCK_UNKNOWN;
03746 REG_LIVE_LENGTH (regno) = -1;
03747 }
03748
03749 BITMAP_FREE (local_live);
03750 BITMAP_FREE (local_processed);
03751 BITMAP_FREE (setjumps_crossed);
03752 }
03753 }
03754
03755
03756
03757
03758 static void
03759 df_ri_free (struct dataflow *dflow)
03760 {
03761 free (dflow->problem_data);
03762 free (dflow);
03763 }
03764
03765
03766
03767
03768 static void
03769 df_ri_dump (struct dataflow *dflow, FILE *file)
03770 {
03771 print_rtl_with_bb (file, get_insns ());
03772
03773 if (dflow->flags & DF_RI_LIFE)
03774 {
03775 fprintf (file, "Register info:\n");
03776 dump_flow_info (file, -1);
03777 }
03778 }
03779
03780
03781
03782 static struct df_problem problem_RI =
03783 {
03784 DF_RI,
03785 DF_NONE,
03786 df_ri_alloc,
03787 NULL,
03788 NULL,
03789 df_ri_compute,
03790 NULL,
03791 NULL,
03792 NULL,
03793 NULL,
03794 NULL,
03795 NULL,
03796 df_ri_free,
03797 df_ri_dump,
03798
03799
03800
03801
03802 df_lr_add_problem,
03803 0
03804 };
03805
03806
03807
03808
03809
03810
03811 struct dataflow *
03812 df_ri_add_problem (struct df *df, int flags)
03813 {
03814 return df_add_problem (df, &problem_RI, flags);
03815 }