190075Sobrien/* Control flow graph manipulation code for GNU compiler. 290075Sobrien Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 3169689Skan 1999, 2000, 2001, 2002, 2003, 2004, 2005 4169689Skan Free Software Foundation, Inc. 590075Sobrien 690075SobrienThis file is part of GCC. 790075Sobrien 890075SobrienGCC is free software; you can redistribute it and/or modify it under 990075Sobrienthe terms of the GNU General Public License as published by the Free 1090075SobrienSoftware Foundation; either version 2, or (at your option) any later 1190075Sobrienversion. 1290075Sobrien 1390075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1490075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1590075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1690075Sobrienfor more details. 1790075Sobrien 1890075SobrienYou should have received a copy of the GNU General Public License 1990075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 20169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 21169689Skan02110-1301, USA. */ 2290075Sobrien 2390075Sobrien/* This file contains low level functions to manipulate the CFG and 24132718Skan analyze it. All other modules should not transform the data structure 2590075Sobrien directly and use abstraction instead. The file is supposed to be 2690075Sobrien ordered bottom-up and should not contain any code dependent on a 2790075Sobrien particular intermediate language (RTL or trees). 2890075Sobrien 2990075Sobrien Available functionality: 3090075Sobrien - Initialization/deallocation 3190075Sobrien init_flow, clear_edges 3290075Sobrien - Low level basic block manipulation 3390075Sobrien alloc_block, expunge_block 3490075Sobrien - Edge manipulation 3590075Sobrien make_edge, make_single_succ_edge, cached_make_edge, remove_edge 3690075Sobrien - Low level edge redirection (without updating instruction chain) 3790075Sobrien redirect_edge_succ, redirect_edge_succ_nodup, redirect_edge_pred 3890075Sobrien - Dumping and debugging 3990075Sobrien dump_flow_info, debug_flow_info, dump_edge_info 4090075Sobrien - Allocation of AUX fields for basic blocks 4190075Sobrien alloc_aux_for_blocks, free_aux_for_blocks, alloc_aux_for_block 42117395Skan - clear_bb_flags 43132718Skan - Consistency checking 44132718Skan verify_flow_info 45132718Skan - Dumping and debugging 46132718Skan print_rtl_with_bb, dump_bb, debug_bb, debug_bb_n 4790075Sobrien */ 4890075Sobrien 4990075Sobrien#include "config.h" 5090075Sobrien#include "system.h" 51132718Skan#include "coretypes.h" 52132718Skan#include "tm.h" 5390075Sobrien#include "tree.h" 5490075Sobrien#include "rtl.h" 5590075Sobrien#include "hard-reg-set.h" 5690075Sobrien#include "regs.h" 5790075Sobrien#include "flags.h" 5890075Sobrien#include "output.h" 5990075Sobrien#include "function.h" 6090075Sobrien#include "except.h" 6190075Sobrien#include "toplev.h" 6290075Sobrien#include "tm_p.h" 6390075Sobrien#include "obstack.h" 64169689Skan#include "timevar.h" 65169689Skan#include "tree-pass.h" 66169689Skan#include "ggc.h" 67169689Skan#include "hashtab.h" 68132718Skan#include "alloc-pool.h" 6990075Sobrien 7090075Sobrien/* The obstack on which the flow graph components are allocated. */ 7190075Sobrien 72169689Skanstruct bitmap_obstack reg_obstack; 7390075Sobrien 74132718Skanvoid debug_flow_info (void); 75132718Skanstatic void free_edge (edge); 7690075Sobrien 77169689Skan#define RDIV(X,Y) (((X) + (Y) / 2) / (Y)) 78169689Skan 7990075Sobrien/* Called once at initialization time. */ 8090075Sobrien 8190075Sobrienvoid 82132718Skaninit_flow (void) 8390075Sobrien{ 84169689Skan if (!cfun->cfg) 85169689Skan cfun->cfg = ggc_alloc_cleared (sizeof (struct control_flow_graph)); 8690075Sobrien n_edges = 0; 87169689Skan ENTRY_BLOCK_PTR = ggc_alloc_cleared (sizeof (struct basic_block_def)); 88169689Skan ENTRY_BLOCK_PTR->index = ENTRY_BLOCK; 89169689Skan EXIT_BLOCK_PTR = ggc_alloc_cleared (sizeof (struct basic_block_def)); 90169689Skan EXIT_BLOCK_PTR->index = EXIT_BLOCK; 91169689Skan ENTRY_BLOCK_PTR->next_bb = EXIT_BLOCK_PTR; 92169689Skan EXIT_BLOCK_PTR->prev_bb = ENTRY_BLOCK_PTR; 9390075Sobrien} 9490075Sobrien 9590075Sobrien/* Helper function for remove_edge and clear_edges. Frees edge structure 9690075Sobrien without actually unlinking it from the pred/succ lists. */ 9790075Sobrien 9890075Sobrienstatic void 99169689Skanfree_edge (edge e ATTRIBUTE_UNUSED) 10090075Sobrien{ 10190075Sobrien n_edges--; 102169689Skan ggc_free (e); 10390075Sobrien} 10490075Sobrien 10590075Sobrien/* Free the memory associated with the edge structures. */ 10690075Sobrien 10790075Sobrienvoid 108132718Skanclear_edges (void) 10990075Sobrien{ 110117395Skan basic_block bb; 11190075Sobrien edge e; 112169689Skan edge_iterator ei; 11390075Sobrien 114117395Skan FOR_EACH_BB (bb) 11590075Sobrien { 116169689Skan FOR_EACH_EDGE (e, ei, bb->succs) 117169689Skan free_edge (e); 118169689Skan VEC_truncate (edge, bb->succs, 0); 119169689Skan VEC_truncate (edge, bb->preds, 0); 12090075Sobrien } 12190075Sobrien 122169689Skan FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs) 123169689Skan free_edge (e); 124169689Skan VEC_truncate (edge, EXIT_BLOCK_PTR->preds, 0); 125169689Skan VEC_truncate (edge, ENTRY_BLOCK_PTR->succs, 0); 12690075Sobrien 127169689Skan gcc_assert (!n_edges); 12890075Sobrien} 12990075Sobrien 13090075Sobrien/* Allocate memory for basic_block. */ 13190075Sobrien 13290075Sobrienbasic_block 133132718Skanalloc_block (void) 13490075Sobrien{ 13590075Sobrien basic_block bb; 136169689Skan bb = ggc_alloc_cleared (sizeof (*bb)); 13790075Sobrien return bb; 13890075Sobrien} 13990075Sobrien 140117395Skan/* Link block B to chain after AFTER. */ 141117395Skanvoid 142132718Skanlink_block (basic_block b, basic_block after) 143117395Skan{ 144117395Skan b->next_bb = after->next_bb; 145117395Skan b->prev_bb = after; 146117395Skan after->next_bb = b; 147117395Skan b->next_bb->prev_bb = b; 148117395Skan} 14990075Sobrien 150117395Skan/* Unlink block B from chain. */ 15190075Sobrienvoid 152132718Skanunlink_block (basic_block b) 15396263Sobrien{ 154117395Skan b->next_bb->prev_bb = b->prev_bb; 155117395Skan b->prev_bb->next_bb = b->next_bb; 156169689Skan b->prev_bb = NULL; 157169689Skan b->next_bb = NULL; 158117395Skan} 159117395Skan 160117395Skan/* Sequentially order blocks and compact the arrays. */ 161117395Skanvoid 162132718Skancompact_blocks (void) 163117395Skan{ 164117395Skan int i; 165117395Skan basic_block bb; 166132718Skan 167169689Skan SET_BASIC_BLOCK (ENTRY_BLOCK, ENTRY_BLOCK_PTR); 168169689Skan SET_BASIC_BLOCK (EXIT_BLOCK, EXIT_BLOCK_PTR); 169169689Skan 170169689Skan i = NUM_FIXED_BLOCKS; 171169689Skan FOR_EACH_BB (bb) 172117395Skan { 173169689Skan SET_BASIC_BLOCK (i, bb); 174117395Skan bb->index = i; 175117395Skan i++; 176117395Skan } 177117395Skan 178169689Skan gcc_assert (i == n_basic_blocks); 179117395Skan 180169689Skan for (; i < last_basic_block; i++) 181169689Skan SET_BASIC_BLOCK (i, NULL); 182169689Skan 183117395Skan last_basic_block = n_basic_blocks; 184117395Skan} 185117395Skan 186117395Skan/* Remove block B from the basic block array. */ 187117395Skan 188117395Skanvoid 189132718Skanexpunge_block (basic_block b) 190117395Skan{ 191117395Skan unlink_block (b); 192169689Skan SET_BASIC_BLOCK (b->index, NULL); 193117395Skan n_basic_blocks--; 194169689Skan /* We should be able to ggc_free here, but we are not. 195169689Skan The dead SSA_NAMES are left pointing to dead statements that are pointing 196169689Skan to dead basic blocks making garbage collector to die. 197169689Skan We should be able to release all dead SSA_NAMES and at the same time we should 198169689Skan clear out BB pointer of dead statements consistently. */ 19996263Sobrien} 200117395Skan 201169689Skan/* Connect E to E->src. */ 202169689Skan 203169689Skanstatic inline void 204169689Skanconnect_src (edge e) 205169689Skan{ 206169689Skan VEC_safe_push (edge, gc, e->src->succs, e); 207169689Skan} 208169689Skan 209169689Skan/* Connect E to E->dest. */ 210169689Skan 211169689Skanstatic inline void 212169689Skanconnect_dest (edge e) 213169689Skan{ 214169689Skan basic_block dest = e->dest; 215169689Skan VEC_safe_push (edge, gc, dest->preds, e); 216169689Skan e->dest_idx = EDGE_COUNT (dest->preds) - 1; 217169689Skan} 218169689Skan 219169689Skan/* Disconnect edge E from E->src. */ 220169689Skan 221169689Skanstatic inline void 222169689Skandisconnect_src (edge e) 223169689Skan{ 224169689Skan basic_block src = e->src; 225169689Skan edge_iterator ei; 226169689Skan edge tmp; 227169689Skan 228169689Skan for (ei = ei_start (src->succs); (tmp = ei_safe_edge (ei)); ) 229169689Skan { 230169689Skan if (tmp == e) 231169689Skan { 232169689Skan VEC_unordered_remove (edge, src->succs, ei.index); 233169689Skan return; 234169689Skan } 235169689Skan else 236169689Skan ei_next (&ei); 237169689Skan } 238169689Skan 239169689Skan gcc_unreachable (); 240169689Skan} 241169689Skan 242169689Skan/* Disconnect edge E from E->dest. */ 243169689Skan 244169689Skanstatic inline void 245169689Skandisconnect_dest (edge e) 246169689Skan{ 247169689Skan basic_block dest = e->dest; 248169689Skan unsigned int dest_idx = e->dest_idx; 249169689Skan 250169689Skan VEC_unordered_remove (edge, dest->preds, dest_idx); 251169689Skan 252169689Skan /* If we removed an edge in the middle of the edge vector, we need 253169689Skan to update dest_idx of the edge that moved into the "hole". */ 254169689Skan if (dest_idx < EDGE_COUNT (dest->preds)) 255169689Skan EDGE_PRED (dest, dest_idx)->dest_idx = dest_idx; 256169689Skan} 257169689Skan 258117395Skan/* Create an edge connecting SRC and DEST with flags FLAGS. Return newly 259117395Skan created edge. Use this only if you are sure that this edge can't 260117395Skan possibly already exist. */ 26196263Sobrien 262117395Skanedge 263132718Skanunchecked_make_edge (basic_block src, basic_block dst, int flags) 26490075Sobrien{ 265117395Skan edge e; 266169689Skan e = ggc_alloc_cleared (sizeof (*e)); 267117395Skan n_edges++; 26890075Sobrien 269117395Skan e->src = src; 270117395Skan e->dest = dst; 271117395Skan e->flags = flags; 27296263Sobrien 273169689Skan connect_src (e); 274169689Skan connect_dest (e); 275117395Skan 276169689Skan execute_on_growing_pred (e); 277169689Skan 278117395Skan return e; 27990075Sobrien} 280132718Skan 28190075Sobrien/* Create an edge connecting SRC and DST with FLAGS optionally using 28290075Sobrien edge cache CACHE. Return the new edge, NULL if already exist. */ 28390075Sobrien 28490075Sobrienedge 285169689Skancached_make_edge (sbitmap edge_cache, basic_block src, basic_block dst, int flags) 28690075Sobrien{ 287169689Skan if (edge_cache == NULL 288169689Skan || src == ENTRY_BLOCK_PTR 289169689Skan || dst == EXIT_BLOCK_PTR) 290169689Skan return make_edge (src, dst, flags); 29190075Sobrien 292169689Skan /* Does the requested edge already exist? */ 293169689Skan if (! TEST_BIT (edge_cache, dst->index)) 294169689Skan { 295169689Skan /* The edge does not exist. Create one and update the 296169689Skan cache. */ 297169689Skan SET_BIT (edge_cache, dst->index); 298169689Skan return unchecked_make_edge (src, dst, flags); 299169689Skan } 30090075Sobrien 301169689Skan /* At this point, we know that the requested edge exists. Adjust 302169689Skan flags if necessary. */ 303169689Skan if (flags) 30490075Sobrien { 305169689Skan edge e = find_edge (src, dst); 306169689Skan e->flags |= flags; 30790075Sobrien } 30890075Sobrien 309169689Skan return NULL; 31090075Sobrien} 31190075Sobrien 31290075Sobrien/* Create an edge connecting SRC and DEST with flags FLAGS. Return newly 31390075Sobrien created edge or NULL if already exist. */ 31490075Sobrien 31590075Sobrienedge 316132718Skanmake_edge (basic_block src, basic_block dest, int flags) 31790075Sobrien{ 318169689Skan edge e = find_edge (src, dest); 319169689Skan 320169689Skan /* Make sure we don't add duplicate edges. */ 321169689Skan if (e) 322169689Skan { 323169689Skan e->flags |= flags; 324169689Skan return NULL; 325169689Skan } 326169689Skan 327169689Skan return unchecked_make_edge (src, dest, flags); 32890075Sobrien} 32990075Sobrien 33090075Sobrien/* Create an edge connecting SRC to DEST and set probability by knowing 33190075Sobrien that it is the single edge leaving SRC. */ 33290075Sobrien 33390075Sobrienedge 334132718Skanmake_single_succ_edge (basic_block src, basic_block dest, int flags) 33590075Sobrien{ 33690075Sobrien edge e = make_edge (src, dest, flags); 33790075Sobrien 33890075Sobrien e->probability = REG_BR_PROB_BASE; 33990075Sobrien e->count = src->count; 34090075Sobrien return e; 34190075Sobrien} 34290075Sobrien 34390075Sobrien/* This function will remove an edge from the flow graph. */ 34490075Sobrien 34590075Sobrienvoid 346132718Skanremove_edge (edge e) 34790075Sobrien{ 348169689Skan remove_predictions_associated_with_edge (e); 349169689Skan execute_on_shrinking_pred (e); 35090075Sobrien 351169689Skan disconnect_src (e); 352169689Skan disconnect_dest (e); 35390075Sobrien 35490075Sobrien free_edge (e); 35590075Sobrien} 35690075Sobrien 35790075Sobrien/* Redirect an edge's successor from one block to another. */ 35890075Sobrien 35990075Sobrienvoid 360132718Skanredirect_edge_succ (edge e, basic_block new_succ) 36190075Sobrien{ 362169689Skan execute_on_shrinking_pred (e); 36390075Sobrien 364169689Skan disconnect_dest (e); 36590075Sobrien 366169689Skan e->dest = new_succ; 367169689Skan 36890075Sobrien /* Reconnect the edge to the new successor block. */ 369169689Skan connect_dest (e); 370169689Skan 371169689Skan execute_on_growing_pred (e); 37290075Sobrien} 37390075Sobrien 37490075Sobrien/* Like previous but avoid possible duplicate edge. */ 37590075Sobrien 37690075Sobrienedge 377132718Skanredirect_edge_succ_nodup (edge e, basic_block new_succ) 37890075Sobrien{ 37990075Sobrien edge s; 38090075Sobrien 381169689Skan s = find_edge (e->src, new_succ); 382169689Skan if (s && s != e) 38390075Sobrien { 38490075Sobrien s->flags |= e->flags; 38590075Sobrien s->probability += e->probability; 386117395Skan if (s->probability > REG_BR_PROB_BASE) 387117395Skan s->probability = REG_BR_PROB_BASE; 38890075Sobrien s->count += e->count; 38990075Sobrien remove_edge (e); 39090075Sobrien e = s; 39190075Sobrien } 39290075Sobrien else 39390075Sobrien redirect_edge_succ (e, new_succ); 39490075Sobrien 39590075Sobrien return e; 39690075Sobrien} 39790075Sobrien 39890075Sobrien/* Redirect an edge's predecessor from one block to another. */ 39990075Sobrien 40090075Sobrienvoid 401132718Skanredirect_edge_pred (edge e, basic_block new_pred) 40290075Sobrien{ 403169689Skan disconnect_src (e); 40490075Sobrien 405169689Skan e->src = new_pred; 40690075Sobrien 40790075Sobrien /* Reconnect the edge to the new predecessor block. */ 408169689Skan connect_src (e); 40990075Sobrien} 410117395Skan 411169689Skan/* Clear all basic block flags, with the exception of partitioning. */ 412117395Skanvoid 413132718Skanclear_bb_flags (void) 414117395Skan{ 415117395Skan basic_block bb; 416117395Skan 417117395Skan FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb) 418169689Skan bb->flags = (BB_PARTITION (bb) | (bb->flags & BB_DISABLE_SCHEDULE) 419169689Skan | (bb->flags & BB_RTL)); 420117395Skan} 42190075Sobrien 422169689Skan/* Check the consistency of profile information. We can't do that 423169689Skan in verify_flow_info, as the counts may get invalid for incompletely 424169689Skan solved graphs, later eliminating of conditionals or roundoff errors. 425169689Skan It is still practical to have them reported for debugging of simple 426169689Skan testcases. */ 42790075Sobrienvoid 428169689Skancheck_bb_profile (basic_block bb, FILE * file) 42990075Sobrien{ 430169689Skan edge e; 431169689Skan int sum = 0; 432169689Skan gcov_type lsum; 433169689Skan edge_iterator ei; 43490075Sobrien 435169689Skan if (profile_status == PROFILE_ABSENT) 436169689Skan return; 43790075Sobrien 438169689Skan if (bb != EXIT_BLOCK_PTR) 439169689Skan { 440169689Skan FOR_EACH_EDGE (e, ei, bb->succs) 441169689Skan sum += e->probability; 442169689Skan if (EDGE_COUNT (bb->succs) && abs (sum - REG_BR_PROB_BASE) > 100) 443169689Skan fprintf (file, "Invalid sum of outgoing probabilities %.1f%%\n", 444169689Skan sum * 100.0 / REG_BR_PROB_BASE); 445169689Skan lsum = 0; 446169689Skan FOR_EACH_EDGE (e, ei, bb->succs) 447169689Skan lsum += e->count; 448169689Skan if (EDGE_COUNT (bb->succs) 449169689Skan && (lsum - bb->count > 100 || lsum - bb->count < -100)) 450169689Skan fprintf (file, "Invalid sum of outgoing counts %i, should be %i\n", 451169689Skan (int) lsum, (int) bb->count); 452169689Skan } 453169689Skan if (bb != ENTRY_BLOCK_PTR) 454169689Skan { 455169689Skan sum = 0; 456169689Skan FOR_EACH_EDGE (e, ei, bb->preds) 457169689Skan sum += EDGE_FREQUENCY (e); 458169689Skan if (abs (sum - bb->frequency) > 100) 459169689Skan fprintf (file, 460169689Skan "Invalid sum of incoming frequencies %i, should be %i\n", 461169689Skan sum, bb->frequency); 462169689Skan lsum = 0; 463169689Skan FOR_EACH_EDGE (e, ei, bb->preds) 464169689Skan lsum += e->count; 465169689Skan if (lsum - bb->count > 100 || lsum - bb->count < -100) 466169689Skan fprintf (file, "Invalid sum of incoming counts %i, should be %i\n", 467169689Skan (int) lsum, (int) bb->count); 468169689Skan } 469169689Skan} 470169689Skan 471169689Skan/* Emit basic block information for BB. HEADER is true if the user wants 472169689Skan the generic information and the predecessors, FOOTER is true if they want 473169689Skan the successors. FLAGS is the dump flags of interest; TDF_DETAILS emit 474169689Skan global register liveness information. PREFIX is put in front of every 475169689Skan line. The output is emitted to FILE. */ 476169689Skanvoid 477169689Skandump_bb_info (basic_block bb, bool header, bool footer, int flags, 478169689Skan const char *prefix, FILE *file) 479169689Skan{ 480169689Skan edge e; 481169689Skan edge_iterator ei; 48290075Sobrien 483169689Skan if (header) 48490075Sobrien { 485169689Skan fprintf (file, "\n%sBasic block %d ", prefix, bb->index); 486169689Skan if (bb->prev_bb) 487169689Skan fprintf (file, ", prev %d", bb->prev_bb->index); 488169689Skan if (bb->next_bb) 489169689Skan fprintf (file, ", next %d", bb->next_bb->index); 490169689Skan fprintf (file, ", loop_depth %d, count ", bb->loop_depth); 49190075Sobrien fprintf (file, HOST_WIDEST_INT_PRINT_DEC, bb->count); 492117395Skan fprintf (file, ", freq %i", bb->frequency); 493117395Skan if (maybe_hot_bb_p (bb)) 494117395Skan fprintf (file, ", maybe hot"); 495117395Skan if (probably_never_executed_bb_p (bb)) 496117395Skan fprintf (file, ", probably never executed"); 497117395Skan fprintf (file, ".\n"); 49890075Sobrien 499169689Skan fprintf (file, "%sPredecessors: ", prefix); 500169689Skan FOR_EACH_EDGE (e, ei, bb->preds) 50190075Sobrien dump_edge_info (file, e, 0); 502169689Skan } 50390075Sobrien 504169689Skan if (footer) 505169689Skan { 506169689Skan fprintf (file, "\n%sSuccessors: ", prefix); 507169689Skan FOR_EACH_EDGE (e, ei, bb->succs) 50890075Sobrien dump_edge_info (file, e, 1); 509169689Skan } 51090075Sobrien 511169689Skan if ((flags & TDF_DETAILS) 512169689Skan && (bb->flags & BB_RTL)) 513169689Skan { 514169689Skan if (bb->il.rtl->global_live_at_start && header) 515169689Skan { 516169689Skan fprintf (file, "\n%sRegisters live at start:", prefix); 517169689Skan dump_regset (bb->il.rtl->global_live_at_start, file); 518169689Skan } 51990075Sobrien 520169689Skan if (bb->il.rtl->global_live_at_end && footer) 521169689Skan { 522169689Skan fprintf (file, "\n%sRegisters live at end:", prefix); 523169689Skan dump_regset (bb->il.rtl->global_live_at_end, file); 524169689Skan } 525169689Skan } 52690075Sobrien 527169689Skan putc ('\n', file); 528169689Skan} 529117395Skan 530169689Skanvoid 531169689Skandump_flow_info (FILE *file, int flags) 532169689Skan{ 533169689Skan basic_block bb; 534169689Skan 535169689Skan /* There are no pseudo registers after reload. Don't dump them. */ 536169689Skan if (reg_n_info && !reload_completed 537169689Skan && (flags & TDF_DETAILS) != 0) 538169689Skan { 539169689Skan unsigned int i, max = max_reg_num (); 540169689Skan fprintf (file, "%d registers.\n", max); 541169689Skan for (i = FIRST_PSEUDO_REGISTER; i < max; i++) 542169689Skan if (REG_N_REFS (i)) 543169689Skan { 544169689Skan enum reg_class class, altclass; 545169689Skan 546169689Skan fprintf (file, "\nRegister %d used %d times across %d insns", 547169689Skan i, REG_N_REFS (i), REG_LIVE_LENGTH (i)); 548169689Skan if (REG_BASIC_BLOCK (i) >= 0) 549169689Skan fprintf (file, " in block %d", REG_BASIC_BLOCK (i)); 550169689Skan if (REG_N_SETS (i)) 551169689Skan fprintf (file, "; set %d time%s", REG_N_SETS (i), 552169689Skan (REG_N_SETS (i) == 1) ? "" : "s"); 553169689Skan if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i])) 554169689Skan fprintf (file, "; user var"); 555169689Skan if (REG_N_DEATHS (i) != 1) 556169689Skan fprintf (file, "; dies in %d places", REG_N_DEATHS (i)); 557169689Skan if (REG_N_CALLS_CROSSED (i) == 1) 558169689Skan fprintf (file, "; crosses 1 call"); 559169689Skan else if (REG_N_CALLS_CROSSED (i)) 560169689Skan fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i)); 561169689Skan if (regno_reg_rtx[i] != NULL 562169689Skan && PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD) 563169689Skan fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i)); 564169689Skan 565169689Skan class = reg_preferred_class (i); 566169689Skan altclass = reg_alternate_class (i); 567169689Skan if (class != GENERAL_REGS || altclass != ALL_REGS) 568169689Skan { 569169689Skan if (altclass == ALL_REGS || class == ALL_REGS) 570169689Skan fprintf (file, "; pref %s", reg_class_names[(int) class]); 571169689Skan else if (altclass == NO_REGS) 572169689Skan fprintf (file, "; %s or none", reg_class_names[(int) class]); 573169689Skan else 574169689Skan fprintf (file, "; pref %s, else %s", 575169689Skan reg_class_names[(int) class], 576169689Skan reg_class_names[(int) altclass]); 577169689Skan } 578169689Skan 579169689Skan if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i])) 580169689Skan fprintf (file, "; pointer"); 581169689Skan fprintf (file, ".\n"); 582169689Skan } 58390075Sobrien } 58490075Sobrien 585169689Skan fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges); 586169689Skan FOR_EACH_BB (bb) 587169689Skan { 588169689Skan dump_bb_info (bb, true, true, flags, "", file); 589169689Skan check_bb_profile (bb, file); 590169689Skan } 591169689Skan 59290075Sobrien putc ('\n', file); 59390075Sobrien} 59490075Sobrien 59590075Sobrienvoid 596132718Skandebug_flow_info (void) 59790075Sobrien{ 598169689Skan dump_flow_info (stderr, TDF_DETAILS); 59990075Sobrien} 60090075Sobrien 60190075Sobrienvoid 602132718Skandump_edge_info (FILE *file, edge e, int do_succ) 60390075Sobrien{ 60490075Sobrien basic_block side = (do_succ ? e->dest : e->src); 60590075Sobrien 60690075Sobrien if (side == ENTRY_BLOCK_PTR) 60790075Sobrien fputs (" ENTRY", file); 60890075Sobrien else if (side == EXIT_BLOCK_PTR) 60990075Sobrien fputs (" EXIT", file); 61090075Sobrien else 61190075Sobrien fprintf (file, " %d", side->index); 61290075Sobrien 61390075Sobrien if (e->probability) 61490075Sobrien fprintf (file, " [%.1f%%] ", e->probability * 100.0 / REG_BR_PROB_BASE); 61590075Sobrien 61690075Sobrien if (e->count) 61790075Sobrien { 61890075Sobrien fprintf (file, " count:"); 61990075Sobrien fprintf (file, HOST_WIDEST_INT_PRINT_DEC, e->count); 62090075Sobrien } 62190075Sobrien 62290075Sobrien if (e->flags) 62390075Sobrien { 624132718Skan static const char * const bitnames[] = { 625132718Skan "fallthru", "ab", "abcall", "eh", "fake", "dfs_back", 626169689Skan "can_fallthru", "irreducible", "sibcall", "loop_exit", 627169689Skan "true", "false", "exec" 628132718Skan }; 62990075Sobrien int comma = 0; 63090075Sobrien int i, flags = e->flags; 63190075Sobrien 63290075Sobrien fputs (" (", file); 63390075Sobrien for (i = 0; flags; i++) 63490075Sobrien if (flags & (1 << i)) 63590075Sobrien { 63690075Sobrien flags &= ~(1 << i); 63790075Sobrien 63890075Sobrien if (comma) 63990075Sobrien fputc (',', file); 64090075Sobrien if (i < (int) ARRAY_SIZE (bitnames)) 64190075Sobrien fputs (bitnames[i], file); 64290075Sobrien else 64390075Sobrien fprintf (file, "%d", i); 64490075Sobrien comma = 1; 64590075Sobrien } 64690075Sobrien 64790075Sobrien fputc (')', file); 64890075Sobrien } 64990075Sobrien} 65090075Sobrien 65190075Sobrien/* Simple routines to easily allocate AUX fields of basic blocks. */ 65290075Sobrien 65390075Sobrienstatic struct obstack block_aux_obstack; 65490075Sobrienstatic void *first_block_aux_obj = 0; 65590075Sobrienstatic struct obstack edge_aux_obstack; 65690075Sobrienstatic void *first_edge_aux_obj = 0; 65790075Sobrien 658117395Skan/* Allocate a memory block of SIZE as BB->aux. The obstack must 65990075Sobrien be first initialized by alloc_aux_for_blocks. */ 66090075Sobrien 66190075Sobrieninline void 662132718Skanalloc_aux_for_block (basic_block bb, int size) 66390075Sobrien{ 66490075Sobrien /* Verify that aux field is clear. */ 665169689Skan gcc_assert (!bb->aux && first_block_aux_obj); 66690075Sobrien bb->aux = obstack_alloc (&block_aux_obstack, size); 66790075Sobrien memset (bb->aux, 0, size); 66890075Sobrien} 66990075Sobrien 67090075Sobrien/* Initialize the block_aux_obstack and if SIZE is nonzero, call 67190075Sobrien alloc_aux_for_block for each basic block. */ 67290075Sobrien 67390075Sobrienvoid 674132718Skanalloc_aux_for_blocks (int size) 67590075Sobrien{ 67690075Sobrien static int initialized; 67790075Sobrien 67890075Sobrien if (!initialized) 67990075Sobrien { 68090075Sobrien gcc_obstack_init (&block_aux_obstack); 68190075Sobrien initialized = 1; 68290075Sobrien } 683169689Skan else 684169689Skan /* Check whether AUX data are still allocated. */ 685169689Skan gcc_assert (!first_block_aux_obj); 68690075Sobrien 687132718Skan first_block_aux_obj = obstack_alloc (&block_aux_obstack, 0); 68890075Sobrien if (size) 68990075Sobrien { 690117395Skan basic_block bb; 69190075Sobrien 692117395Skan FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb) 693117395Skan alloc_aux_for_block (bb, size); 69490075Sobrien } 69590075Sobrien} 69690075Sobrien 69790075Sobrien/* Clear AUX pointers of all blocks. */ 69890075Sobrien 69990075Sobrienvoid 700132718Skanclear_aux_for_blocks (void) 70190075Sobrien{ 702117395Skan basic_block bb; 70390075Sobrien 704117395Skan FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb) 705117395Skan bb->aux = NULL; 70690075Sobrien} 70790075Sobrien 70890075Sobrien/* Free data allocated in block_aux_obstack and clear AUX pointers 70990075Sobrien of all blocks. */ 71090075Sobrien 71190075Sobrienvoid 712132718Skanfree_aux_for_blocks (void) 71390075Sobrien{ 714169689Skan gcc_assert (first_block_aux_obj); 71590075Sobrien obstack_free (&block_aux_obstack, first_block_aux_obj); 71690075Sobrien first_block_aux_obj = NULL; 71790075Sobrien 71890075Sobrien clear_aux_for_blocks (); 71990075Sobrien} 72090075Sobrien 721117395Skan/* Allocate a memory edge of SIZE as BB->aux. The obstack must 72290075Sobrien be first initialized by alloc_aux_for_edges. */ 72390075Sobrien 72490075Sobrieninline void 725132718Skanalloc_aux_for_edge (edge e, int size) 72690075Sobrien{ 72790075Sobrien /* Verify that aux field is clear. */ 728169689Skan gcc_assert (!e->aux && first_edge_aux_obj); 72990075Sobrien e->aux = obstack_alloc (&edge_aux_obstack, size); 73090075Sobrien memset (e->aux, 0, size); 73190075Sobrien} 73290075Sobrien 73390075Sobrien/* Initialize the edge_aux_obstack and if SIZE is nonzero, call 73490075Sobrien alloc_aux_for_edge for each basic edge. */ 73590075Sobrien 73690075Sobrienvoid 737132718Skanalloc_aux_for_edges (int size) 73890075Sobrien{ 73990075Sobrien static int initialized; 74090075Sobrien 74190075Sobrien if (!initialized) 74290075Sobrien { 74390075Sobrien gcc_obstack_init (&edge_aux_obstack); 74490075Sobrien initialized = 1; 74590075Sobrien } 746169689Skan else 747169689Skan /* Check whether AUX data are still allocated. */ 748169689Skan gcc_assert (!first_edge_aux_obj); 74990075Sobrien 750132718Skan first_edge_aux_obj = obstack_alloc (&edge_aux_obstack, 0); 75190075Sobrien if (size) 75290075Sobrien { 753117395Skan basic_block bb; 754117395Skan 755117395Skan FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb) 75690075Sobrien { 75790075Sobrien edge e; 758169689Skan edge_iterator ei; 75990075Sobrien 760169689Skan FOR_EACH_EDGE (e, ei, bb->succs) 76190075Sobrien alloc_aux_for_edge (e, size); 76290075Sobrien } 76390075Sobrien } 76490075Sobrien} 76590075Sobrien 76690075Sobrien/* Clear AUX pointers of all edges. */ 76790075Sobrien 76890075Sobrienvoid 769132718Skanclear_aux_for_edges (void) 77090075Sobrien{ 771117395Skan basic_block bb; 772117395Skan edge e; 77390075Sobrien 774117395Skan FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb) 77590075Sobrien { 776169689Skan edge_iterator ei; 777169689Skan FOR_EACH_EDGE (e, ei, bb->succs) 77890075Sobrien e->aux = NULL; 77990075Sobrien } 78090075Sobrien} 78190075Sobrien 78290075Sobrien/* Free data allocated in edge_aux_obstack and clear AUX pointers 78390075Sobrien of all edges. */ 78490075Sobrien 78590075Sobrienvoid 786132718Skanfree_aux_for_edges (void) 78790075Sobrien{ 788169689Skan gcc_assert (first_edge_aux_obj); 78990075Sobrien obstack_free (&edge_aux_obstack, first_edge_aux_obj); 79090075Sobrien first_edge_aux_obj = NULL; 79190075Sobrien 79290075Sobrien clear_aux_for_edges (); 79390075Sobrien} 794132718Skan 795132718Skanvoid 796169689Skandebug_bb (basic_block bb) 797132718Skan{ 798169689Skan dump_bb (bb, stderr, 0); 799169689Skan} 800132718Skan 801169689Skanbasic_block 802169689Skandebug_bb_n (int n) 803169689Skan{ 804169689Skan basic_block bb = BASIC_BLOCK (n); 805169689Skan dump_bb (bb, stderr, 0); 806169689Skan return bb; 807169689Skan} 808132718Skan 809169689Skan/* Dumps cfg related information about basic block BB to FILE. */ 810169689Skan 811169689Skanstatic void 812169689Skandump_cfg_bb_info (FILE *file, basic_block bb) 813169689Skan{ 814169689Skan unsigned i; 815169689Skan edge_iterator ei; 816169689Skan bool first = true; 817169689Skan static const char * const bb_bitnames[] = 818132718Skan { 819169689Skan "dirty", "new", "reachable", "visited", "irreducible_loop", "superblock" 820169689Skan }; 821169689Skan const unsigned n_bitnames = sizeof (bb_bitnames) / sizeof (char *); 822169689Skan edge e; 823132718Skan 824169689Skan fprintf (file, "Basic block %d", bb->index); 825169689Skan for (i = 0; i < n_bitnames; i++) 826169689Skan if (bb->flags & (1 << i)) 827169689Skan { 828169689Skan if (first) 829169689Skan fprintf (file, " ("); 830169689Skan else 831169689Skan fprintf (file, ", "); 832169689Skan first = false; 833260012Spfg fprintf (file, "%s", bb_bitnames[i]); 834169689Skan } 835169689Skan if (!first) 836169689Skan fprintf (file, ")"); 837169689Skan fprintf (file, "\n"); 838132718Skan 839169689Skan fprintf (file, "Predecessors: "); 840169689Skan FOR_EACH_EDGE (e, ei, bb->preds) 841169689Skan dump_edge_info (file, e, 0); 842132718Skan 843169689Skan fprintf (file, "\nSuccessors: "); 844169689Skan FOR_EACH_EDGE (e, ei, bb->succs) 845169689Skan dump_edge_info (file, e, 1); 846169689Skan fprintf (file, "\n\n"); 847169689Skan} 848169689Skan 849169689Skan/* Dumps a brief description of cfg to FILE. */ 850169689Skan 851169689Skanvoid 852169689Skanbrief_dump_cfg (FILE *file) 853169689Skan{ 854169689Skan basic_block bb; 855169689Skan 856169689Skan FOR_EACH_BB (bb) 857132718Skan { 858169689Skan dump_cfg_bb_info (file, bb); 859169689Skan } 860169689Skan} 861132718Skan 862169689Skan/* An edge originally destinating BB of FREQUENCY and COUNT has been proved to 863169689Skan leave the block by TAKEN_EDGE. Update profile of BB such that edge E can be 864169689Skan redirected to destination of TAKEN_EDGE. 865132718Skan 866169689Skan This function may leave the profile inconsistent in the case TAKEN_EDGE 867169689Skan frequency or count is believed to be lower than FREQUENCY or COUNT 868169689Skan respectively. */ 869169689Skanvoid 870169689Skanupdate_bb_profile_for_threading (basic_block bb, int edge_frequency, 871169689Skan gcov_type count, edge taken_edge) 872169689Skan{ 873169689Skan edge c; 874169689Skan int prob; 875169689Skan edge_iterator ei; 876132718Skan 877169689Skan bb->count -= count; 878169689Skan if (bb->count < 0) 879169689Skan { 880169689Skan if (dump_file) 881169689Skan fprintf (dump_file, "bb %i count became negative after threading", 882169689Skan bb->index); 883169689Skan bb->count = 0; 884169689Skan } 885132718Skan 886169689Skan /* Compute the probability of TAKEN_EDGE being reached via threaded edge. 887169689Skan Watch for overflows. */ 888169689Skan if (bb->frequency) 889169689Skan prob = edge_frequency * REG_BR_PROB_BASE / bb->frequency; 890169689Skan else 891169689Skan prob = 0; 892169689Skan if (prob > taken_edge->probability) 893169689Skan { 894169689Skan if (dump_file) 895169689Skan fprintf (dump_file, "Jump threading proved probability of edge " 896169689Skan "%i->%i too small (it is %i, should be %i).\n", 897169689Skan taken_edge->src->index, taken_edge->dest->index, 898169689Skan taken_edge->probability, prob); 899169689Skan prob = taken_edge->probability; 900169689Skan } 901132718Skan 902169689Skan /* Now rescale the probabilities. */ 903169689Skan taken_edge->probability -= prob; 904169689Skan prob = REG_BR_PROB_BASE - prob; 905169689Skan bb->frequency -= edge_frequency; 906169689Skan if (bb->frequency < 0) 907169689Skan bb->frequency = 0; 908169689Skan if (prob <= 0) 909169689Skan { 910169689Skan if (dump_file) 911169689Skan fprintf (dump_file, "Edge frequencies of bb %i has been reset, " 912169689Skan "frequency of block should end up being 0, it is %i\n", 913169689Skan bb->index, bb->frequency); 914169689Skan EDGE_SUCC (bb, 0)->probability = REG_BR_PROB_BASE; 915169689Skan ei = ei_start (bb->succs); 916169689Skan ei_next (&ei); 917169689Skan for (; (c = ei_safe_edge (ei)); ei_next (&ei)) 918169689Skan c->probability = 0; 919169689Skan } 920169689Skan else if (prob != REG_BR_PROB_BASE) 921169689Skan { 922169689Skan int scale = RDIV (65536 * REG_BR_PROB_BASE, prob); 923132718Skan 924169689Skan FOR_EACH_EDGE (c, ei, bb->succs) 925132718Skan { 926169689Skan c->probability = RDIV (c->probability * scale, 65536); 927169689Skan if (c->probability > REG_BR_PROB_BASE) 928169689Skan c->probability = REG_BR_PROB_BASE; 929132718Skan } 930132718Skan } 931132718Skan 932169689Skan gcc_assert (bb == taken_edge->src); 933169689Skan taken_edge->count -= count; 934169689Skan if (taken_edge->count < 0) 935169689Skan { 936169689Skan if (dump_file) 937169689Skan fprintf (dump_file, "edge %i->%i count became negative after threading", 938169689Skan taken_edge->src->index, taken_edge->dest->index); 939169689Skan taken_edge->count = 0; 940169689Skan } 941169689Skan} 942132718Skan 943169689Skan/* Multiply all frequencies of basic blocks in array BBS of length NBBS 944169689Skan by NUM/DEN, in int arithmetic. May lose some accuracy. */ 945169689Skanvoid 946169689Skanscale_bbs_frequencies_int (basic_block *bbs, int nbbs, int num, int den) 947169689Skan{ 948169689Skan int i; 949169689Skan edge e; 950169689Skan if (num < 0) 951169689Skan num = 0; 952169689Skan if (num > den) 953169689Skan return; 954169689Skan /* Assume that the users are producing the fraction from frequencies 955169689Skan that never grow far enough to risk arithmetic overflow. */ 956169689Skan gcc_assert (num < 65536); 957169689Skan for (i = 0; i < nbbs; i++) 958169689Skan { 959169689Skan edge_iterator ei; 960169689Skan bbs[i]->frequency = RDIV (bbs[i]->frequency * num, den); 961169689Skan bbs[i]->count = RDIV (bbs[i]->count * num, den); 962169689Skan FOR_EACH_EDGE (e, ei, bbs[i]->succs) 963169689Skan e->count = RDIV (e->count * num, den); 964169689Skan } 965169689Skan} 966132718Skan 967169689Skan/* numbers smaller than this value are safe to multiply without getting 968169689Skan 64bit overflow. */ 969169689Skan#define MAX_SAFE_MULTIPLIER (1 << (sizeof (HOST_WIDEST_INT) * 4 - 1)) 970132718Skan 971169689Skan/* Multiply all frequencies of basic blocks in array BBS of length NBBS 972169689Skan by NUM/DEN, in gcov_type arithmetic. More accurate than previous 973169689Skan function but considerably slower. */ 974169689Skanvoid 975169689Skanscale_bbs_frequencies_gcov_type (basic_block *bbs, int nbbs, gcov_type num, 976169689Skan gcov_type den) 977169689Skan{ 978169689Skan int i; 979169689Skan edge e; 980169689Skan gcov_type fraction = RDIV (num * 65536, den); 981169689Skan 982169689Skan gcc_assert (fraction >= 0); 983169689Skan 984169689Skan if (num < MAX_SAFE_MULTIPLIER) 985169689Skan for (i = 0; i < nbbs; i++) 986132718Skan { 987169689Skan edge_iterator ei; 988169689Skan bbs[i]->frequency = RDIV (bbs[i]->frequency * num, den); 989169689Skan if (bbs[i]->count <= MAX_SAFE_MULTIPLIER) 990169689Skan bbs[i]->count = RDIV (bbs[i]->count * num, den); 991169689Skan else 992169689Skan bbs[i]->count = RDIV (bbs[i]->count * fraction, 65536); 993169689Skan FOR_EACH_EDGE (e, ei, bbs[i]->succs) 994169689Skan if (bbs[i]->count <= MAX_SAFE_MULTIPLIER) 995169689Skan e->count = RDIV (e->count * num, den); 996169689Skan else 997169689Skan e->count = RDIV (e->count * fraction, 65536); 998132718Skan } 999169689Skan else 1000169689Skan for (i = 0; i < nbbs; i++) 1001169689Skan { 1002169689Skan edge_iterator ei; 1003169689Skan if (sizeof (gcov_type) > sizeof (int)) 1004169689Skan bbs[i]->frequency = RDIV (bbs[i]->frequency * num, den); 1005169689Skan else 1006169689Skan bbs[i]->frequency = RDIV (bbs[i]->frequency * fraction, 65536); 1007169689Skan bbs[i]->count = RDIV (bbs[i]->count * fraction, 65536); 1008169689Skan FOR_EACH_EDGE (e, ei, bbs[i]->succs) 1009169689Skan e->count = RDIV (e->count * fraction, 65536); 1010169689Skan } 1011169689Skan} 1012132718Skan 1013169689Skan/* Data structures used to maintain mapping between basic blocks and 1014169689Skan copies. */ 1015169689Skanstatic htab_t bb_original; 1016169689Skanstatic htab_t bb_copy; 1017169689Skanstatic alloc_pool original_copy_bb_pool; 1018132718Skan 1019169689Skanstruct htab_bb_copy_original_entry 1020169689Skan{ 1021169689Skan /* Block we are attaching info to. */ 1022169689Skan int index1; 1023169689Skan /* Index of original or copy (depending on the hashtable) */ 1024169689Skan int index2; 1025169689Skan}; 1026169689Skan 1027169689Skanstatic hashval_t 1028169689Skanbb_copy_original_hash (const void *p) 1029169689Skan{ 1030169689Skan struct htab_bb_copy_original_entry *data 1031169689Skan = ((struct htab_bb_copy_original_entry *)p); 1032169689Skan 1033169689Skan return data->index1; 1034132718Skan} 1035169689Skanstatic int 1036169689Skanbb_copy_original_eq (const void *p, const void *q) 1037169689Skan{ 1038169689Skan struct htab_bb_copy_original_entry *data 1039169689Skan = ((struct htab_bb_copy_original_entry *)p); 1040169689Skan struct htab_bb_copy_original_entry *data2 1041169689Skan = ((struct htab_bb_copy_original_entry *)q); 1042132718Skan 1043169689Skan return data->index1 == data2->index1; 1044169689Skan} 1045132718Skan 1046169689Skan/* Initialize the data structures to maintain mapping between blocks 1047169689Skan and its copies. */ 1048132718Skanvoid 1049169689Skaninitialize_original_copy_tables (void) 1050132718Skan{ 1051169689Skan gcc_assert (!original_copy_bb_pool); 1052169689Skan original_copy_bb_pool 1053169689Skan = create_alloc_pool ("original_copy", 1054169689Skan sizeof (struct htab_bb_copy_original_entry), 10); 1055169689Skan bb_original = htab_create (10, bb_copy_original_hash, 1056169689Skan bb_copy_original_eq, NULL); 1057169689Skan bb_copy = htab_create (10, bb_copy_original_hash, bb_copy_original_eq, NULL); 1058169689Skan} 1059132718Skan 1060169689Skan/* Free the data structures to maintain mapping between blocks and 1061169689Skan its copies. */ 1062169689Skanvoid 1063169689Skanfree_original_copy_tables (void) 1064169689Skan{ 1065169689Skan gcc_assert (original_copy_bb_pool); 1066169689Skan htab_delete (bb_copy); 1067169689Skan htab_delete (bb_original); 1068169689Skan free_alloc_pool (original_copy_bb_pool); 1069169689Skan bb_copy = NULL; 1070169689Skan bb_original = NULL; 1071169689Skan original_copy_bb_pool = NULL; 1072169689Skan} 1073132718Skan 1074169689Skan/* Set original for basic block. Do nothing when data structures are not 1075169689Skan initialized so passes not needing this don't need to care. */ 1076169689Skanvoid 1077169689Skanset_bb_original (basic_block bb, basic_block original) 1078169689Skan{ 1079169689Skan if (original_copy_bb_pool) 1080169689Skan { 1081169689Skan struct htab_bb_copy_original_entry **slot; 1082169689Skan struct htab_bb_copy_original_entry key; 1083132718Skan 1084169689Skan key.index1 = bb->index; 1085169689Skan slot = 1086169689Skan (struct htab_bb_copy_original_entry **) htab_find_slot (bb_original, 1087169689Skan &key, INSERT); 1088169689Skan if (*slot) 1089169689Skan (*slot)->index2 = original->index; 1090169689Skan else 1091169689Skan { 1092169689Skan *slot = pool_alloc (original_copy_bb_pool); 1093169689Skan (*slot)->index1 = bb->index; 1094169689Skan (*slot)->index2 = original->index; 1095169689Skan } 1096169689Skan } 1097132718Skan} 1098132718Skan 1099169689Skan/* Get the original basic block. */ 1100169689Skanbasic_block 1101169689Skanget_bb_original (basic_block bb) 1102169689Skan{ 1103169689Skan struct htab_bb_copy_original_entry *entry; 1104169689Skan struct htab_bb_copy_original_entry key; 1105169689Skan 1106169689Skan gcc_assert (original_copy_bb_pool); 1107169689Skan 1108169689Skan key.index1 = bb->index; 1109169689Skan entry = (struct htab_bb_copy_original_entry *) htab_find (bb_original, &key); 1110169689Skan if (entry) 1111169689Skan return BASIC_BLOCK (entry->index2); 1112169689Skan else 1113169689Skan return NULL; 1114169689Skan} 1115169689Skan 1116169689Skan/* Set copy for basic block. Do nothing when data structures are not 1117169689Skan initialized so passes not needing this don't need to care. */ 1118132718Skanvoid 1119169689Skanset_bb_copy (basic_block bb, basic_block copy) 1120132718Skan{ 1121169689Skan if (original_copy_bb_pool) 1122169689Skan { 1123169689Skan struct htab_bb_copy_original_entry **slot; 1124169689Skan struct htab_bb_copy_original_entry key; 1125169689Skan 1126169689Skan key.index1 = bb->index; 1127169689Skan slot = 1128169689Skan (struct htab_bb_copy_original_entry **) htab_find_slot (bb_copy, 1129169689Skan &key, INSERT); 1130169689Skan if (*slot) 1131169689Skan (*slot)->index2 = copy->index; 1132169689Skan else 1133169689Skan { 1134169689Skan *slot = pool_alloc (original_copy_bb_pool); 1135169689Skan (*slot)->index1 = bb->index; 1136169689Skan (*slot)->index2 = copy->index; 1137169689Skan } 1138169689Skan } 1139132718Skan} 1140132718Skan 1141169689Skan/* Get the copy of basic block. */ 1142132718Skanbasic_block 1143169689Skanget_bb_copy (basic_block bb) 1144132718Skan{ 1145169689Skan struct htab_bb_copy_original_entry *entry; 1146169689Skan struct htab_bb_copy_original_entry key; 1147169689Skan 1148169689Skan gcc_assert (original_copy_bb_pool); 1149169689Skan 1150169689Skan key.index1 = bb->index; 1151169689Skan entry = (struct htab_bb_copy_original_entry *) htab_find (bb_copy, &key); 1152169689Skan if (entry) 1153169689Skan return BASIC_BLOCK (entry->index2); 1154169689Skan else 1155169689Skan return NULL; 1156132718Skan} 1157