1 /* Convert RTL to assembler code and output it, for GNU compiler. 2 Copyright (C) 1987-2016 Free Software Foundation, Inc. 3 4 This file is part of GCC. 5 6 GCC is free software; you can redistribute it and/or modify it under 7 the terms of the GNU General Public License as published by the Free 8 Software Foundation; either version 3, or (at your option) any later 9 version. 10 11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GCC; see the file COPYING3. If not see 18 <http://www.gnu.org/licenses/>. */ 19 20 /* This is the final pass of the compiler. 21 It looks at the rtl code for a function and outputs assembler code. 22 23 Call `final_start_function' to output the assembler code for function entry, 24 `final' to output assembler code for some RTL code, 25 `final_end_function' to output assembler code for function exit. 26 If a function is compiled in several pieces, each piece is 27 output separately with `final'. 28 29 Some optimizations are also done at this level. 30 Move instructions that were made unnecessary by good register allocation 31 are detected and omitted from the output. (Though most of these 32 are removed by the last jump pass.) 33 34 Instructions to set the condition codes are omitted when it can be 35 seen that the condition codes already had the desired values. 36 37 In some cases it is sufficient if the inherited condition codes 38 have related values, but this may require the following insn 39 (the one that tests the condition codes) to be modified. 40 41 The code for the function prologue and epilogue are generated 42 directly in assembler by the target functions function_prologue and 43 function_epilogue. Those instructions never exist as rtl. */ 44 45 #include "config.h" 46 #define INCLUDE_ALGORITHM /* reverse */ 47 #include "system.h" 48 #include "coretypes.h" 49 #include "backend.h" 50 #include "target.h" 51 #include "rtl.h" 52 #include "tree.h" 53 #include "cfghooks.h" 54 #include "df.h" 55 #include "tm_p.h" 56 #include "insn-config.h" 57 #include "regs.h" 58 #include "emit-rtl.h" 59 #include "recog.h" 60 #include "cgraph.h" 61 #include "tree-pretty-print.h" /* for dump_function_header */ 62 #include "varasm.h" 63 #include "insn-attr.h" 64 #include "conditions.h" 65 #include "flags.h" 66 #include "output.h" 67 #include "except.h" 68 #include "rtl-error.h" 69 #include "toplev.h" /* exact_log2, floor_log2 */ 70 #include "reload.h" 71 #include "intl.h" 72 #include "cfgrtl.h" 73 #include "debug.h" 74 #include "tree-pass.h" 75 #include "tree-ssa.h" 76 #include "cfgloop.h" 77 #include "params.h" 78 #include "asan.h" 79 #include "rtl-iter.h" 80 #include "print-rtl.h" 81 82 #ifdef XCOFF_DEBUGGING_INFO 83 #include "xcoffout.h" /* Needed for external data declarations. */ 84 #endif 85 86 #include "dwarf2out.h" 87 88 #ifdef DBX_DEBUGGING_INFO 89 #include "dbxout.h" 90 #endif 91 92 #include "sdbout.h" 93 94 /* Most ports that aren't using cc0 don't need to define CC_STATUS_INIT. 95 So define a null default for it to save conditionalization later. */ 96 #ifndef CC_STATUS_INIT 97 #define CC_STATUS_INIT 98 #endif 99 100 /* Is the given character a logical line separator for the assembler? */ 101 #ifndef IS_ASM_LOGICAL_LINE_SEPARATOR 102 #define IS_ASM_LOGICAL_LINE_SEPARATOR(C, STR) ((C) == ';') 103 #endif 104 105 #ifndef JUMP_TABLES_IN_TEXT_SECTION 106 #define JUMP_TABLES_IN_TEXT_SECTION 0 107 #endif 108 109 /* Bitflags used by final_scan_insn. */ 110 #define SEEN_NOTE 1 111 #define SEEN_EMITTED 2 112 113 /* Last insn processed by final_scan_insn. */ 114 static rtx_insn *debug_insn; 115 rtx_insn *current_output_insn; 116 117 /* Line number of last NOTE. */ 118 static int last_linenum; 119 120 /* Last discriminator written to assembly. */ 121 static int last_discriminator; 122 123 /* Discriminator of current block. */ 124 static int discriminator; 125 126 /* Highest line number in current block. */ 127 static int high_block_linenum; 128 129 /* Likewise for function. */ 130 static int high_function_linenum; 131 132 /* Filename of last NOTE. */ 133 static const char *last_filename; 134 135 /* Override filename and line number. */ 136 static const char *override_filename; 137 static int override_linenum; 138 139 /* Whether to force emission of a line note before the next insn. */ 140 static bool force_source_line = false; 141 142 extern const int length_unit_log; /* This is defined in insn-attrtab.c. */ 143 144 /* Nonzero while outputting an `asm' with operands. 145 This means that inconsistencies are the user's fault, so don't die. 146 The precise value is the insn being output, to pass to error_for_asm. */ 147 const rtx_insn *this_is_asm_operands; 148 149 /* Number of operands of this insn, for an `asm' with operands. */ 150 static unsigned int insn_noperands; 151 152 /* Compare optimization flag. */ 153 154 static rtx last_ignored_compare = 0; 155 156 /* Assign a unique number to each insn that is output. 157 This can be used to generate unique local labels. */ 158 159 static int insn_counter = 0; 160 161 /* This variable contains machine-dependent flags (defined in tm.h) 162 set and examined by output routines 163 that describe how to interpret the condition codes properly. */ 164 165 CC_STATUS cc_status; 166 167 /* During output of an insn, this contains a copy of cc_status 168 from before the insn. */ 169 170 CC_STATUS cc_prev_status; 171 172 /* Number of unmatched NOTE_INSN_BLOCK_BEG notes we have seen. */ 173 174 static int block_depth; 175 176 /* Nonzero if have enabled APP processing of our assembler output. */ 177 178 static int app_on; 179 180 /* If we are outputting an insn sequence, this contains the sequence rtx. 181 Zero otherwise. */ 182 183 rtx_sequence *final_sequence; 184 185 #ifdef ASSEMBLER_DIALECT 186 187 /* Number of the assembler dialect to use, starting at 0. */ 188 static int dialect_number; 189 #endif 190 191 /* Nonnull if the insn currently being emitted was a COND_EXEC pattern. */ 192 rtx current_insn_predicate; 193 194 /* True if printing into -fdump-final-insns= dump. */ 195 bool final_insns_dump_p; 196 197 /* True if profile_function should be called, but hasn't been called yet. */ 198 static bool need_profile_function; 199 200 static int asm_insn_count (rtx); 201 static void profile_function (FILE *); 202 static void profile_after_prologue (FILE *); 203 static bool notice_source_line (rtx_insn *, bool *); 204 static rtx walk_alter_subreg (rtx *, bool *); 205 static void output_asm_name (void); 206 static void output_alternate_entry_point (FILE *, rtx_insn *); 207 static tree get_mem_expr_from_op (rtx, int *); 208 static void output_asm_operand_names (rtx *, int *, int); 209 #ifdef LEAF_REGISTERS 210 static void leaf_renumber_regs (rtx_insn *); 211 #endif 212 #if HAVE_cc0 213 static int alter_cond (rtx); 214 #endif 215 #ifndef ADDR_VEC_ALIGN 216 static int final_addr_vec_align (rtx); 217 #endif 218 static int align_fuzz (rtx, rtx, int, unsigned); 219 static void collect_fn_hard_reg_usage (void); 220 static tree get_call_fndecl (rtx_insn *); 221 222 /* Initialize data in final at the beginning of a compilation. */ 223 224 void 225 init_final (const char *filename ATTRIBUTE_UNUSED) 226 { 227 app_on = 0; 228 final_sequence = 0; 229 230 #ifdef ASSEMBLER_DIALECT 231 dialect_number = ASSEMBLER_DIALECT; 232 #endif 233 } 234 235 /* Default target function prologue and epilogue assembler output. 236 237 If not overridden for epilogue code, then the function body itself 238 contains return instructions wherever needed. */ 239 void 240 default_function_pro_epilogue (FILE *file ATTRIBUTE_UNUSED, 241 HOST_WIDE_INT size ATTRIBUTE_UNUSED) 242 { 243 } 244 245 void 246 default_function_switched_text_sections (FILE *file ATTRIBUTE_UNUSED, 247 tree decl ATTRIBUTE_UNUSED, 248 bool new_is_cold ATTRIBUTE_UNUSED) 249 { 250 } 251 252 /* Default target hook that outputs nothing to a stream. */ 253 void 254 no_asm_to_stream (FILE *file ATTRIBUTE_UNUSED) 255 { 256 } 257 258 /* Enable APP processing of subsequent output. 259 Used before the output from an `asm' statement. */ 260 261 void 262 app_enable (void) 263 { 264 if (! app_on) 265 { 266 fputs (ASM_APP_ON, asm_out_file); 267 app_on = 1; 268 } 269 } 270 271 /* Disable APP processing of subsequent output. 272 Called from varasm.c before most kinds of output. */ 273 274 void 275 app_disable (void) 276 { 277 if (app_on) 278 { 279 fputs (ASM_APP_OFF, asm_out_file); 280 app_on = 0; 281 } 282 } 283 284 /* Return the number of slots filled in the current 285 delayed branch sequence (we don't count the insn needing the 286 delay slot). Zero if not in a delayed branch sequence. */ 287 288 int 289 dbr_sequence_length (void) 290 { 291 if (final_sequence != 0) 292 return XVECLEN (final_sequence, 0) - 1; 293 else 294 return 0; 295 } 296 297 /* The next two pages contain routines used to compute the length of an insn 298 and to shorten branches. */ 299 300 /* Arrays for insn lengths, and addresses. The latter is referenced by 301 `insn_current_length'. */ 302 303 static int *insn_lengths; 304 305 vec<int> insn_addresses_; 306 307 /* Max uid for which the above arrays are valid. */ 308 static int insn_lengths_max_uid; 309 310 /* Address of insn being processed. Used by `insn_current_length'. */ 311 int insn_current_address; 312 313 /* Address of insn being processed in previous iteration. */ 314 int insn_last_address; 315 316 /* known invariant alignment of insn being processed. */ 317 int insn_current_align; 318 319 /* After shorten_branches, for any insn, uid_align[INSN_UID (insn)] 320 gives the next following alignment insn that increases the known 321 alignment, or NULL_RTX if there is no such insn. 322 For any alignment obtained this way, we can again index uid_align with 323 its uid to obtain the next following align that in turn increases the 324 alignment, till we reach NULL_RTX; the sequence obtained this way 325 for each insn we'll call the alignment chain of this insn in the following 326 comments. */ 327 328 struct label_alignment 329 { 330 short alignment; 331 short max_skip; 332 }; 333 334 static rtx *uid_align; 335 static int *uid_shuid; 336 static struct label_alignment *label_align; 337 338 /* Indicate that branch shortening hasn't yet been done. */ 339 340 void 341 init_insn_lengths (void) 342 { 343 if (uid_shuid) 344 { 345 free (uid_shuid); 346 uid_shuid = 0; 347 } 348 if (insn_lengths) 349 { 350 free (insn_lengths); 351 insn_lengths = 0; 352 insn_lengths_max_uid = 0; 353 } 354 if (HAVE_ATTR_length) 355 INSN_ADDRESSES_FREE (); 356 if (uid_align) 357 { 358 free (uid_align); 359 uid_align = 0; 360 } 361 } 362 363 /* Obtain the current length of an insn. If branch shortening has been done, 364 get its actual length. Otherwise, use FALLBACK_FN to calculate the 365 length. */ 366 static int 367 get_attr_length_1 (rtx_insn *insn, int (*fallback_fn) (rtx_insn *)) 368 { 369 rtx body; 370 int i; 371 int length = 0; 372 373 if (!HAVE_ATTR_length) 374 return 0; 375 376 if (insn_lengths_max_uid > INSN_UID (insn)) 377 return insn_lengths[INSN_UID (insn)]; 378 else 379 switch (GET_CODE (insn)) 380 { 381 case NOTE: 382 case BARRIER: 383 case CODE_LABEL: 384 case DEBUG_INSN: 385 return 0; 386 387 case CALL_INSN: 388 case JUMP_INSN: 389 length = fallback_fn (insn); 390 break; 391 392 case INSN: 393 body = PATTERN (insn); 394 if (GET_CODE (body) == USE || GET_CODE (body) == CLOBBER) 395 return 0; 396 397 else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0) 398 length = asm_insn_count (body) * fallback_fn (insn); 399 else if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (body)) 400 for (i = 0; i < seq->len (); i++) 401 length += get_attr_length_1 (seq->insn (i), fallback_fn); 402 else 403 length = fallback_fn (insn); 404 break; 405 406 default: 407 break; 408 } 409 410 #ifdef ADJUST_INSN_LENGTH 411 ADJUST_INSN_LENGTH (insn, length); 412 #endif 413 return length; 414 } 415 416 /* Obtain the current length of an insn. If branch shortening has been done, 417 get its actual length. Otherwise, get its maximum length. */ 418 int 419 get_attr_length (rtx_insn *insn) 420 { 421 return get_attr_length_1 (insn, insn_default_length); 422 } 423 424 /* Obtain the current length of an insn. If branch shortening has been done, 425 get its actual length. Otherwise, get its minimum length. */ 426 int 427 get_attr_min_length (rtx_insn *insn) 428 { 429 return get_attr_length_1 (insn, insn_min_length); 430 } 431 432 /* Code to handle alignment inside shorten_branches. */ 433 434 /* Here is an explanation how the algorithm in align_fuzz can give 435 proper results: 436 437 Call a sequence of instructions beginning with alignment point X 438 and continuing until the next alignment point `block X'. When `X' 439 is used in an expression, it means the alignment value of the 440 alignment point. 441 442 Call the distance between the start of the first insn of block X, and 443 the end of the last insn of block X `IX', for the `inner size of X'. 444 This is clearly the sum of the instruction lengths. 445 446 Likewise with the next alignment-delimited block following X, which we 447 shall call block Y. 448 449 Call the distance between the start of the first insn of block X, and 450 the start of the first insn of block Y `OX', for the `outer size of X'. 451 452 The estimated padding is then OX - IX. 453 454 OX can be safely estimated as 455 456 if (X >= Y) 457 OX = round_up(IX, Y) 458 else 459 OX = round_up(IX, X) + Y - X 460 461 Clearly est(IX) >= real(IX), because that only depends on the 462 instruction lengths, and those being overestimated is a given. 463 464 Clearly round_up(foo, Z) >= round_up(bar, Z) if foo >= bar, so 465 we needn't worry about that when thinking about OX. 466 467 When X >= Y, the alignment provided by Y adds no uncertainty factor 468 for branch ranges starting before X, so we can just round what we have. 469 But when X < Y, we don't know anything about the, so to speak, 470 `middle bits', so we have to assume the worst when aligning up from an 471 address mod X to one mod Y, which is Y - X. */ 472 473 #ifndef LABEL_ALIGN 474 #define LABEL_ALIGN(LABEL) align_labels_log 475 #endif 476 477 #ifndef LOOP_ALIGN 478 #define LOOP_ALIGN(LABEL) align_loops_log 479 #endif 480 481 #ifndef LABEL_ALIGN_AFTER_BARRIER 482 #define LABEL_ALIGN_AFTER_BARRIER(LABEL) 0 483 #endif 484 485 #ifndef JUMP_ALIGN 486 #define JUMP_ALIGN(LABEL) align_jumps_log 487 #endif 488 489 int 490 default_label_align_after_barrier_max_skip (rtx_insn *insn ATTRIBUTE_UNUSED) 491 { 492 return 0; 493 } 494 495 int 496 default_loop_align_max_skip (rtx_insn *insn ATTRIBUTE_UNUSED) 497 { 498 return align_loops_max_skip; 499 } 500 501 int 502 default_label_align_max_skip (rtx_insn *insn ATTRIBUTE_UNUSED) 503 { 504 return align_labels_max_skip; 505 } 506 507 int 508 default_jump_align_max_skip (rtx_insn *insn ATTRIBUTE_UNUSED) 509 { 510 return align_jumps_max_skip; 511 } 512 513 #ifndef ADDR_VEC_ALIGN 514 static int 515 final_addr_vec_align (rtx addr_vec) 516 { 517 int align = GET_MODE_SIZE (GET_MODE (PATTERN (addr_vec))); 518 519 if (align > BIGGEST_ALIGNMENT / BITS_PER_UNIT) 520 align = BIGGEST_ALIGNMENT / BITS_PER_UNIT; 521 return exact_log2 (align); 522 523 } 524 525 #define ADDR_VEC_ALIGN(ADDR_VEC) final_addr_vec_align (ADDR_VEC) 526 #endif 527 528 #ifndef INSN_LENGTH_ALIGNMENT 529 #define INSN_LENGTH_ALIGNMENT(INSN) length_unit_log 530 #endif 531 532 #define INSN_SHUID(INSN) (uid_shuid[INSN_UID (INSN)]) 533 534 static int min_labelno, max_labelno; 535 536 #define LABEL_TO_ALIGNMENT(LABEL) \ 537 (label_align[CODE_LABEL_NUMBER (LABEL) - min_labelno].alignment) 538 539 #define LABEL_TO_MAX_SKIP(LABEL) \ 540 (label_align[CODE_LABEL_NUMBER (LABEL) - min_labelno].max_skip) 541 542 /* For the benefit of port specific code do this also as a function. */ 543 544 int 545 label_to_alignment (rtx label) 546 { 547 if (CODE_LABEL_NUMBER (label) <= max_labelno) 548 return LABEL_TO_ALIGNMENT (label); 549 return 0; 550 } 551 552 int 553 label_to_max_skip (rtx label) 554 { 555 if (CODE_LABEL_NUMBER (label) <= max_labelno) 556 return LABEL_TO_MAX_SKIP (label); 557 return 0; 558 } 559 560 /* The differences in addresses 561 between a branch and its target might grow or shrink depending on 562 the alignment the start insn of the range (the branch for a forward 563 branch or the label for a backward branch) starts out on; if these 564 differences are used naively, they can even oscillate infinitely. 565 We therefore want to compute a 'worst case' address difference that 566 is independent of the alignment the start insn of the range end 567 up on, and that is at least as large as the actual difference. 568 The function align_fuzz calculates the amount we have to add to the 569 naively computed difference, by traversing the part of the alignment 570 chain of the start insn of the range that is in front of the end insn 571 of the range, and considering for each alignment the maximum amount 572 that it might contribute to a size increase. 573 574 For casesi tables, we also want to know worst case minimum amounts of 575 address difference, in case a machine description wants to introduce 576 some common offset that is added to all offsets in a table. 577 For this purpose, align_fuzz with a growth argument of 0 computes the 578 appropriate adjustment. */ 579 580 /* Compute the maximum delta by which the difference of the addresses of 581 START and END might grow / shrink due to a different address for start 582 which changes the size of alignment insns between START and END. 583 KNOWN_ALIGN_LOG is the alignment known for START. 584 GROWTH should be ~0 if the objective is to compute potential code size 585 increase, and 0 if the objective is to compute potential shrink. 586 The return value is undefined for any other value of GROWTH. */ 587 588 static int 589 align_fuzz (rtx start, rtx end, int known_align_log, unsigned int growth) 590 { 591 int uid = INSN_UID (start); 592 rtx align_label; 593 int known_align = 1 << known_align_log; 594 int end_shuid = INSN_SHUID (end); 595 int fuzz = 0; 596 597 for (align_label = uid_align[uid]; align_label; align_label = uid_align[uid]) 598 { 599 int align_addr, new_align; 600 601 uid = INSN_UID (align_label); 602 align_addr = INSN_ADDRESSES (uid) - insn_lengths[uid]; 603 if (uid_shuid[uid] > end_shuid) 604 break; 605 known_align_log = LABEL_TO_ALIGNMENT (align_label); 606 new_align = 1 << known_align_log; 607 if (new_align < known_align) 608 continue; 609 fuzz += (-align_addr ^ growth) & (new_align - known_align); 610 known_align = new_align; 611 } 612 return fuzz; 613 } 614 615 /* Compute a worst-case reference address of a branch so that it 616 can be safely used in the presence of aligned labels. Since the 617 size of the branch itself is unknown, the size of the branch is 618 not included in the range. I.e. for a forward branch, the reference 619 address is the end address of the branch as known from the previous 620 branch shortening pass, minus a value to account for possible size 621 increase due to alignment. For a backward branch, it is the start 622 address of the branch as known from the current pass, plus a value 623 to account for possible size increase due to alignment. 624 NB.: Therefore, the maximum offset allowed for backward branches needs 625 to exclude the branch size. */ 626 627 int 628 insn_current_reference_address (rtx_insn *branch) 629 { 630 rtx dest; 631 int seq_uid; 632 633 if (! INSN_ADDRESSES_SET_P ()) 634 return 0; 635 636 rtx_insn *seq = NEXT_INSN (PREV_INSN (branch)); 637 seq_uid = INSN_UID (seq); 638 if (!JUMP_P (branch)) 639 /* This can happen for example on the PA; the objective is to know the 640 offset to address something in front of the start of the function. 641 Thus, we can treat it like a backward branch. 642 We assume here that FUNCTION_BOUNDARY / BITS_PER_UNIT is larger than 643 any alignment we'd encounter, so we skip the call to align_fuzz. */ 644 return insn_current_address; 645 dest = JUMP_LABEL (branch); 646 647 /* BRANCH has no proper alignment chain set, so use SEQ. 648 BRANCH also has no INSN_SHUID. */ 649 if (INSN_SHUID (seq) < INSN_SHUID (dest)) 650 { 651 /* Forward branch. */ 652 return (insn_last_address + insn_lengths[seq_uid] 653 - align_fuzz (seq, dest, length_unit_log, ~0)); 654 } 655 else 656 { 657 /* Backward branch. */ 658 return (insn_current_address 659 + align_fuzz (dest, seq, length_unit_log, ~0)); 660 } 661 } 662 663 /* Compute branch alignments based on frequency information in the 664 CFG. */ 665 666 unsigned int 667 compute_alignments (void) 668 { 669 int log, max_skip, max_log; 670 basic_block bb; 671 int freq_max = 0; 672 int freq_threshold = 0; 673 674 if (label_align) 675 { 676 free (label_align); 677 label_align = 0; 678 } 679 680 max_labelno = max_label_num (); 681 min_labelno = get_first_label_num (); 682 label_align = XCNEWVEC (struct label_alignment, max_labelno - min_labelno + 1); 683 684 /* If not optimizing or optimizing for size, don't assign any alignments. */ 685 if (! optimize || optimize_function_for_size_p (cfun)) 686 return 0; 687 688 if (dump_file) 689 { 690 dump_reg_info (dump_file); 691 dump_flow_info (dump_file, TDF_DETAILS); 692 flow_loops_dump (dump_file, NULL, 1); 693 } 694 loop_optimizer_init (AVOID_CFG_MODIFICATIONS); 695 FOR_EACH_BB_FN (bb, cfun) 696 if (bb->frequency > freq_max) 697 freq_max = bb->frequency; 698 freq_threshold = freq_max / PARAM_VALUE (PARAM_ALIGN_THRESHOLD); 699 700 if (dump_file) 701 fprintf (dump_file, "freq_max: %i\n",freq_max); 702 FOR_EACH_BB_FN (bb, cfun) 703 { 704 rtx_insn *label = BB_HEAD (bb); 705 int fallthru_frequency = 0, branch_frequency = 0, has_fallthru = 0; 706 edge e; 707 edge_iterator ei; 708 709 if (!LABEL_P (label) 710 || optimize_bb_for_size_p (bb)) 711 { 712 if (dump_file) 713 fprintf (dump_file, 714 "BB %4i freq %4i loop %2i loop_depth %2i skipped.\n", 715 bb->index, bb->frequency, bb->loop_father->num, 716 bb_loop_depth (bb)); 717 continue; 718 } 719 max_log = LABEL_ALIGN (label); 720 max_skip = targetm.asm_out.label_align_max_skip (label); 721 722 FOR_EACH_EDGE (e, ei, bb->preds) 723 { 724 if (e->flags & EDGE_FALLTHRU) 725 has_fallthru = 1, fallthru_frequency += EDGE_FREQUENCY (e); 726 else 727 branch_frequency += EDGE_FREQUENCY (e); 728 } 729 if (dump_file) 730 { 731 fprintf (dump_file, "BB %4i freq %4i loop %2i loop_depth" 732 " %2i fall %4i branch %4i", 733 bb->index, bb->frequency, bb->loop_father->num, 734 bb_loop_depth (bb), 735 fallthru_frequency, branch_frequency); 736 if (!bb->loop_father->inner && bb->loop_father->num) 737 fprintf (dump_file, " inner_loop"); 738 if (bb->loop_father->header == bb) 739 fprintf (dump_file, " loop_header"); 740 fprintf (dump_file, "\n"); 741 } 742 743 /* There are two purposes to align block with no fallthru incoming edge: 744 1) to avoid fetch stalls when branch destination is near cache boundary 745 2) to improve cache efficiency in case the previous block is not executed 746 (so it does not need to be in the cache). 747 748 We to catch first case, we align frequently executed blocks. 749 To catch the second, we align blocks that are executed more frequently 750 than the predecessor and the predecessor is likely to not be executed 751 when function is called. */ 752 753 if (!has_fallthru 754 && (branch_frequency > freq_threshold 755 || (bb->frequency > bb->prev_bb->frequency * 10 756 && (bb->prev_bb->frequency 757 <= ENTRY_BLOCK_PTR_FOR_FN (cfun)->frequency / 2)))) 758 { 759 log = JUMP_ALIGN (label); 760 if (dump_file) 761 fprintf (dump_file, " jump alignment added.\n"); 762 if (max_log < log) 763 { 764 max_log = log; 765 max_skip = targetm.asm_out.jump_align_max_skip (label); 766 } 767 } 768 /* In case block is frequent and reached mostly by non-fallthru edge, 769 align it. It is most likely a first block of loop. */ 770 if (has_fallthru 771 && !(single_succ_p (bb) 772 && single_succ (bb) == EXIT_BLOCK_PTR_FOR_FN (cfun)) 773 && optimize_bb_for_speed_p (bb) 774 && branch_frequency + fallthru_frequency > freq_threshold 775 && (branch_frequency 776 > fallthru_frequency * PARAM_VALUE (PARAM_ALIGN_LOOP_ITERATIONS))) 777 { 778 log = LOOP_ALIGN (label); 779 if (dump_file) 780 fprintf (dump_file, " internal loop alignment added.\n"); 781 if (max_log < log) 782 { 783 max_log = log; 784 max_skip = targetm.asm_out.loop_align_max_skip (label); 785 } 786 } 787 LABEL_TO_ALIGNMENT (label) = max_log; 788 LABEL_TO_MAX_SKIP (label) = max_skip; 789 } 790 791 loop_optimizer_finalize (); 792 free_dominance_info (CDI_DOMINATORS); 793 return 0; 794 } 795 796 /* Grow the LABEL_ALIGN array after new labels are created. */ 797 798 static void 799 grow_label_align (void) 800 { 801 int old = max_labelno; 802 int n_labels; 803 int n_old_labels; 804 805 max_labelno = max_label_num (); 806 807 n_labels = max_labelno - min_labelno + 1; 808 n_old_labels = old - min_labelno + 1; 809 810 label_align = XRESIZEVEC (struct label_alignment, label_align, n_labels); 811 812 /* Range of labels grows monotonically in the function. Failing here 813 means that the initialization of array got lost. */ 814 gcc_assert (n_old_labels <= n_labels); 815 816 memset (label_align + n_old_labels, 0, 817 (n_labels - n_old_labels) * sizeof (struct label_alignment)); 818 } 819 820 /* Update the already computed alignment information. LABEL_PAIRS is a vector 821 made up of pairs of labels for which the alignment information of the first 822 element will be copied from that of the second element. */ 823 824 void 825 update_alignments (vec<rtx> &label_pairs) 826 { 827 unsigned int i = 0; 828 rtx iter, label = NULL_RTX; 829 830 if (max_labelno != max_label_num ()) 831 grow_label_align (); 832 833 FOR_EACH_VEC_ELT (label_pairs, i, iter) 834 if (i & 1) 835 { 836 LABEL_TO_ALIGNMENT (label) = LABEL_TO_ALIGNMENT (iter); 837 LABEL_TO_MAX_SKIP (label) = LABEL_TO_MAX_SKIP (iter); 838 } 839 else 840 label = iter; 841 } 842 843 namespace { 844 845 const pass_data pass_data_compute_alignments = 846 { 847 RTL_PASS, /* type */ 848 "alignments", /* name */ 849 OPTGROUP_NONE, /* optinfo_flags */ 850 TV_NONE, /* tv_id */ 851 0, /* properties_required */ 852 0, /* properties_provided */ 853 0, /* properties_destroyed */ 854 0, /* todo_flags_start */ 855 0, /* todo_flags_finish */ 856 }; 857 858 class pass_compute_alignments : public rtl_opt_pass 859 { 860 public: 861 pass_compute_alignments (gcc::context *ctxt) 862 : rtl_opt_pass (pass_data_compute_alignments, ctxt) 863 {} 864 865 /* opt_pass methods: */ 866 virtual unsigned int execute (function *) { return compute_alignments (); } 867 868 }; // class pass_compute_alignments 869 870 } // anon namespace 871 872 rtl_opt_pass * 873 make_pass_compute_alignments (gcc::context *ctxt) 874 { 875 return new pass_compute_alignments (ctxt); 876 } 877 878 879 /* Make a pass over all insns and compute their actual lengths by shortening 880 any branches of variable length if possible. */ 881 882 /* shorten_branches might be called multiple times: for example, the SH 883 port splits out-of-range conditional branches in MACHINE_DEPENDENT_REORG. 884 In order to do this, it needs proper length information, which it obtains 885 by calling shorten_branches. This cannot be collapsed with 886 shorten_branches itself into a single pass unless we also want to integrate 887 reorg.c, since the branch splitting exposes new instructions with delay 888 slots. */ 889 890 void 891 shorten_branches (rtx_insn *first) 892 { 893 rtx_insn *insn; 894 int max_uid; 895 int i; 896 int max_log; 897 int max_skip; 898 #define MAX_CODE_ALIGN 16 899 rtx_insn *seq; 900 int something_changed = 1; 901 char *varying_length; 902 rtx body; 903 int uid; 904 rtx align_tab[MAX_CODE_ALIGN + 1]; 905 906 /* Compute maximum UID and allocate label_align / uid_shuid. */ 907 max_uid = get_max_uid (); 908 909 /* Free uid_shuid before reallocating it. */ 910 free (uid_shuid); 911 912 uid_shuid = XNEWVEC (int, max_uid); 913 914 if (max_labelno != max_label_num ()) 915 grow_label_align (); 916 917 /* Initialize label_align and set up uid_shuid to be strictly 918 monotonically rising with insn order. */ 919 /* We use max_log here to keep track of the maximum alignment we want to 920 impose on the next CODE_LABEL (or the current one if we are processing 921 the CODE_LABEL itself). */ 922 923 max_log = 0; 924 max_skip = 0; 925 926 for (insn = get_insns (), i = 1; insn; insn = NEXT_INSN (insn)) 927 { 928 int log; 929 930 INSN_SHUID (insn) = i++; 931 if (INSN_P (insn)) 932 continue; 933 934 if (LABEL_P (insn)) 935 { 936 rtx_insn *next; 937 bool next_is_jumptable; 938 939 /* Merge in alignments computed by compute_alignments. */ 940 log = LABEL_TO_ALIGNMENT (insn); 941 if (max_log < log) 942 { 943 max_log = log; 944 max_skip = LABEL_TO_MAX_SKIP (insn); 945 } 946 947 next = next_nonnote_insn (insn); 948 next_is_jumptable = next && JUMP_TABLE_DATA_P (next); 949 if (!next_is_jumptable) 950 { 951 log = LABEL_ALIGN (insn); 952 if (max_log < log) 953 { 954 max_log = log; 955 max_skip = targetm.asm_out.label_align_max_skip (insn); 956 } 957 } 958 /* ADDR_VECs only take room if read-only data goes into the text 959 section. */ 960 if ((JUMP_TABLES_IN_TEXT_SECTION 961 || readonly_data_section == text_section) 962 && next_is_jumptable) 963 { 964 log = ADDR_VEC_ALIGN (next); 965 if (max_log < log) 966 { 967 max_log = log; 968 max_skip = targetm.asm_out.label_align_max_skip (insn); 969 } 970 } 971 LABEL_TO_ALIGNMENT (insn) = max_log; 972 LABEL_TO_MAX_SKIP (insn) = max_skip; 973 max_log = 0; 974 max_skip = 0; 975 } 976 else if (BARRIER_P (insn)) 977 { 978 rtx_insn *label; 979 980 for (label = insn; label && ! INSN_P (label); 981 label = NEXT_INSN (label)) 982 if (LABEL_P (label)) 983 { 984 log = LABEL_ALIGN_AFTER_BARRIER (insn); 985 if (max_log < log) 986 { 987 max_log = log; 988 max_skip = targetm.asm_out.label_align_after_barrier_max_skip (label); 989 } 990 break; 991 } 992 } 993 } 994 if (!HAVE_ATTR_length) 995 return; 996 997 /* Allocate the rest of the arrays. */ 998 insn_lengths = XNEWVEC (int, max_uid); 999 insn_lengths_max_uid = max_uid; 1000 /* Syntax errors can lead to labels being outside of the main insn stream. 1001 Initialize insn_addresses, so that we get reproducible results. */ 1002 INSN_ADDRESSES_ALLOC (max_uid); 1003 1004 varying_length = XCNEWVEC (char, max_uid); 1005 1006 /* Initialize uid_align. We scan instructions 1007 from end to start, and keep in align_tab[n] the last seen insn 1008 that does an alignment of at least n+1, i.e. the successor 1009 in the alignment chain for an insn that does / has a known 1010 alignment of n. */ 1011 uid_align = XCNEWVEC (rtx, max_uid); 1012 1013 for (i = MAX_CODE_ALIGN + 1; --i >= 0;) 1014 align_tab[i] = NULL_RTX; 1015 seq = get_last_insn (); 1016 for (; seq; seq = PREV_INSN (seq)) 1017 { 1018 int uid = INSN_UID (seq); 1019 int log; 1020 log = (LABEL_P (seq) ? LABEL_TO_ALIGNMENT (seq) : 0); 1021 uid_align[uid] = align_tab[0]; 1022 if (log) 1023 { 1024 /* Found an alignment label. */ 1025 uid_align[uid] = align_tab[log]; 1026 for (i = log - 1; i >= 0; i--) 1027 align_tab[i] = seq; 1028 } 1029 } 1030 1031 /* When optimizing, we start assuming minimum length, and keep increasing 1032 lengths as we find the need for this, till nothing changes. 1033 When not optimizing, we start assuming maximum lengths, and 1034 do a single pass to update the lengths. */ 1035 bool increasing = optimize != 0; 1036 1037 #ifdef CASE_VECTOR_SHORTEN_MODE 1038 if (optimize) 1039 { 1040 /* Look for ADDR_DIFF_VECs, and initialize their minimum and maximum 1041 label fields. */ 1042 1043 int min_shuid = INSN_SHUID (get_insns ()) - 1; 1044 int max_shuid = INSN_SHUID (get_last_insn ()) + 1; 1045 int rel; 1046 1047 for (insn = first; insn != 0; insn = NEXT_INSN (insn)) 1048 { 1049 rtx min_lab = NULL_RTX, max_lab = NULL_RTX, pat; 1050 int len, i, min, max, insn_shuid; 1051 int min_align; 1052 addr_diff_vec_flags flags; 1053 1054 if (! JUMP_TABLE_DATA_P (insn) 1055 || GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC) 1056 continue; 1057 pat = PATTERN (insn); 1058 len = XVECLEN (pat, 1); 1059 gcc_assert (len > 0); 1060 min_align = MAX_CODE_ALIGN; 1061 for (min = max_shuid, max = min_shuid, i = len - 1; i >= 0; i--) 1062 { 1063 rtx lab = XEXP (XVECEXP (pat, 1, i), 0); 1064 int shuid = INSN_SHUID (lab); 1065 if (shuid < min) 1066 { 1067 min = shuid; 1068 min_lab = lab; 1069 } 1070 if (shuid > max) 1071 { 1072 max = shuid; 1073 max_lab = lab; 1074 } 1075 if (min_align > LABEL_TO_ALIGNMENT (lab)) 1076 min_align = LABEL_TO_ALIGNMENT (lab); 1077 } 1078 XEXP (pat, 2) = gen_rtx_LABEL_REF (Pmode, min_lab); 1079 XEXP (pat, 3) = gen_rtx_LABEL_REF (Pmode, max_lab); 1080 insn_shuid = INSN_SHUID (insn); 1081 rel = INSN_SHUID (XEXP (XEXP (pat, 0), 0)); 1082 memset (&flags, 0, sizeof (flags)); 1083 flags.min_align = min_align; 1084 flags.base_after_vec = rel > insn_shuid; 1085 flags.min_after_vec = min > insn_shuid; 1086 flags.max_after_vec = max > insn_shuid; 1087 flags.min_after_base = min > rel; 1088 flags.max_after_base = max > rel; 1089 ADDR_DIFF_VEC_FLAGS (pat) = flags; 1090 1091 if (increasing) 1092 PUT_MODE (pat, CASE_VECTOR_SHORTEN_MODE (0, 0, pat)); 1093 } 1094 } 1095 #endif /* CASE_VECTOR_SHORTEN_MODE */ 1096 1097 /* Compute initial lengths, addresses, and varying flags for each insn. */ 1098 int (*length_fun) (rtx_insn *) = increasing ? insn_min_length : insn_default_length; 1099 1100 for (insn_current_address = 0, insn = first; 1101 insn != 0; 1102 insn_current_address += insn_lengths[uid], insn = NEXT_INSN (insn)) 1103 { 1104 uid = INSN_UID (insn); 1105 1106 insn_lengths[uid] = 0; 1107 1108 if (LABEL_P (insn)) 1109 { 1110 int log = LABEL_TO_ALIGNMENT (insn); 1111 if (log) 1112 { 1113 int align = 1 << log; 1114 int new_address = (insn_current_address + align - 1) & -align; 1115 insn_lengths[uid] = new_address - insn_current_address; 1116 } 1117 } 1118 1119 INSN_ADDRESSES (uid) = insn_current_address + insn_lengths[uid]; 1120 1121 if (NOTE_P (insn) || BARRIER_P (insn) 1122 || LABEL_P (insn) || DEBUG_INSN_P (insn)) 1123 continue; 1124 if (insn->deleted ()) 1125 continue; 1126 1127 body = PATTERN (insn); 1128 if (JUMP_TABLE_DATA_P (insn)) 1129 { 1130 /* This only takes room if read-only data goes into the text 1131 section. */ 1132 if (JUMP_TABLES_IN_TEXT_SECTION 1133 || readonly_data_section == text_section) 1134 insn_lengths[uid] = (XVECLEN (body, 1135 GET_CODE (body) == ADDR_DIFF_VEC) 1136 * GET_MODE_SIZE (GET_MODE (body))); 1137 /* Alignment is handled by ADDR_VEC_ALIGN. */ 1138 } 1139 else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0) 1140 insn_lengths[uid] = asm_insn_count (body) * insn_default_length (insn); 1141 else if (rtx_sequence *body_seq = dyn_cast <rtx_sequence *> (body)) 1142 { 1143 int i; 1144 int const_delay_slots; 1145 if (DELAY_SLOTS) 1146 const_delay_slots = const_num_delay_slots (body_seq->insn (0)); 1147 else 1148 const_delay_slots = 0; 1149 1150 int (*inner_length_fun) (rtx_insn *) 1151 = const_delay_slots ? length_fun : insn_default_length; 1152 /* Inside a delay slot sequence, we do not do any branch shortening 1153 if the shortening could change the number of delay slots 1154 of the branch. */ 1155 for (i = 0; i < body_seq->len (); i++) 1156 { 1157 rtx_insn *inner_insn = body_seq->insn (i); 1158 int inner_uid = INSN_UID (inner_insn); 1159 int inner_length; 1160 1161 if (GET_CODE (PATTERN (inner_insn)) == ASM_INPUT 1162 || asm_noperands (PATTERN (inner_insn)) >= 0) 1163 inner_length = (asm_insn_count (PATTERN (inner_insn)) 1164 * insn_default_length (inner_insn)); 1165 else 1166 inner_length = inner_length_fun (inner_insn); 1167 1168 insn_lengths[inner_uid] = inner_length; 1169 if (const_delay_slots) 1170 { 1171 if ((varying_length[inner_uid] 1172 = insn_variable_length_p (inner_insn)) != 0) 1173 varying_length[uid] = 1; 1174 INSN_ADDRESSES (inner_uid) = (insn_current_address 1175 + insn_lengths[uid]); 1176 } 1177 else 1178 varying_length[inner_uid] = 0; 1179 insn_lengths[uid] += inner_length; 1180 } 1181 } 1182 else if (GET_CODE (body) != USE && GET_CODE (body) != CLOBBER) 1183 { 1184 insn_lengths[uid] = length_fun (insn); 1185 varying_length[uid] = insn_variable_length_p (insn); 1186 } 1187 1188 /* If needed, do any adjustment. */ 1189 #ifdef ADJUST_INSN_LENGTH 1190 ADJUST_INSN_LENGTH (insn, insn_lengths[uid]); 1191 if (insn_lengths[uid] < 0) 1192 fatal_insn ("negative insn length", insn); 1193 #endif 1194 } 1195 1196 /* Now loop over all the insns finding varying length insns. For each, 1197 get the current insn length. If it has changed, reflect the change. 1198 When nothing changes for a full pass, we are done. */ 1199 1200 while (something_changed) 1201 { 1202 something_changed = 0; 1203 insn_current_align = MAX_CODE_ALIGN - 1; 1204 for (insn_current_address = 0, insn = first; 1205 insn != 0; 1206 insn = NEXT_INSN (insn)) 1207 { 1208 int new_length; 1209 #ifdef ADJUST_INSN_LENGTH 1210 int tmp_length; 1211 #endif 1212 int length_align; 1213 1214 uid = INSN_UID (insn); 1215 1216 if (LABEL_P (insn)) 1217 { 1218 int log = LABEL_TO_ALIGNMENT (insn); 1219 1220 #ifdef CASE_VECTOR_SHORTEN_MODE 1221 /* If the mode of a following jump table was changed, we 1222 may need to update the alignment of this label. */ 1223 rtx_insn *next; 1224 bool next_is_jumptable; 1225 1226 next = next_nonnote_insn (insn); 1227 next_is_jumptable = next && JUMP_TABLE_DATA_P (next); 1228 if ((JUMP_TABLES_IN_TEXT_SECTION 1229 || readonly_data_section == text_section) 1230 && next_is_jumptable) 1231 { 1232 int newlog = ADDR_VEC_ALIGN (next); 1233 if (newlog != log) 1234 { 1235 log = newlog; 1236 LABEL_TO_ALIGNMENT (insn) = log; 1237 something_changed = 1; 1238 } 1239 } 1240 #endif 1241 1242 if (log > insn_current_align) 1243 { 1244 int align = 1 << log; 1245 int new_address= (insn_current_address + align - 1) & -align; 1246 insn_lengths[uid] = new_address - insn_current_address; 1247 insn_current_align = log; 1248 insn_current_address = new_address; 1249 } 1250 else 1251 insn_lengths[uid] = 0; 1252 INSN_ADDRESSES (uid) = insn_current_address; 1253 continue; 1254 } 1255 1256 length_align = INSN_LENGTH_ALIGNMENT (insn); 1257 if (length_align < insn_current_align) 1258 insn_current_align = length_align; 1259 1260 insn_last_address = INSN_ADDRESSES (uid); 1261 INSN_ADDRESSES (uid) = insn_current_address; 1262 1263 #ifdef CASE_VECTOR_SHORTEN_MODE 1264 if (optimize 1265 && JUMP_TABLE_DATA_P (insn) 1266 && GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC) 1267 { 1268 rtx body = PATTERN (insn); 1269 int old_length = insn_lengths[uid]; 1270 rtx_insn *rel_lab = 1271 safe_as_a <rtx_insn *> (XEXP (XEXP (body, 0), 0)); 1272 rtx min_lab = XEXP (XEXP (body, 2), 0); 1273 rtx max_lab = XEXP (XEXP (body, 3), 0); 1274 int rel_addr = INSN_ADDRESSES (INSN_UID (rel_lab)); 1275 int min_addr = INSN_ADDRESSES (INSN_UID (min_lab)); 1276 int max_addr = INSN_ADDRESSES (INSN_UID (max_lab)); 1277 rtx_insn *prev; 1278 int rel_align = 0; 1279 addr_diff_vec_flags flags; 1280 machine_mode vec_mode; 1281 1282 /* Avoid automatic aggregate initialization. */ 1283 flags = ADDR_DIFF_VEC_FLAGS (body); 1284 1285 /* Try to find a known alignment for rel_lab. */ 1286 for (prev = rel_lab; 1287 prev 1288 && ! insn_lengths[INSN_UID (prev)] 1289 && ! (varying_length[INSN_UID (prev)] & 1); 1290 prev = PREV_INSN (prev)) 1291 if (varying_length[INSN_UID (prev)] & 2) 1292 { 1293 rel_align = LABEL_TO_ALIGNMENT (prev); 1294 break; 1295 } 1296 1297 /* See the comment on addr_diff_vec_flags in rtl.h for the 1298 meaning of the flags values. base: REL_LAB vec: INSN */ 1299 /* Anything after INSN has still addresses from the last 1300 pass; adjust these so that they reflect our current 1301 estimate for this pass. */ 1302 if (flags.base_after_vec) 1303 rel_addr += insn_current_address - insn_last_address; 1304 if (flags.min_after_vec) 1305 min_addr += insn_current_address - insn_last_address; 1306 if (flags.max_after_vec) 1307 max_addr += insn_current_address - insn_last_address; 1308 /* We want to know the worst case, i.e. lowest possible value 1309 for the offset of MIN_LAB. If MIN_LAB is after REL_LAB, 1310 its offset is positive, and we have to be wary of code shrink; 1311 otherwise, it is negative, and we have to be vary of code 1312 size increase. */ 1313 if (flags.min_after_base) 1314 { 1315 /* If INSN is between REL_LAB and MIN_LAB, the size 1316 changes we are about to make can change the alignment 1317 within the observed offset, therefore we have to break 1318 it up into two parts that are independent. */ 1319 if (! flags.base_after_vec && flags.min_after_vec) 1320 { 1321 min_addr -= align_fuzz (rel_lab, insn, rel_align, 0); 1322 min_addr -= align_fuzz (insn, min_lab, 0, 0); 1323 } 1324 else 1325 min_addr -= align_fuzz (rel_lab, min_lab, rel_align, 0); 1326 } 1327 else 1328 { 1329 if (flags.base_after_vec && ! flags.min_after_vec) 1330 { 1331 min_addr -= align_fuzz (min_lab, insn, 0, ~0); 1332 min_addr -= align_fuzz (insn, rel_lab, 0, ~0); 1333 } 1334 else 1335 min_addr -= align_fuzz (min_lab, rel_lab, 0, ~0); 1336 } 1337 /* Likewise, determine the highest lowest possible value 1338 for the offset of MAX_LAB. */ 1339 if (flags.max_after_base) 1340 { 1341 if (! flags.base_after_vec && flags.max_after_vec) 1342 { 1343 max_addr += align_fuzz (rel_lab, insn, rel_align, ~0); 1344 max_addr += align_fuzz (insn, max_lab, 0, ~0); 1345 } 1346 else 1347 max_addr += align_fuzz (rel_lab, max_lab, rel_align, ~0); 1348 } 1349 else 1350 { 1351 if (flags.base_after_vec && ! flags.max_after_vec) 1352 { 1353 max_addr += align_fuzz (max_lab, insn, 0, 0); 1354 max_addr += align_fuzz (insn, rel_lab, 0, 0); 1355 } 1356 else 1357 max_addr += align_fuzz (max_lab, rel_lab, 0, 0); 1358 } 1359 vec_mode = CASE_VECTOR_SHORTEN_MODE (min_addr - rel_addr, 1360 max_addr - rel_addr, body); 1361 if (!increasing 1362 || (GET_MODE_SIZE (vec_mode) 1363 >= GET_MODE_SIZE (GET_MODE (body)))) 1364 PUT_MODE (body, vec_mode); 1365 if (JUMP_TABLES_IN_TEXT_SECTION 1366 || readonly_data_section == text_section) 1367 { 1368 insn_lengths[uid] 1369 = (XVECLEN (body, 1) * GET_MODE_SIZE (GET_MODE (body))); 1370 insn_current_address += insn_lengths[uid]; 1371 if (insn_lengths[uid] != old_length) 1372 something_changed = 1; 1373 } 1374 1375 continue; 1376 } 1377 #endif /* CASE_VECTOR_SHORTEN_MODE */ 1378 1379 if (! (varying_length[uid])) 1380 { 1381 if (NONJUMP_INSN_P (insn) 1382 && GET_CODE (PATTERN (insn)) == SEQUENCE) 1383 { 1384 int i; 1385 1386 body = PATTERN (insn); 1387 for (i = 0; i < XVECLEN (body, 0); i++) 1388 { 1389 rtx inner_insn = XVECEXP (body, 0, i); 1390 int inner_uid = INSN_UID (inner_insn); 1391 1392 INSN_ADDRESSES (inner_uid) = insn_current_address; 1393 1394 insn_current_address += insn_lengths[inner_uid]; 1395 } 1396 } 1397 else 1398 insn_current_address += insn_lengths[uid]; 1399 1400 continue; 1401 } 1402 1403 if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE) 1404 { 1405 rtx_sequence *seqn = as_a <rtx_sequence *> (PATTERN (insn)); 1406 int i; 1407 1408 body = PATTERN (insn); 1409 new_length = 0; 1410 for (i = 0; i < seqn->len (); i++) 1411 { 1412 rtx_insn *inner_insn = seqn->insn (i); 1413 int inner_uid = INSN_UID (inner_insn); 1414 int inner_length; 1415 1416 INSN_ADDRESSES (inner_uid) = insn_current_address; 1417 1418 /* insn_current_length returns 0 for insns with a 1419 non-varying length. */ 1420 if (! varying_length[inner_uid]) 1421 inner_length = insn_lengths[inner_uid]; 1422 else 1423 inner_length = insn_current_length (inner_insn); 1424 1425 if (inner_length != insn_lengths[inner_uid]) 1426 { 1427 if (!increasing || inner_length > insn_lengths[inner_uid]) 1428 { 1429 insn_lengths[inner_uid] = inner_length; 1430 something_changed = 1; 1431 } 1432 else 1433 inner_length = insn_lengths[inner_uid]; 1434 } 1435 insn_current_address += inner_length; 1436 new_length += inner_length; 1437 } 1438 } 1439 else 1440 { 1441 new_length = insn_current_length (insn); 1442 insn_current_address += new_length; 1443 } 1444 1445 #ifdef ADJUST_INSN_LENGTH 1446 /* If needed, do any adjustment. */ 1447 tmp_length = new_length; 1448 ADJUST_INSN_LENGTH (insn, new_length); 1449 insn_current_address += (new_length - tmp_length); 1450 #endif 1451 1452 if (new_length != insn_lengths[uid] 1453 && (!increasing || new_length > insn_lengths[uid])) 1454 { 1455 insn_lengths[uid] = new_length; 1456 something_changed = 1; 1457 } 1458 else 1459 insn_current_address += insn_lengths[uid] - new_length; 1460 } 1461 /* For a non-optimizing compile, do only a single pass. */ 1462 if (!increasing) 1463 break; 1464 } 1465 1466 free (varying_length); 1467 } 1468 1469 /* Given the body of an INSN known to be generated by an ASM statement, return 1470 the number of machine instructions likely to be generated for this insn. 1471 This is used to compute its length. */ 1472 1473 static int 1474 asm_insn_count (rtx body) 1475 { 1476 const char *templ; 1477 1478 if (GET_CODE (body) == ASM_INPUT) 1479 templ = XSTR (body, 0); 1480 else 1481 templ = decode_asm_operands (body, NULL, NULL, NULL, NULL, NULL); 1482 1483 return asm_str_count (templ); 1484 } 1485 1486 /* Return the number of machine instructions likely to be generated for the 1487 inline-asm template. */ 1488 int 1489 asm_str_count (const char *templ) 1490 { 1491 int count = 1; 1492 1493 if (!*templ) 1494 return 0; 1495 1496 for (; *templ; templ++) 1497 if (IS_ASM_LOGICAL_LINE_SEPARATOR (*templ, templ) 1498 || *templ == '\n') 1499 count++; 1500 1501 return count; 1502 } 1503 1504 /* ??? This is probably the wrong place for these. */ 1505 /* Structure recording the mapping from source file and directory 1506 names at compile time to those to be embedded in debug 1507 information. */ 1508 struct debug_prefix_map 1509 { 1510 const char *old_prefix; 1511 const char *new_prefix; 1512 size_t old_len; 1513 size_t new_len; 1514 struct debug_prefix_map *next; 1515 }; 1516 1517 /* Linked list of such structures. */ 1518 static debug_prefix_map *debug_prefix_maps; 1519 1520 1521 /* Record a debug file prefix mapping. ARG is the argument to 1522 -fdebug-prefix-map and must be of the form OLD=NEW. */ 1523 1524 void 1525 add_debug_prefix_map (const char *arg) 1526 { 1527 debug_prefix_map *map; 1528 const char *p; 1529 char *env; 1530 const char *old; 1531 size_t oldlen; 1532 1533 p = strchr (arg, '='); 1534 if (!p) 1535 { 1536 error ("invalid argument %qs to -fdebug-prefix-map", arg); 1537 return; 1538 } 1539 if (*arg == '$') 1540 { 1541 env = xstrndup (arg+1, p - (arg+1)); 1542 old = getenv(env); 1543 if (!old) 1544 { 1545 warning (0, "environment variable %qs not set in argument to " 1546 "-fdebug-prefix-map", env); 1547 free(env); 1548 return; 1549 } 1550 oldlen = strlen(old); 1551 free(env); 1552 } 1553 else 1554 { 1555 old = xstrndup (arg, p - arg); 1556 oldlen = p - arg; 1557 } 1558 1559 map = XNEW (debug_prefix_map); 1560 map->old_prefix = old; 1561 map->old_len = oldlen; 1562 p++; 1563 map->new_prefix = xstrdup (p); 1564 map->new_len = strlen (p); 1565 map->next = debug_prefix_maps; 1566 debug_prefix_maps = map; 1567 } 1568 1569 /* Perform user-specified mapping of debug filename prefixes. Return 1570 the new name corresponding to FILENAME. */ 1571 1572 static const char * 1573 remap_debug_prefix_filename (const char *filename) 1574 { 1575 debug_prefix_map *map; 1576 char *s; 1577 const char *name; 1578 size_t name_len; 1579 1580 for (map = debug_prefix_maps; map; map = map->next) 1581 if (filename_ncmp (filename, map->old_prefix, map->old_len) == 0) 1582 break; 1583 if (!map) 1584 return filename; 1585 name = filename + map->old_len; 1586 name_len = strlen (name) + 1; 1587 s = (char *) alloca (name_len + map->new_len); 1588 memcpy (s, map->new_prefix, map->new_len); 1589 memcpy (s + map->new_len, name, name_len); 1590 return ggc_strdup (s); 1591 } 1592 1593 #include <regex.h> 1594 1595 typedef struct debug_regex_map 1596 { 1597 regex_t re; 1598 const char *sub; 1599 struct debug_regex_map *next; 1600 } debug_regex_map; 1601 1602 /* Linked list of such structures. */ 1603 debug_regex_map *debug_regex_maps; 1604 1605 1606 /* Record a debug file regex mapping. ARG is the argument to 1607 -fdebug-regex-map and must be of the form OLD=NEW. */ 1608 1609 void 1610 add_debug_regex_map (const char *arg) 1611 { 1612 debug_regex_map *map; 1613 const char *p; 1614 char *old; 1615 char buf[1024]; 1616 regex_t re; 1617 int e; 1618 1619 p = strchr (arg, '='); 1620 if (!p) 1621 { 1622 error ("invalid argument %qs to -fdebug-regex-map", arg); 1623 return; 1624 } 1625 1626 old = xstrndup (arg, p - arg); 1627 if ((e = regcomp(&re, old, REG_EXTENDED)) != 0) 1628 { 1629 regerror(e, &re, buf, sizeof(buf)); 1630 warning (0, "regular expression compilation for %qs in argument to " 1631 "-fdebug-regex-map failed: %qs", old, buf); 1632 free(old); 1633 return; 1634 } 1635 free(old); 1636 1637 map = XNEW (debug_regex_map); 1638 map->re = re; 1639 p++; 1640 map->sub = xstrdup (p); 1641 map->next = debug_regex_maps; 1642 debug_regex_maps = map; 1643 } 1644 1645 extern "C" ssize_t regasub(char **, const char *, 1646 const regmatch_t *rm, const char *); 1647 1648 /* Perform user-specified mapping of debug filename regular expressions. Return 1649 the new name corresponding to FILENAME. */ 1650 1651 static const char * 1652 remap_debug_regex_filename (const char *filename) 1653 { 1654 debug_regex_map *map; 1655 char *s; 1656 regmatch_t rm[10]; 1657 1658 for (map = debug_regex_maps; map; map = map->next) 1659 if (regexec (&map->re, filename, 10, rm, 0) == 0 1660 && regasub (&s, map->sub, rm, filename) >= 0) 1661 { 1662 const char *name = ggc_strdup(s); 1663 free(s); 1664 return name; 1665 } 1666 return filename; 1667 } 1668 1669 const char * 1670 remap_debug_filename (const char *filename) 1671 { 1672 return remap_debug_regex_filename (remap_debug_prefix_filename (filename)); 1673 } 1674 1675 /* Return true if DWARF2 debug info can be emitted for DECL. */ 1676 1677 static bool 1678 dwarf2_debug_info_emitted_p (tree decl) 1679 { 1680 if (write_symbols != DWARF2_DEBUG && write_symbols != VMS_AND_DWARF2_DEBUG) 1681 return false; 1682 1683 if (DECL_IGNORED_P (decl)) 1684 return false; 1685 1686 return true; 1687 } 1688 1689 /* Return scope resulting from combination of S1 and S2. */ 1690 static tree 1691 choose_inner_scope (tree s1, tree s2) 1692 { 1693 if (!s1) 1694 return s2; 1695 if (!s2) 1696 return s1; 1697 if (BLOCK_NUMBER (s1) > BLOCK_NUMBER (s2)) 1698 return s1; 1699 return s2; 1700 } 1701 1702 /* Emit lexical block notes needed to change scope from S1 to S2. */ 1703 1704 static void 1705 change_scope (rtx_insn *orig_insn, tree s1, tree s2) 1706 { 1707 rtx_insn *insn = orig_insn; 1708 tree com = NULL_TREE; 1709 tree ts1 = s1, ts2 = s2; 1710 tree s; 1711 1712 while (ts1 != ts2) 1713 { 1714 gcc_assert (ts1 && ts2); 1715 if (BLOCK_NUMBER (ts1) > BLOCK_NUMBER (ts2)) 1716 ts1 = BLOCK_SUPERCONTEXT (ts1); 1717 else if (BLOCK_NUMBER (ts1) < BLOCK_NUMBER (ts2)) 1718 ts2 = BLOCK_SUPERCONTEXT (ts2); 1719 else 1720 { 1721 ts1 = BLOCK_SUPERCONTEXT (ts1); 1722 ts2 = BLOCK_SUPERCONTEXT (ts2); 1723 } 1724 } 1725 com = ts1; 1726 1727 /* Close scopes. */ 1728 s = s1; 1729 while (s != com) 1730 { 1731 rtx_note *note = emit_note_before (NOTE_INSN_BLOCK_END, insn); 1732 NOTE_BLOCK (note) = s; 1733 s = BLOCK_SUPERCONTEXT (s); 1734 } 1735 1736 /* Open scopes. */ 1737 s = s2; 1738 while (s != com) 1739 { 1740 insn = emit_note_before (NOTE_INSN_BLOCK_BEG, insn); 1741 NOTE_BLOCK (insn) = s; 1742 s = BLOCK_SUPERCONTEXT (s); 1743 } 1744 } 1745 1746 /* Rebuild all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes based 1747 on the scope tree and the newly reordered instructions. */ 1748 1749 static void 1750 reemit_insn_block_notes (void) 1751 { 1752 tree cur_block = DECL_INITIAL (cfun->decl); 1753 rtx_insn *insn; 1754 rtx_note *note; 1755 1756 insn = get_insns (); 1757 for (; insn; insn = NEXT_INSN (insn)) 1758 { 1759 tree this_block; 1760 1761 /* Prevent lexical blocks from straddling section boundaries. */ 1762 if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS) 1763 { 1764 for (tree s = cur_block; s != DECL_INITIAL (cfun->decl); 1765 s = BLOCK_SUPERCONTEXT (s)) 1766 { 1767 rtx_note *note = emit_note_before (NOTE_INSN_BLOCK_END, insn); 1768 NOTE_BLOCK (note) = s; 1769 note = emit_note_after (NOTE_INSN_BLOCK_BEG, insn); 1770 NOTE_BLOCK (note) = s; 1771 } 1772 } 1773 1774 if (!active_insn_p (insn)) 1775 continue; 1776 1777 /* Avoid putting scope notes between jump table and its label. */ 1778 if (JUMP_TABLE_DATA_P (insn)) 1779 continue; 1780 1781 this_block = insn_scope (insn); 1782 /* For sequences compute scope resulting from merging all scopes 1783 of instructions nested inside. */ 1784 if (rtx_sequence *body = dyn_cast <rtx_sequence *> (PATTERN (insn))) 1785 { 1786 int i; 1787 1788 this_block = NULL; 1789 for (i = 0; i < body->len (); i++) 1790 this_block = choose_inner_scope (this_block, 1791 insn_scope (body->insn (i))); 1792 } 1793 if (! this_block) 1794 { 1795 if (INSN_LOCATION (insn) == UNKNOWN_LOCATION) 1796 continue; 1797 else 1798 this_block = DECL_INITIAL (cfun->decl); 1799 } 1800 1801 if (this_block != cur_block) 1802 { 1803 change_scope (insn, cur_block, this_block); 1804 cur_block = this_block; 1805 } 1806 } 1807 1808 /* change_scope emits before the insn, not after. */ 1809 note = emit_note (NOTE_INSN_DELETED); 1810 change_scope (note, cur_block, DECL_INITIAL (cfun->decl)); 1811 delete_insn (note); 1812 1813 reorder_blocks (); 1814 } 1815 1816 static const char *some_local_dynamic_name; 1817 1818 /* Locate some local-dynamic symbol still in use by this function 1819 so that we can print its name in local-dynamic base patterns. 1820 Return null if there are no local-dynamic references. */ 1821 1822 const char * 1823 get_some_local_dynamic_name () 1824 { 1825 subrtx_iterator::array_type array; 1826 rtx_insn *insn; 1827 1828 if (some_local_dynamic_name) 1829 return some_local_dynamic_name; 1830 1831 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn)) 1832 if (NONDEBUG_INSN_P (insn)) 1833 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), ALL) 1834 { 1835 const_rtx x = *iter; 1836 if (GET_CODE (x) == SYMBOL_REF) 1837 { 1838 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC) 1839 return some_local_dynamic_name = XSTR (x, 0); 1840 if (CONSTANT_POOL_ADDRESS_P (x)) 1841 iter.substitute (get_pool_constant (x)); 1842 } 1843 } 1844 1845 return 0; 1846 } 1847 1848 /* Output assembler code for the start of a function, 1849 and initialize some of the variables in this file 1850 for the new function. The label for the function and associated 1851 assembler pseudo-ops have already been output in `assemble_start_function'. 1852 1853 FIRST is the first insn of the rtl for the function being compiled. 1854 FILE is the file to write assembler code to. 1855 OPTIMIZE_P is nonzero if we should eliminate redundant 1856 test and compare insns. */ 1857 1858 void 1859 final_start_function (rtx_insn *first, FILE *file, 1860 int optimize_p ATTRIBUTE_UNUSED) 1861 { 1862 block_depth = 0; 1863 1864 this_is_asm_operands = 0; 1865 1866 need_profile_function = false; 1867 1868 last_filename = LOCATION_FILE (prologue_location); 1869 last_linenum = LOCATION_LINE (prologue_location); 1870 last_discriminator = discriminator = 0; 1871 1872 high_block_linenum = high_function_linenum = last_linenum; 1873 1874 if (flag_sanitize & SANITIZE_ADDRESS) 1875 asan_function_start (); 1876 1877 if (!DECL_IGNORED_P (current_function_decl)) 1878 debug_hooks->begin_prologue (last_linenum, last_filename); 1879 1880 if (!dwarf2_debug_info_emitted_p (current_function_decl)) 1881 dwarf2out_begin_prologue (0, NULL); 1882 1883 #ifdef LEAF_REG_REMAP 1884 if (crtl->uses_only_leaf_regs) 1885 leaf_renumber_regs (first); 1886 #endif 1887 1888 /* The Sun386i and perhaps other machines don't work right 1889 if the profiling code comes after the prologue. */ 1890 if (targetm.profile_before_prologue () && crtl->profile) 1891 { 1892 if (targetm.asm_out.function_prologue == default_function_pro_epilogue 1893 && targetm.have_prologue ()) 1894 { 1895 rtx_insn *insn; 1896 for (insn = first; insn; insn = NEXT_INSN (insn)) 1897 if (!NOTE_P (insn)) 1898 { 1899 insn = NULL; 1900 break; 1901 } 1902 else if (NOTE_KIND (insn) == NOTE_INSN_BASIC_BLOCK 1903 || NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG) 1904 break; 1905 else if (NOTE_KIND (insn) == NOTE_INSN_DELETED 1906 || NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION) 1907 continue; 1908 else 1909 { 1910 insn = NULL; 1911 break; 1912 } 1913 1914 if (insn) 1915 need_profile_function = true; 1916 else 1917 profile_function (file); 1918 } 1919 else 1920 profile_function (file); 1921 } 1922 1923 /* If debugging, assign block numbers to all of the blocks in this 1924 function. */ 1925 if (write_symbols) 1926 { 1927 reemit_insn_block_notes (); 1928 number_blocks (current_function_decl); 1929 /* We never actually put out begin/end notes for the top-level 1930 block in the function. But, conceptually, that block is 1931 always needed. */ 1932 TREE_ASM_WRITTEN (DECL_INITIAL (current_function_decl)) = 1; 1933 } 1934 1935 if (warn_frame_larger_than 1936 && get_frame_size () > frame_larger_than_size) 1937 { 1938 /* Issue a warning */ 1939 warning (OPT_Wframe_larger_than_, 1940 "the frame size of %wd bytes is larger than %wd bytes", 1941 get_frame_size (), frame_larger_than_size); 1942 } 1943 1944 /* First output the function prologue: code to set up the stack frame. */ 1945 targetm.asm_out.function_prologue (file, get_frame_size ()); 1946 1947 /* If the machine represents the prologue as RTL, the profiling code must 1948 be emitted when NOTE_INSN_PROLOGUE_END is scanned. */ 1949 if (! targetm.have_prologue ()) 1950 profile_after_prologue (file); 1951 } 1952 1953 static void 1954 profile_after_prologue (FILE *file ATTRIBUTE_UNUSED) 1955 { 1956 if (!targetm.profile_before_prologue () && crtl->profile) 1957 profile_function (file); 1958 } 1959 1960 static void 1961 profile_function (FILE *file ATTRIBUTE_UNUSED) 1962 { 1963 #ifndef NO_PROFILE_COUNTERS 1964 # define NO_PROFILE_COUNTERS 0 1965 #endif 1966 #ifdef ASM_OUTPUT_REG_PUSH 1967 rtx sval = NULL, chain = NULL; 1968 1969 if (cfun->returns_struct) 1970 sval = targetm.calls.struct_value_rtx (TREE_TYPE (current_function_decl), 1971 true); 1972 if (cfun->static_chain_decl) 1973 chain = targetm.calls.static_chain (current_function_decl, true); 1974 #endif /* ASM_OUTPUT_REG_PUSH */ 1975 1976 if (! NO_PROFILE_COUNTERS) 1977 { 1978 int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE); 1979 switch_to_section (data_section); 1980 ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT)); 1981 targetm.asm_out.internal_label (file, "LP", current_function_funcdef_no); 1982 assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1); 1983 } 1984 1985 switch_to_section (current_function_section ()); 1986 1987 #ifdef ASM_OUTPUT_REG_PUSH 1988 if (sval && REG_P (sval)) 1989 ASM_OUTPUT_REG_PUSH (file, REGNO (sval)); 1990 if (chain && REG_P (chain)) 1991 ASM_OUTPUT_REG_PUSH (file, REGNO (chain)); 1992 #endif 1993 1994 FUNCTION_PROFILER (file, current_function_funcdef_no); 1995 1996 #ifdef ASM_OUTPUT_REG_PUSH 1997 if (chain && REG_P (chain)) 1998 ASM_OUTPUT_REG_POP (file, REGNO (chain)); 1999 if (sval && REG_P (sval)) 2000 ASM_OUTPUT_REG_POP (file, REGNO (sval)); 2001 #endif 2002 } 2003 2004 /* Output assembler code for the end of a function. 2005 For clarity, args are same as those of `final_start_function' 2006 even though not all of them are needed. */ 2007 2008 void 2009 final_end_function (void) 2010 { 2011 app_disable (); 2012 2013 if (!DECL_IGNORED_P (current_function_decl)) 2014 debug_hooks->end_function (high_function_linenum); 2015 2016 /* Finally, output the function epilogue: 2017 code to restore the stack frame and return to the caller. */ 2018 targetm.asm_out.function_epilogue (asm_out_file, get_frame_size ()); 2019 2020 /* And debug output. */ 2021 if (!DECL_IGNORED_P (current_function_decl)) 2022 debug_hooks->end_epilogue (last_linenum, last_filename); 2023 2024 if (!dwarf2_debug_info_emitted_p (current_function_decl) 2025 && dwarf2out_do_frame ()) 2026 dwarf2out_end_epilogue (last_linenum, last_filename); 2027 2028 some_local_dynamic_name = 0; 2029 } 2030 2031 2032 /* Dumper helper for basic block information. FILE is the assembly 2033 output file, and INSN is the instruction being emitted. */ 2034 2035 static void 2036 dump_basic_block_info (FILE *file, rtx_insn *insn, basic_block *start_to_bb, 2037 basic_block *end_to_bb, int bb_map_size, int *bb_seqn) 2038 { 2039 basic_block bb; 2040 2041 if (!flag_debug_asm) 2042 return; 2043 2044 if (INSN_UID (insn) < bb_map_size 2045 && (bb = start_to_bb[INSN_UID (insn)]) != NULL) 2046 { 2047 edge e; 2048 edge_iterator ei; 2049 2050 fprintf (file, "%s BLOCK %d", ASM_COMMENT_START, bb->index); 2051 if (bb->frequency) 2052 fprintf (file, " freq:%d", bb->frequency); 2053 if (bb->count) 2054 fprintf (file, " count:%" PRId64, 2055 bb->count); 2056 fprintf (file, " seq:%d", (*bb_seqn)++); 2057 fprintf (file, "\n%s PRED:", ASM_COMMENT_START); 2058 FOR_EACH_EDGE (e, ei, bb->preds) 2059 { 2060 dump_edge_info (file, e, TDF_DETAILS, 0); 2061 } 2062 fprintf (file, "\n"); 2063 } 2064 if (INSN_UID (insn) < bb_map_size 2065 && (bb = end_to_bb[INSN_UID (insn)]) != NULL) 2066 { 2067 edge e; 2068 edge_iterator ei; 2069 2070 fprintf (asm_out_file, "%s SUCC:", ASM_COMMENT_START); 2071 FOR_EACH_EDGE (e, ei, bb->succs) 2072 { 2073 dump_edge_info (asm_out_file, e, TDF_DETAILS, 1); 2074 } 2075 fprintf (file, "\n"); 2076 } 2077 } 2078 2079 /* Output assembler code for some insns: all or part of a function. 2080 For description of args, see `final_start_function', above. */ 2081 2082 void 2083 final (rtx_insn *first, FILE *file, int optimize_p) 2084 { 2085 rtx_insn *insn, *next; 2086 int seen = 0; 2087 2088 /* Used for -dA dump. */ 2089 basic_block *start_to_bb = NULL; 2090 basic_block *end_to_bb = NULL; 2091 int bb_map_size = 0; 2092 int bb_seqn = 0; 2093 2094 last_ignored_compare = 0; 2095 2096 if (HAVE_cc0) 2097 for (insn = first; insn; insn = NEXT_INSN (insn)) 2098 { 2099 /* If CC tracking across branches is enabled, record the insn which 2100 jumps to each branch only reached from one place. */ 2101 if (optimize_p && JUMP_P (insn)) 2102 { 2103 rtx lab = JUMP_LABEL (insn); 2104 if (lab && LABEL_P (lab) && LABEL_NUSES (lab) == 1) 2105 { 2106 LABEL_REFS (lab) = insn; 2107 } 2108 } 2109 } 2110 2111 init_recog (); 2112 2113 CC_STATUS_INIT; 2114 2115 if (flag_debug_asm) 2116 { 2117 basic_block bb; 2118 2119 bb_map_size = get_max_uid () + 1; 2120 start_to_bb = XCNEWVEC (basic_block, bb_map_size); 2121 end_to_bb = XCNEWVEC (basic_block, bb_map_size); 2122 2123 /* There is no cfg for a thunk. */ 2124 if (!cfun->is_thunk) 2125 FOR_EACH_BB_REVERSE_FN (bb, cfun) 2126 { 2127 start_to_bb[INSN_UID (BB_HEAD (bb))] = bb; 2128 end_to_bb[INSN_UID (BB_END (bb))] = bb; 2129 } 2130 } 2131 2132 /* Output the insns. */ 2133 for (insn = first; insn;) 2134 { 2135 if (HAVE_ATTR_length) 2136 { 2137 if ((unsigned) INSN_UID (insn) >= INSN_ADDRESSES_SIZE ()) 2138 { 2139 /* This can be triggered by bugs elsewhere in the compiler if 2140 new insns are created after init_insn_lengths is called. */ 2141 gcc_assert (NOTE_P (insn)); 2142 insn_current_address = -1; 2143 } 2144 else 2145 insn_current_address = INSN_ADDRESSES (INSN_UID (insn)); 2146 } 2147 2148 dump_basic_block_info (file, insn, start_to_bb, end_to_bb, 2149 bb_map_size, &bb_seqn); 2150 insn = final_scan_insn (insn, file, optimize_p, 0, &seen); 2151 } 2152 2153 if (flag_debug_asm) 2154 { 2155 free (start_to_bb); 2156 free (end_to_bb); 2157 } 2158 2159 /* Remove CFI notes, to avoid compare-debug failures. */ 2160 for (insn = first; insn; insn = next) 2161 { 2162 next = NEXT_INSN (insn); 2163 if (NOTE_P (insn) 2164 && (NOTE_KIND (insn) == NOTE_INSN_CFI 2165 || NOTE_KIND (insn) == NOTE_INSN_CFI_LABEL)) 2166 delete_insn (insn); 2167 } 2168 } 2169 2170 const char * 2171 get_insn_template (int code, rtx insn) 2172 { 2173 switch (insn_data[code].output_format) 2174 { 2175 case INSN_OUTPUT_FORMAT_SINGLE: 2176 return insn_data[code].output.single; 2177 case INSN_OUTPUT_FORMAT_MULTI: 2178 return insn_data[code].output.multi[which_alternative]; 2179 case INSN_OUTPUT_FORMAT_FUNCTION: 2180 gcc_assert (insn); 2181 return (*insn_data[code].output.function) (recog_data.operand, 2182 as_a <rtx_insn *> (insn)); 2183 2184 default: 2185 gcc_unreachable (); 2186 } 2187 } 2188 2189 /* Emit the appropriate declaration for an alternate-entry-point 2190 symbol represented by INSN, to FILE. INSN is a CODE_LABEL with 2191 LABEL_KIND != LABEL_NORMAL. 2192 2193 The case fall-through in this function is intentional. */ 2194 static void 2195 output_alternate_entry_point (FILE *file, rtx_insn *insn) 2196 { 2197 const char *name = LABEL_NAME (insn); 2198 2199 switch (LABEL_KIND (insn)) 2200 { 2201 case LABEL_WEAK_ENTRY: 2202 #ifdef ASM_WEAKEN_LABEL 2203 ASM_WEAKEN_LABEL (file, name); 2204 #endif 2205 case LABEL_GLOBAL_ENTRY: 2206 targetm.asm_out.globalize_label (file, name); 2207 case LABEL_STATIC_ENTRY: 2208 #ifdef ASM_OUTPUT_TYPE_DIRECTIVE 2209 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function"); 2210 #endif 2211 ASM_OUTPUT_LABEL (file, name); 2212 break; 2213 2214 case LABEL_NORMAL: 2215 default: 2216 gcc_unreachable (); 2217 } 2218 } 2219 2220 /* Given a CALL_INSN, find and return the nested CALL. */ 2221 static rtx 2222 call_from_call_insn (rtx_call_insn *insn) 2223 { 2224 rtx x; 2225 gcc_assert (CALL_P (insn)); 2226 x = PATTERN (insn); 2227 2228 while (GET_CODE (x) != CALL) 2229 { 2230 switch (GET_CODE (x)) 2231 { 2232 default: 2233 gcc_unreachable (); 2234 case COND_EXEC: 2235 x = COND_EXEC_CODE (x); 2236 break; 2237 case PARALLEL: 2238 x = XVECEXP (x, 0, 0); 2239 break; 2240 case SET: 2241 x = XEXP (x, 1); 2242 break; 2243 } 2244 } 2245 return x; 2246 } 2247 2248 /* The final scan for one insn, INSN. 2249 Args are same as in `final', except that INSN 2250 is the insn being scanned. 2251 Value returned is the next insn to be scanned. 2252 2253 NOPEEPHOLES is the flag to disallow peephole processing (currently 2254 used for within delayed branch sequence output). 2255 2256 SEEN is used to track the end of the prologue, for emitting 2257 debug information. We force the emission of a line note after 2258 both NOTE_INSN_PROLOGUE_END and NOTE_INSN_FUNCTION_BEG. */ 2259 2260 rtx_insn * 2261 final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, 2262 int nopeepholes ATTRIBUTE_UNUSED, int *seen) 2263 { 2264 #if HAVE_cc0 2265 rtx set; 2266 #endif 2267 rtx_insn *next; 2268 2269 insn_counter++; 2270 2271 /* Ignore deleted insns. These can occur when we split insns (due to a 2272 template of "#") while not optimizing. */ 2273 if (insn->deleted ()) 2274 return NEXT_INSN (insn); 2275 2276 switch (GET_CODE (insn)) 2277 { 2278 case NOTE: 2279 switch (NOTE_KIND (insn)) 2280 { 2281 case NOTE_INSN_DELETED: 2282 case NOTE_INSN_UPDATE_SJLJ_CONTEXT: 2283 break; 2284 2285 case NOTE_INSN_SWITCH_TEXT_SECTIONS: 2286 in_cold_section_p = !in_cold_section_p; 2287 2288 if (dwarf2out_do_frame ()) 2289 dwarf2out_switch_text_section (); 2290 else if (!DECL_IGNORED_P (current_function_decl)) 2291 debug_hooks->switch_text_section (); 2292 2293 switch_to_section (current_function_section ()); 2294 targetm.asm_out.function_switched_text_sections (asm_out_file, 2295 current_function_decl, 2296 in_cold_section_p); 2297 /* Emit a label for the split cold section. Form label name by 2298 suffixing "cold" to the original function's name. */ 2299 if (in_cold_section_p) 2300 { 2301 cold_function_name 2302 = clone_function_name (current_function_decl, "cold"); 2303 #ifdef ASM_DECLARE_COLD_FUNCTION_NAME 2304 ASM_DECLARE_COLD_FUNCTION_NAME (asm_out_file, 2305 IDENTIFIER_POINTER 2306 (cold_function_name), 2307 current_function_decl); 2308 #else 2309 ASM_OUTPUT_LABEL (asm_out_file, 2310 IDENTIFIER_POINTER (cold_function_name)); 2311 #endif 2312 } 2313 break; 2314 2315 case NOTE_INSN_BASIC_BLOCK: 2316 if (need_profile_function) 2317 { 2318 profile_function (asm_out_file); 2319 need_profile_function = false; 2320 } 2321 2322 if (targetm.asm_out.unwind_emit) 2323 targetm.asm_out.unwind_emit (asm_out_file, insn); 2324 2325 discriminator = NOTE_BASIC_BLOCK (insn)->discriminator; 2326 2327 break; 2328 2329 case NOTE_INSN_EH_REGION_BEG: 2330 ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LEHB", 2331 NOTE_EH_HANDLER (insn)); 2332 break; 2333 2334 case NOTE_INSN_EH_REGION_END: 2335 ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LEHE", 2336 NOTE_EH_HANDLER (insn)); 2337 break; 2338 2339 case NOTE_INSN_PROLOGUE_END: 2340 targetm.asm_out.function_end_prologue (file); 2341 profile_after_prologue (file); 2342 2343 if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE) 2344 { 2345 *seen |= SEEN_EMITTED; 2346 force_source_line = true; 2347 } 2348 else 2349 *seen |= SEEN_NOTE; 2350 2351 break; 2352 2353 case NOTE_INSN_EPILOGUE_BEG: 2354 if (!DECL_IGNORED_P (current_function_decl)) 2355 (*debug_hooks->begin_epilogue) (last_linenum, last_filename); 2356 targetm.asm_out.function_begin_epilogue (file); 2357 break; 2358 2359 case NOTE_INSN_CFI: 2360 dwarf2out_emit_cfi (NOTE_CFI (insn)); 2361 break; 2362 2363 case NOTE_INSN_CFI_LABEL: 2364 ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LCFI", 2365 NOTE_LABEL_NUMBER (insn)); 2366 break; 2367 2368 case NOTE_INSN_FUNCTION_BEG: 2369 if (need_profile_function) 2370 { 2371 profile_function (asm_out_file); 2372 need_profile_function = false; 2373 } 2374 2375 app_disable (); 2376 if (!DECL_IGNORED_P (current_function_decl)) 2377 debug_hooks->end_prologue (last_linenum, last_filename); 2378 2379 if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE) 2380 { 2381 *seen |= SEEN_EMITTED; 2382 force_source_line = true; 2383 } 2384 else 2385 *seen |= SEEN_NOTE; 2386 2387 break; 2388 2389 case NOTE_INSN_BLOCK_BEG: 2390 if (debug_info_level == DINFO_LEVEL_NORMAL 2391 || debug_info_level == DINFO_LEVEL_VERBOSE 2392 || write_symbols == DWARF2_DEBUG 2393 || write_symbols == VMS_AND_DWARF2_DEBUG 2394 || write_symbols == VMS_DEBUG) 2395 { 2396 int n = BLOCK_NUMBER (NOTE_BLOCK (insn)); 2397 2398 app_disable (); 2399 ++block_depth; 2400 high_block_linenum = last_linenum; 2401 2402 /* Output debugging info about the symbol-block beginning. */ 2403 if (!DECL_IGNORED_P (current_function_decl)) 2404 debug_hooks->begin_block (last_linenum, n); 2405 2406 /* Mark this block as output. */ 2407 TREE_ASM_WRITTEN (NOTE_BLOCK (insn)) = 1; 2408 } 2409 if (write_symbols == DBX_DEBUG 2410 || write_symbols == SDB_DEBUG) 2411 { 2412 location_t *locus_ptr 2413 = block_nonartificial_location (NOTE_BLOCK (insn)); 2414 2415 if (locus_ptr != NULL) 2416 { 2417 override_filename = LOCATION_FILE (*locus_ptr); 2418 override_linenum = LOCATION_LINE (*locus_ptr); 2419 } 2420 } 2421 break; 2422 2423 case NOTE_INSN_BLOCK_END: 2424 if (debug_info_level == DINFO_LEVEL_NORMAL 2425 || debug_info_level == DINFO_LEVEL_VERBOSE 2426 || write_symbols == DWARF2_DEBUG 2427 || write_symbols == VMS_AND_DWARF2_DEBUG 2428 || write_symbols == VMS_DEBUG) 2429 { 2430 int n = BLOCK_NUMBER (NOTE_BLOCK (insn)); 2431 2432 app_disable (); 2433 2434 /* End of a symbol-block. */ 2435 --block_depth; 2436 gcc_assert (block_depth >= 0); 2437 2438 if (!DECL_IGNORED_P (current_function_decl)) 2439 debug_hooks->end_block (high_block_linenum, n); 2440 } 2441 if (write_symbols == DBX_DEBUG 2442 || write_symbols == SDB_DEBUG) 2443 { 2444 tree outer_block = BLOCK_SUPERCONTEXT (NOTE_BLOCK (insn)); 2445 location_t *locus_ptr 2446 = block_nonartificial_location (outer_block); 2447 2448 if (locus_ptr != NULL) 2449 { 2450 override_filename = LOCATION_FILE (*locus_ptr); 2451 override_linenum = LOCATION_LINE (*locus_ptr); 2452 } 2453 else 2454 { 2455 override_filename = NULL; 2456 override_linenum = 0; 2457 } 2458 } 2459 break; 2460 2461 case NOTE_INSN_DELETED_LABEL: 2462 /* Emit the label. We may have deleted the CODE_LABEL because 2463 the label could be proved to be unreachable, though still 2464 referenced (in the form of having its address taken. */ 2465 ASM_OUTPUT_DEBUG_LABEL (file, "L", CODE_LABEL_NUMBER (insn)); 2466 break; 2467 2468 case NOTE_INSN_DELETED_DEBUG_LABEL: 2469 /* Similarly, but need to use different namespace for it. */ 2470 if (CODE_LABEL_NUMBER (insn) != -1) 2471 ASM_OUTPUT_DEBUG_LABEL (file, "LDL", CODE_LABEL_NUMBER (insn)); 2472 break; 2473 2474 case NOTE_INSN_VAR_LOCATION: 2475 case NOTE_INSN_CALL_ARG_LOCATION: 2476 if (!DECL_IGNORED_P (current_function_decl)) 2477 debug_hooks->var_location (insn); 2478 break; 2479 2480 default: 2481 gcc_unreachable (); 2482 break; 2483 } 2484 break; 2485 2486 case BARRIER: 2487 break; 2488 2489 case CODE_LABEL: 2490 /* The target port might emit labels in the output function for 2491 some insn, e.g. sh.c output_branchy_insn. */ 2492 if (CODE_LABEL_NUMBER (insn) <= max_labelno) 2493 { 2494 int align = LABEL_TO_ALIGNMENT (insn); 2495 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN 2496 int max_skip = LABEL_TO_MAX_SKIP (insn); 2497 #endif 2498 2499 if (align && NEXT_INSN (insn)) 2500 { 2501 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN 2502 ASM_OUTPUT_MAX_SKIP_ALIGN (file, align, max_skip); 2503 #else 2504 #ifdef ASM_OUTPUT_ALIGN_WITH_NOP 2505 ASM_OUTPUT_ALIGN_WITH_NOP (file, align); 2506 #else 2507 ASM_OUTPUT_ALIGN (file, align); 2508 #endif 2509 #endif 2510 } 2511 } 2512 CC_STATUS_INIT; 2513 2514 if (!DECL_IGNORED_P (current_function_decl) && LABEL_NAME (insn)) 2515 debug_hooks->label (as_a <rtx_code_label *> (insn)); 2516 2517 app_disable (); 2518 2519 next = next_nonnote_insn (insn); 2520 /* If this label is followed by a jump-table, make sure we put 2521 the label in the read-only section. Also possibly write the 2522 label and jump table together. */ 2523 if (next != 0 && JUMP_TABLE_DATA_P (next)) 2524 { 2525 #if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC) 2526 /* In this case, the case vector is being moved by the 2527 target, so don't output the label at all. Leave that 2528 to the back end macros. */ 2529 #else 2530 if (! JUMP_TABLES_IN_TEXT_SECTION) 2531 { 2532 int log_align; 2533 2534 switch_to_section (targetm.asm_out.function_rodata_section 2535 (current_function_decl)); 2536 2537 #ifdef ADDR_VEC_ALIGN 2538 log_align = ADDR_VEC_ALIGN (next); 2539 #else 2540 log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT); 2541 #endif 2542 ASM_OUTPUT_ALIGN (file, log_align); 2543 } 2544 else 2545 switch_to_section (current_function_section ()); 2546 2547 #ifdef ASM_OUTPUT_CASE_LABEL 2548 ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn), 2549 next); 2550 #else 2551 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn)); 2552 #endif 2553 #endif 2554 break; 2555 } 2556 if (LABEL_ALT_ENTRY_P (insn)) 2557 output_alternate_entry_point (file, insn); 2558 else 2559 targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn)); 2560 break; 2561 2562 default: 2563 { 2564 rtx body = PATTERN (insn); 2565 int insn_code_number; 2566 const char *templ; 2567 bool is_stmt; 2568 2569 /* Reset this early so it is correct for ASM statements. */ 2570 current_insn_predicate = NULL_RTX; 2571 2572 /* An INSN, JUMP_INSN or CALL_INSN. 2573 First check for special kinds that recog doesn't recognize. */ 2574 2575 if (GET_CODE (body) == USE /* These are just declarations. */ 2576 || GET_CODE (body) == CLOBBER) 2577 break; 2578 2579 #if HAVE_cc0 2580 { 2581 /* If there is a REG_CC_SETTER note on this insn, it means that 2582 the setting of the condition code was done in the delay slot 2583 of the insn that branched here. So recover the cc status 2584 from the insn that set it. */ 2585 2586 rtx note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX); 2587 if (note) 2588 { 2589 rtx_insn *other = as_a <rtx_insn *> (XEXP (note, 0)); 2590 NOTICE_UPDATE_CC (PATTERN (other), other); 2591 cc_prev_status = cc_status; 2592 } 2593 } 2594 #endif 2595 2596 /* Detect insns that are really jump-tables 2597 and output them as such. */ 2598 2599 if (JUMP_TABLE_DATA_P (insn)) 2600 { 2601 #if !(defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC)) 2602 int vlen, idx; 2603 #endif 2604 2605 if (! JUMP_TABLES_IN_TEXT_SECTION) 2606 switch_to_section (targetm.asm_out.function_rodata_section 2607 (current_function_decl)); 2608 else 2609 switch_to_section (current_function_section ()); 2610 2611 app_disable (); 2612 2613 #if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC) 2614 if (GET_CODE (body) == ADDR_VEC) 2615 { 2616 #ifdef ASM_OUTPUT_ADDR_VEC 2617 ASM_OUTPUT_ADDR_VEC (PREV_INSN (insn), body); 2618 #else 2619 gcc_unreachable (); 2620 #endif 2621 } 2622 else 2623 { 2624 #ifdef ASM_OUTPUT_ADDR_DIFF_VEC 2625 ASM_OUTPUT_ADDR_DIFF_VEC (PREV_INSN (insn), body); 2626 #else 2627 gcc_unreachable (); 2628 #endif 2629 } 2630 #else 2631 vlen = XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC); 2632 for (idx = 0; idx < vlen; idx++) 2633 { 2634 if (GET_CODE (body) == ADDR_VEC) 2635 { 2636 #ifdef ASM_OUTPUT_ADDR_VEC_ELT 2637 ASM_OUTPUT_ADDR_VEC_ELT 2638 (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0))); 2639 #else 2640 gcc_unreachable (); 2641 #endif 2642 } 2643 else 2644 { 2645 #ifdef ASM_OUTPUT_ADDR_DIFF_ELT 2646 ASM_OUTPUT_ADDR_DIFF_ELT 2647 (file, 2648 body, 2649 CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)), 2650 CODE_LABEL_NUMBER (XEXP (XEXP (body, 0), 0))); 2651 #else 2652 gcc_unreachable (); 2653 #endif 2654 } 2655 } 2656 #ifdef ASM_OUTPUT_CASE_END 2657 ASM_OUTPUT_CASE_END (file, 2658 CODE_LABEL_NUMBER (PREV_INSN (insn)), 2659 insn); 2660 #endif 2661 #endif 2662 2663 switch_to_section (current_function_section ()); 2664 2665 break; 2666 } 2667 /* Output this line note if it is the first or the last line 2668 note in a row. */ 2669 if (!DECL_IGNORED_P (current_function_decl) 2670 && notice_source_line (insn, &is_stmt)) 2671 (*debug_hooks->source_line) (last_linenum, last_filename, 2672 last_discriminator, is_stmt); 2673 2674 if (GET_CODE (body) == ASM_INPUT) 2675 { 2676 const char *string = XSTR (body, 0); 2677 2678 /* There's no telling what that did to the condition codes. */ 2679 CC_STATUS_INIT; 2680 2681 if (string[0]) 2682 { 2683 expanded_location loc; 2684 2685 app_enable (); 2686 loc = expand_location (ASM_INPUT_SOURCE_LOCATION (body)); 2687 if (*loc.file && loc.line) 2688 fprintf (asm_out_file, "%s %i \"%s\" 1\n", 2689 ASM_COMMENT_START, loc.line, loc.file); 2690 fprintf (asm_out_file, "\t%s\n", string); 2691 #if HAVE_AS_LINE_ZERO 2692 if (*loc.file && loc.line) 2693 fprintf (asm_out_file, "%s 0 \"\" 2\n", ASM_COMMENT_START); 2694 #endif 2695 } 2696 break; 2697 } 2698 2699 /* Detect `asm' construct with operands. */ 2700 if (asm_noperands (body) >= 0) 2701 { 2702 unsigned int noperands = asm_noperands (body); 2703 rtx *ops = XALLOCAVEC (rtx, noperands); 2704 const char *string; 2705 location_t loc; 2706 expanded_location expanded; 2707 2708 /* There's no telling what that did to the condition codes. */ 2709 CC_STATUS_INIT; 2710 2711 /* Get out the operand values. */ 2712 string = decode_asm_operands (body, ops, NULL, NULL, NULL, &loc); 2713 /* Inhibit dying on what would otherwise be compiler bugs. */ 2714 insn_noperands = noperands; 2715 this_is_asm_operands = insn; 2716 expanded = expand_location (loc); 2717 2718 #ifdef FINAL_PRESCAN_INSN 2719 FINAL_PRESCAN_INSN (insn, ops, insn_noperands); 2720 #endif 2721 2722 /* Output the insn using them. */ 2723 if (string[0]) 2724 { 2725 app_enable (); 2726 if (expanded.file && expanded.line) 2727 fprintf (asm_out_file, "%s %i \"%s\" 1\n", 2728 ASM_COMMENT_START, expanded.line, expanded.file); 2729 output_asm_insn (string, ops); 2730 #if HAVE_AS_LINE_ZERO 2731 if (expanded.file && expanded.line) 2732 fprintf (asm_out_file, "%s 0 \"\" 2\n", ASM_COMMENT_START); 2733 #endif 2734 } 2735 2736 if (targetm.asm_out.final_postscan_insn) 2737 targetm.asm_out.final_postscan_insn (file, insn, ops, 2738 insn_noperands); 2739 2740 this_is_asm_operands = 0; 2741 break; 2742 } 2743 2744 app_disable (); 2745 2746 if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (body)) 2747 { 2748 /* A delayed-branch sequence */ 2749 int i; 2750 2751 final_sequence = seq; 2752 2753 /* The first insn in this SEQUENCE might be a JUMP_INSN that will 2754 force the restoration of a comparison that was previously 2755 thought unnecessary. If that happens, cancel this sequence 2756 and cause that insn to be restored. */ 2757 2758 next = final_scan_insn (seq->insn (0), file, 0, 1, seen); 2759 if (next != seq->insn (1)) 2760 { 2761 final_sequence = 0; 2762 return next; 2763 } 2764 2765 for (i = 1; i < seq->len (); i++) 2766 { 2767 rtx_insn *insn = seq->insn (i); 2768 rtx_insn *next = NEXT_INSN (insn); 2769 /* We loop in case any instruction in a delay slot gets 2770 split. */ 2771 do 2772 insn = final_scan_insn (insn, file, 0, 1, seen); 2773 while (insn != next); 2774 } 2775 #ifdef DBR_OUTPUT_SEQEND 2776 DBR_OUTPUT_SEQEND (file); 2777 #endif 2778 final_sequence = 0; 2779 2780 /* If the insn requiring the delay slot was a CALL_INSN, the 2781 insns in the delay slot are actually executed before the 2782 called function. Hence we don't preserve any CC-setting 2783 actions in these insns and the CC must be marked as being 2784 clobbered by the function. */ 2785 if (CALL_P (seq->insn (0))) 2786 { 2787 CC_STATUS_INIT; 2788 } 2789 break; 2790 } 2791 2792 /* We have a real machine instruction as rtl. */ 2793 2794 body = PATTERN (insn); 2795 2796 #if HAVE_cc0 2797 set = single_set (insn); 2798 2799 /* Check for redundant test and compare instructions 2800 (when the condition codes are already set up as desired). 2801 This is done only when optimizing; if not optimizing, 2802 it should be possible for the user to alter a variable 2803 with the debugger in between statements 2804 and the next statement should reexamine the variable 2805 to compute the condition codes. */ 2806 2807 if (optimize_p) 2808 { 2809 if (set 2810 && GET_CODE (SET_DEST (set)) == CC0 2811 && insn != last_ignored_compare) 2812 { 2813 rtx src1, src2; 2814 if (GET_CODE (SET_SRC (set)) == SUBREG) 2815 SET_SRC (set) = alter_subreg (&SET_SRC (set), true); 2816 2817 src1 = SET_SRC (set); 2818 src2 = NULL_RTX; 2819 if (GET_CODE (SET_SRC (set)) == COMPARE) 2820 { 2821 if (GET_CODE (XEXP (SET_SRC (set), 0)) == SUBREG) 2822 XEXP (SET_SRC (set), 0) 2823 = alter_subreg (&XEXP (SET_SRC (set), 0), true); 2824 if (GET_CODE (XEXP (SET_SRC (set), 1)) == SUBREG) 2825 XEXP (SET_SRC (set), 1) 2826 = alter_subreg (&XEXP (SET_SRC (set), 1), true); 2827 if (XEXP (SET_SRC (set), 1) 2828 == CONST0_RTX (GET_MODE (XEXP (SET_SRC (set), 0)))) 2829 src2 = XEXP (SET_SRC (set), 0); 2830 } 2831 if ((cc_status.value1 != 0 2832 && rtx_equal_p (src1, cc_status.value1)) 2833 || (cc_status.value2 != 0 2834 && rtx_equal_p (src1, cc_status.value2)) 2835 || (src2 != 0 && cc_status.value1 != 0 2836 && rtx_equal_p (src2, cc_status.value1)) 2837 || (src2 != 0 && cc_status.value2 != 0 2838 && rtx_equal_p (src2, cc_status.value2))) 2839 { 2840 /* Don't delete insn if it has an addressing side-effect. */ 2841 if (! FIND_REG_INC_NOTE (insn, NULL_RTX) 2842 /* or if anything in it is volatile. */ 2843 && ! volatile_refs_p (PATTERN (insn))) 2844 { 2845 /* We don't really delete the insn; just ignore it. */ 2846 last_ignored_compare = insn; 2847 break; 2848 } 2849 } 2850 } 2851 } 2852 2853 /* If this is a conditional branch, maybe modify it 2854 if the cc's are in a nonstandard state 2855 so that it accomplishes the same thing that it would 2856 do straightforwardly if the cc's were set up normally. */ 2857 2858 if (cc_status.flags != 0 2859 && JUMP_P (insn) 2860 && GET_CODE (body) == SET 2861 && SET_DEST (body) == pc_rtx 2862 && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE 2863 && COMPARISON_P (XEXP (SET_SRC (body), 0)) 2864 && XEXP (XEXP (SET_SRC (body), 0), 0) == cc0_rtx) 2865 { 2866 /* This function may alter the contents of its argument 2867 and clear some of the cc_status.flags bits. 2868 It may also return 1 meaning condition now always true 2869 or -1 meaning condition now always false 2870 or 2 meaning condition nontrivial but altered. */ 2871 int result = alter_cond (XEXP (SET_SRC (body), 0)); 2872 /* If condition now has fixed value, replace the IF_THEN_ELSE 2873 with its then-operand or its else-operand. */ 2874 if (result == 1) 2875 SET_SRC (body) = XEXP (SET_SRC (body), 1); 2876 if (result == -1) 2877 SET_SRC (body) = XEXP (SET_SRC (body), 2); 2878 2879 /* The jump is now either unconditional or a no-op. 2880 If it has become a no-op, don't try to output it. 2881 (It would not be recognized.) */ 2882 if (SET_SRC (body) == pc_rtx) 2883 { 2884 delete_insn (insn); 2885 break; 2886 } 2887 else if (ANY_RETURN_P (SET_SRC (body))) 2888 /* Replace (set (pc) (return)) with (return). */ 2889 PATTERN (insn) = body = SET_SRC (body); 2890 2891 /* Rerecognize the instruction if it has changed. */ 2892 if (result != 0) 2893 INSN_CODE (insn) = -1; 2894 } 2895 2896 /* If this is a conditional trap, maybe modify it if the cc's 2897 are in a nonstandard state so that it accomplishes the same 2898 thing that it would do straightforwardly if the cc's were 2899 set up normally. */ 2900 if (cc_status.flags != 0 2901 && NONJUMP_INSN_P (insn) 2902 && GET_CODE (body) == TRAP_IF 2903 && COMPARISON_P (TRAP_CONDITION (body)) 2904 && XEXP (TRAP_CONDITION (body), 0) == cc0_rtx) 2905 { 2906 /* This function may alter the contents of its argument 2907 and clear some of the cc_status.flags bits. 2908 It may also return 1 meaning condition now always true 2909 or -1 meaning condition now always false 2910 or 2 meaning condition nontrivial but altered. */ 2911 int result = alter_cond (TRAP_CONDITION (body)); 2912 2913 /* If TRAP_CONDITION has become always false, delete the 2914 instruction. */ 2915 if (result == -1) 2916 { 2917 delete_insn (insn); 2918 break; 2919 } 2920 2921 /* If TRAP_CONDITION has become always true, replace 2922 TRAP_CONDITION with const_true_rtx. */ 2923 if (result == 1) 2924 TRAP_CONDITION (body) = const_true_rtx; 2925 2926 /* Rerecognize the instruction if it has changed. */ 2927 if (result != 0) 2928 INSN_CODE (insn) = -1; 2929 } 2930 2931 /* Make same adjustments to instructions that examine the 2932 condition codes without jumping and instructions that 2933 handle conditional moves (if this machine has either one). */ 2934 2935 if (cc_status.flags != 0 2936 && set != 0) 2937 { 2938 rtx cond_rtx, then_rtx, else_rtx; 2939 2940 if (!JUMP_P (insn) 2941 && GET_CODE (SET_SRC (set)) == IF_THEN_ELSE) 2942 { 2943 cond_rtx = XEXP (SET_SRC (set), 0); 2944 then_rtx = XEXP (SET_SRC (set), 1); 2945 else_rtx = XEXP (SET_SRC (set), 2); 2946 } 2947 else 2948 { 2949 cond_rtx = SET_SRC (set); 2950 then_rtx = const_true_rtx; 2951 else_rtx = const0_rtx; 2952 } 2953 2954 if (COMPARISON_P (cond_rtx) 2955 && XEXP (cond_rtx, 0) == cc0_rtx) 2956 { 2957 int result; 2958 result = alter_cond (cond_rtx); 2959 if (result == 1) 2960 validate_change (insn, &SET_SRC (set), then_rtx, 0); 2961 else if (result == -1) 2962 validate_change (insn, &SET_SRC (set), else_rtx, 0); 2963 else if (result == 2) 2964 INSN_CODE (insn) = -1; 2965 if (SET_DEST (set) == SET_SRC (set)) 2966 delete_insn (insn); 2967 } 2968 } 2969 2970 #endif 2971 2972 /* Do machine-specific peephole optimizations if desired. */ 2973 2974 if (HAVE_peephole && optimize_p && !flag_no_peephole && !nopeepholes) 2975 { 2976 rtx_insn *next = peephole (insn); 2977 /* When peepholing, if there were notes within the peephole, 2978 emit them before the peephole. */ 2979 if (next != 0 && next != NEXT_INSN (insn)) 2980 { 2981 rtx_insn *note, *prev = PREV_INSN (insn); 2982 2983 for (note = NEXT_INSN (insn); note != next; 2984 note = NEXT_INSN (note)) 2985 final_scan_insn (note, file, optimize_p, nopeepholes, seen); 2986 2987 /* Put the notes in the proper position for a later 2988 rescan. For example, the SH target can do this 2989 when generating a far jump in a delayed branch 2990 sequence. */ 2991 note = NEXT_INSN (insn); 2992 SET_PREV_INSN (note) = prev; 2993 SET_NEXT_INSN (prev) = note; 2994 SET_NEXT_INSN (PREV_INSN (next)) = insn; 2995 SET_PREV_INSN (insn) = PREV_INSN (next); 2996 SET_NEXT_INSN (insn) = next; 2997 SET_PREV_INSN (next) = insn; 2998 } 2999 3000 /* PEEPHOLE might have changed this. */ 3001 body = PATTERN (insn); 3002 } 3003 3004 /* Try to recognize the instruction. 3005 If successful, verify that the operands satisfy the 3006 constraints for the instruction. Crash if they don't, 3007 since `reload' should have changed them so that they do. */ 3008 3009 insn_code_number = recog_memoized (insn); 3010 cleanup_subreg_operands (insn); 3011 3012 /* Dump the insn in the assembly for debugging (-dAP). 3013 If the final dump is requested as slim RTL, dump slim 3014 RTL to the assembly file also. */ 3015 if (flag_dump_rtl_in_asm) 3016 { 3017 print_rtx_head = ASM_COMMENT_START; 3018 if (! (dump_flags & TDF_SLIM)) 3019 print_rtl_single (asm_out_file, insn); 3020 else 3021 dump_insn_slim (asm_out_file, insn); 3022 print_rtx_head = ""; 3023 } 3024 3025 if (! constrain_operands_cached (insn, 1)) 3026 fatal_insn_not_found (insn); 3027 3028 /* Some target machines need to prescan each insn before 3029 it is output. */ 3030 3031 #ifdef FINAL_PRESCAN_INSN 3032 FINAL_PRESCAN_INSN (insn, recog_data.operand, recog_data.n_operands); 3033 #endif 3034 3035 if (targetm.have_conditional_execution () 3036 && GET_CODE (PATTERN (insn)) == COND_EXEC) 3037 current_insn_predicate = COND_EXEC_TEST (PATTERN (insn)); 3038 3039 #if HAVE_cc0 3040 cc_prev_status = cc_status; 3041 3042 /* Update `cc_status' for this instruction. 3043 The instruction's output routine may change it further. 3044 If the output routine for a jump insn needs to depend 3045 on the cc status, it should look at cc_prev_status. */ 3046 3047 NOTICE_UPDATE_CC (body, insn); 3048 #endif 3049 3050 current_output_insn = debug_insn = insn; 3051 3052 /* Find the proper template for this insn. */ 3053 templ = get_insn_template (insn_code_number, insn); 3054 3055 /* If the C code returns 0, it means that it is a jump insn 3056 which follows a deleted test insn, and that test insn 3057 needs to be reinserted. */ 3058 if (templ == 0) 3059 { 3060 rtx_insn *prev; 3061 3062 gcc_assert (prev_nonnote_insn (insn) == last_ignored_compare); 3063 3064 /* We have already processed the notes between the setter and 3065 the user. Make sure we don't process them again, this is 3066 particularly important if one of the notes is a block 3067 scope note or an EH note. */ 3068 for (prev = insn; 3069 prev != last_ignored_compare; 3070 prev = PREV_INSN (prev)) 3071 { 3072 if (NOTE_P (prev)) 3073 delete_insn (prev); /* Use delete_note. */ 3074 } 3075 3076 return prev; 3077 } 3078 3079 /* If the template is the string "#", it means that this insn must 3080 be split. */ 3081 if (templ[0] == '#' && templ[1] == '\0') 3082 { 3083 rtx_insn *new_rtx = try_split (body, insn, 0); 3084 3085 /* If we didn't split the insn, go away. */ 3086 if (new_rtx == insn && PATTERN (new_rtx) == body) 3087 fatal_insn ("could not split insn", insn); 3088 3089 /* If we have a length attribute, this instruction should have 3090 been split in shorten_branches, to ensure that we would have 3091 valid length info for the splitees. */ 3092 gcc_assert (!HAVE_ATTR_length); 3093 3094 return new_rtx; 3095 } 3096 3097 /* ??? This will put the directives in the wrong place if 3098 get_insn_template outputs assembly directly. However calling it 3099 before get_insn_template breaks if the insns is split. */ 3100 if (targetm.asm_out.unwind_emit_before_insn 3101 && targetm.asm_out.unwind_emit) 3102 targetm.asm_out.unwind_emit (asm_out_file, insn); 3103 3104 rtx_call_insn *call_insn = dyn_cast <rtx_call_insn *> (insn); 3105 if (call_insn != NULL) 3106 { 3107 rtx x = call_from_call_insn (call_insn); 3108 x = XEXP (x, 0); 3109 if (x && MEM_P (x) && GET_CODE (XEXP (x, 0)) == SYMBOL_REF) 3110 { 3111 tree t; 3112 x = XEXP (x, 0); 3113 t = SYMBOL_REF_DECL (x); 3114 if (t) 3115 assemble_external (t); 3116 } 3117 } 3118 3119 /* Output assembler code from the template. */ 3120 output_asm_insn (templ, recog_data.operand); 3121 3122 /* Some target machines need to postscan each insn after 3123 it is output. */ 3124 if (targetm.asm_out.final_postscan_insn) 3125 targetm.asm_out.final_postscan_insn (file, insn, recog_data.operand, 3126 recog_data.n_operands); 3127 3128 if (!targetm.asm_out.unwind_emit_before_insn 3129 && targetm.asm_out.unwind_emit) 3130 targetm.asm_out.unwind_emit (asm_out_file, insn); 3131 3132 /* Let the debug info back-end know about this call. We do this only 3133 after the instruction has been emitted because labels that may be 3134 created to reference the call instruction must appear after it. */ 3135 if (call_insn != NULL && !DECL_IGNORED_P (current_function_decl)) 3136 debug_hooks->var_location (insn); 3137 3138 current_output_insn = debug_insn = 0; 3139 } 3140 } 3141 return NEXT_INSN (insn); 3142 } 3143 3144 /* Return whether a source line note needs to be emitted before INSN. 3145 Sets IS_STMT to TRUE if the line should be marked as a possible 3146 breakpoint location. */ 3147 3148 static bool 3149 notice_source_line (rtx_insn *insn, bool *is_stmt) 3150 { 3151 const char *filename; 3152 int linenum; 3153 3154 if (override_filename) 3155 { 3156 filename = override_filename; 3157 linenum = override_linenum; 3158 } 3159 else if (INSN_HAS_LOCATION (insn)) 3160 { 3161 expanded_location xloc = insn_location (insn); 3162 filename = xloc.file; 3163 linenum = xloc.line; 3164 } 3165 else 3166 { 3167 filename = NULL; 3168 linenum = 0; 3169 } 3170 3171 if (filename == NULL) 3172 return false; 3173 3174 if (force_source_line 3175 || filename != last_filename 3176 || last_linenum != linenum) 3177 { 3178 force_source_line = false; 3179 last_filename = filename; 3180 last_linenum = linenum; 3181 last_discriminator = discriminator; 3182 *is_stmt = true; 3183 high_block_linenum = MAX (last_linenum, high_block_linenum); 3184 high_function_linenum = MAX (last_linenum, high_function_linenum); 3185 return true; 3186 } 3187 3188 if (SUPPORTS_DISCRIMINATOR && last_discriminator != discriminator) 3189 { 3190 /* If the discriminator changed, but the line number did not, 3191 output the line table entry with is_stmt false so the 3192 debugger does not treat this as a breakpoint location. */ 3193 last_discriminator = discriminator; 3194 *is_stmt = false; 3195 return true; 3196 } 3197 3198 return false; 3199 } 3200 3201 /* For each operand in INSN, simplify (subreg (reg)) so that it refers 3202 directly to the desired hard register. */ 3203 3204 void 3205 cleanup_subreg_operands (rtx_insn *insn) 3206 { 3207 int i; 3208 bool changed = false; 3209 extract_insn_cached (insn); 3210 for (i = 0; i < recog_data.n_operands; i++) 3211 { 3212 /* The following test cannot use recog_data.operand when testing 3213 for a SUBREG: the underlying object might have been changed 3214 already if we are inside a match_operator expression that 3215 matches the else clause. Instead we test the underlying 3216 expression directly. */ 3217 if (GET_CODE (*recog_data.operand_loc[i]) == SUBREG) 3218 { 3219 recog_data.operand[i] = alter_subreg (recog_data.operand_loc[i], true); 3220 changed = true; 3221 } 3222 else if (GET_CODE (recog_data.operand[i]) == PLUS 3223 || GET_CODE (recog_data.operand[i]) == MULT 3224 || MEM_P (recog_data.operand[i])) 3225 recog_data.operand[i] = walk_alter_subreg (recog_data.operand_loc[i], &changed); 3226 } 3227 3228 for (i = 0; i < recog_data.n_dups; i++) 3229 { 3230 if (GET_CODE (*recog_data.dup_loc[i]) == SUBREG) 3231 { 3232 *recog_data.dup_loc[i] = alter_subreg (recog_data.dup_loc[i], true); 3233 changed = true; 3234 } 3235 else if (GET_CODE (*recog_data.dup_loc[i]) == PLUS 3236 || GET_CODE (*recog_data.dup_loc[i]) == MULT 3237 || MEM_P (*recog_data.dup_loc[i])) 3238 *recog_data.dup_loc[i] = walk_alter_subreg (recog_data.dup_loc[i], &changed); 3239 } 3240 if (changed) 3241 df_insn_rescan (insn); 3242 } 3243 3244 /* If X is a SUBREG, try to replace it with a REG or a MEM, based on 3245 the thing it is a subreg of. Do it anyway if FINAL_P. */ 3246 3247 rtx 3248 alter_subreg (rtx *xp, bool final_p) 3249 { 3250 rtx x = *xp; 3251 rtx y = SUBREG_REG (x); 3252 3253 /* simplify_subreg does not remove subreg from volatile references. 3254 We are required to. */ 3255 if (MEM_P (y)) 3256 { 3257 int offset = SUBREG_BYTE (x); 3258 3259 /* For paradoxical subregs on big-endian machines, SUBREG_BYTE 3260 contains 0 instead of the proper offset. See simplify_subreg. */ 3261 if (offset == 0 3262 && GET_MODE_SIZE (GET_MODE (y)) < GET_MODE_SIZE (GET_MODE (x))) 3263 { 3264 int difference = GET_MODE_SIZE (GET_MODE (y)) 3265 - GET_MODE_SIZE (GET_MODE (x)); 3266 if (WORDS_BIG_ENDIAN) 3267 offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD; 3268 if (BYTES_BIG_ENDIAN) 3269 offset += difference % UNITS_PER_WORD; 3270 } 3271 3272 if (final_p) 3273 *xp = adjust_address (y, GET_MODE (x), offset); 3274 else 3275 *xp = adjust_address_nv (y, GET_MODE (x), offset); 3276 } 3277 else if (REG_P (y) && HARD_REGISTER_P (y)) 3278 { 3279 rtx new_rtx = simplify_subreg (GET_MODE (x), y, GET_MODE (y), 3280 SUBREG_BYTE (x)); 3281 3282 if (new_rtx != 0) 3283 *xp = new_rtx; 3284 else if (final_p && REG_P (y)) 3285 { 3286 /* Simplify_subreg can't handle some REG cases, but we have to. */ 3287 unsigned int regno; 3288 HOST_WIDE_INT offset; 3289 3290 regno = subreg_regno (x); 3291 if (subreg_lowpart_p (x)) 3292 offset = byte_lowpart_offset (GET_MODE (x), GET_MODE (y)); 3293 else 3294 offset = SUBREG_BYTE (x); 3295 *xp = gen_rtx_REG_offset (y, GET_MODE (x), regno, offset); 3296 } 3297 } 3298 3299 return *xp; 3300 } 3301 3302 /* Do alter_subreg on all the SUBREGs contained in X. */ 3303 3304 static rtx 3305 walk_alter_subreg (rtx *xp, bool *changed) 3306 { 3307 rtx x = *xp; 3308 switch (GET_CODE (x)) 3309 { 3310 case PLUS: 3311 case MULT: 3312 case AND: 3313 XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0), changed); 3314 XEXP (x, 1) = walk_alter_subreg (&XEXP (x, 1), changed); 3315 break; 3316 3317 case MEM: 3318 case ZERO_EXTEND: 3319 XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0), changed); 3320 break; 3321 3322 case SUBREG: 3323 *changed = true; 3324 return alter_subreg (xp, true); 3325 3326 default: 3327 break; 3328 } 3329 3330 return *xp; 3331 } 3332 3333 #if HAVE_cc0 3334 3335 /* Given BODY, the body of a jump instruction, alter the jump condition 3336 as required by the bits that are set in cc_status.flags. 3337 Not all of the bits there can be handled at this level in all cases. 3338 3339 The value is normally 0. 3340 1 means that the condition has become always true. 3341 -1 means that the condition has become always false. 3342 2 means that COND has been altered. */ 3343 3344 static int 3345 alter_cond (rtx cond) 3346 { 3347 int value = 0; 3348 3349 if (cc_status.flags & CC_REVERSED) 3350 { 3351 value = 2; 3352 PUT_CODE (cond, swap_condition (GET_CODE (cond))); 3353 } 3354 3355 if (cc_status.flags & CC_INVERTED) 3356 { 3357 value = 2; 3358 PUT_CODE (cond, reverse_condition (GET_CODE (cond))); 3359 } 3360 3361 if (cc_status.flags & CC_NOT_POSITIVE) 3362 switch (GET_CODE (cond)) 3363 { 3364 case LE: 3365 case LEU: 3366 case GEU: 3367 /* Jump becomes unconditional. */ 3368 return 1; 3369 3370 case GT: 3371 case GTU: 3372 case LTU: 3373 /* Jump becomes no-op. */ 3374 return -1; 3375 3376 case GE: 3377 PUT_CODE (cond, EQ); 3378 value = 2; 3379 break; 3380 3381 case LT: 3382 PUT_CODE (cond, NE); 3383 value = 2; 3384 break; 3385 3386 default: 3387 break; 3388 } 3389 3390 if (cc_status.flags & CC_NOT_NEGATIVE) 3391 switch (GET_CODE (cond)) 3392 { 3393 case GE: 3394 case GEU: 3395 /* Jump becomes unconditional. */ 3396 return 1; 3397 3398 case LT: 3399 case LTU: 3400 /* Jump becomes no-op. */ 3401 return -1; 3402 3403 case LE: 3404 case LEU: 3405 PUT_CODE (cond, EQ); 3406 value = 2; 3407 break; 3408 3409 case GT: 3410 case GTU: 3411 PUT_CODE (cond, NE); 3412 value = 2; 3413 break; 3414 3415 default: 3416 break; 3417 } 3418 3419 if (cc_status.flags & CC_NO_OVERFLOW) 3420 switch (GET_CODE (cond)) 3421 { 3422 case GEU: 3423 /* Jump becomes unconditional. */ 3424 return 1; 3425 3426 case LEU: 3427 PUT_CODE (cond, EQ); 3428 value = 2; 3429 break; 3430 3431 case GTU: 3432 PUT_CODE (cond, NE); 3433 value = 2; 3434 break; 3435 3436 case LTU: 3437 /* Jump becomes no-op. */ 3438 return -1; 3439 3440 default: 3441 break; 3442 } 3443 3444 if (cc_status.flags & (CC_Z_IN_NOT_N | CC_Z_IN_N)) 3445 switch (GET_CODE (cond)) 3446 { 3447 default: 3448 gcc_unreachable (); 3449 3450 case NE: 3451 PUT_CODE (cond, cc_status.flags & CC_Z_IN_N ? GE : LT); 3452 value = 2; 3453 break; 3454 3455 case EQ: 3456 PUT_CODE (cond, cc_status.flags & CC_Z_IN_N ? LT : GE); 3457 value = 2; 3458 break; 3459 } 3460 3461 if (cc_status.flags & CC_NOT_SIGNED) 3462 /* The flags are valid if signed condition operators are converted 3463 to unsigned. */ 3464 switch (GET_CODE (cond)) 3465 { 3466 case LE: 3467 PUT_CODE (cond, LEU); 3468 value = 2; 3469 break; 3470 3471 case LT: 3472 PUT_CODE (cond, LTU); 3473 value = 2; 3474 break; 3475 3476 case GT: 3477 PUT_CODE (cond, GTU); 3478 value = 2; 3479 break; 3480 3481 case GE: 3482 PUT_CODE (cond, GEU); 3483 value = 2; 3484 break; 3485 3486 default: 3487 break; 3488 } 3489 3490 return value; 3491 } 3492 #endif 3493 3494 /* Report inconsistency between the assembler template and the operands. 3495 In an `asm', it's the user's fault; otherwise, the compiler's fault. */ 3496 3497 void 3498 output_operand_lossage (const char *cmsgid, ...) 3499 { 3500 char *fmt_string; 3501 char *new_message; 3502 const char *pfx_str; 3503 va_list ap; 3504 3505 va_start (ap, cmsgid); 3506 3507 pfx_str = this_is_asm_operands ? _("invalid 'asm': ") : "output_operand: "; 3508 fmt_string = xasprintf ("%s%s", pfx_str, _(cmsgid)); 3509 new_message = xvasprintf (fmt_string, ap); 3510 3511 if (this_is_asm_operands) 3512 error_for_asm (this_is_asm_operands, "%s", new_message); 3513 else 3514 internal_error ("%s", new_message); 3515 3516 free (fmt_string); 3517 free (new_message); 3518 va_end (ap); 3519 } 3520 3521 /* Output of assembler code from a template, and its subroutines. */ 3522 3523 /* Annotate the assembly with a comment describing the pattern and 3524 alternative used. */ 3525 3526 static void 3527 output_asm_name (void) 3528 { 3529 if (debug_insn) 3530 { 3531 int num = INSN_CODE (debug_insn); 3532 fprintf (asm_out_file, "\t%s %d\t%s", 3533 ASM_COMMENT_START, INSN_UID (debug_insn), 3534 insn_data[num].name); 3535 if (insn_data[num].n_alternatives > 1) 3536 fprintf (asm_out_file, "/%d", which_alternative + 1); 3537 3538 if (HAVE_ATTR_length) 3539 fprintf (asm_out_file, "\t[length = %d]", 3540 get_attr_length (debug_insn)); 3541 3542 /* Clear this so only the first assembler insn 3543 of any rtl insn will get the special comment for -dp. */ 3544 debug_insn = 0; 3545 } 3546 } 3547 3548 /* If OP is a REG or MEM and we can find a MEM_EXPR corresponding to it 3549 or its address, return that expr . Set *PADDRESSP to 1 if the expr 3550 corresponds to the address of the object and 0 if to the object. */ 3551 3552 static tree 3553 get_mem_expr_from_op (rtx op, int *paddressp) 3554 { 3555 tree expr; 3556 int inner_addressp; 3557 3558 *paddressp = 0; 3559 3560 if (REG_P (op)) 3561 return REG_EXPR (op); 3562 else if (!MEM_P (op)) 3563 return 0; 3564 3565 if (MEM_EXPR (op) != 0) 3566 return MEM_EXPR (op); 3567 3568 /* Otherwise we have an address, so indicate it and look at the address. */ 3569 *paddressp = 1; 3570 op = XEXP (op, 0); 3571 3572 /* First check if we have a decl for the address, then look at the right side 3573 if it is a PLUS. Otherwise, strip off arithmetic and keep looking. 3574 But don't allow the address to itself be indirect. */ 3575 if ((expr = get_mem_expr_from_op (op, &inner_addressp)) && ! inner_addressp) 3576 return expr; 3577 else if (GET_CODE (op) == PLUS 3578 && (expr = get_mem_expr_from_op (XEXP (op, 1), &inner_addressp))) 3579 return expr; 3580 3581 while (UNARY_P (op) 3582 || GET_RTX_CLASS (GET_CODE (op)) == RTX_BIN_ARITH) 3583 op = XEXP (op, 0); 3584 3585 expr = get_mem_expr_from_op (op, &inner_addressp); 3586 return inner_addressp ? 0 : expr; 3587 } 3588 3589 /* Output operand names for assembler instructions. OPERANDS is the 3590 operand vector, OPORDER is the order to write the operands, and NOPS 3591 is the number of operands to write. */ 3592 3593 static void 3594 output_asm_operand_names (rtx *operands, int *oporder, int nops) 3595 { 3596 int wrote = 0; 3597 int i; 3598 3599 for (i = 0; i < nops; i++) 3600 { 3601 int addressp; 3602 rtx op = operands[oporder[i]]; 3603 tree expr = get_mem_expr_from_op (op, &addressp); 3604 3605 fprintf (asm_out_file, "%c%s", 3606 wrote ? ',' : '\t', wrote ? "" : ASM_COMMENT_START); 3607 wrote = 1; 3608 if (expr) 3609 { 3610 fprintf (asm_out_file, "%s", 3611 addressp ? "*" : ""); 3612 print_mem_expr (asm_out_file, expr); 3613 wrote = 1; 3614 } 3615 else if (REG_P (op) && ORIGINAL_REGNO (op) 3616 && ORIGINAL_REGNO (op) != REGNO (op)) 3617 fprintf (asm_out_file, " tmp%i", ORIGINAL_REGNO (op)); 3618 } 3619 } 3620 3621 #ifdef ASSEMBLER_DIALECT 3622 /* Helper function to parse assembler dialects in the asm string. 3623 This is called from output_asm_insn and asm_fprintf. */ 3624 static const char * 3625 do_assembler_dialects (const char *p, int *dialect) 3626 { 3627 char c = *(p - 1); 3628 3629 switch (c) 3630 { 3631 case '{': 3632 { 3633 int i; 3634 3635 if (*dialect) 3636 output_operand_lossage ("nested assembly dialect alternatives"); 3637 else 3638 *dialect = 1; 3639 3640 /* If we want the first dialect, do nothing. Otherwise, skip 3641 DIALECT_NUMBER of strings ending with '|'. */ 3642 for (i = 0; i < dialect_number; i++) 3643 { 3644 while (*p && *p != '}') 3645 { 3646 if (*p == '|') 3647 { 3648 p++; 3649 break; 3650 } 3651 3652 /* Skip over any character after a percent sign. */ 3653 if (*p == '%') 3654 p++; 3655 if (*p) 3656 p++; 3657 } 3658 3659 if (*p == '}') 3660 break; 3661 } 3662 3663 if (*p == '\0') 3664 output_operand_lossage ("unterminated assembly dialect alternative"); 3665 } 3666 break; 3667 3668 case '|': 3669 if (*dialect) 3670 { 3671 /* Skip to close brace. */ 3672 do 3673 { 3674 if (*p == '\0') 3675 { 3676 output_operand_lossage ("unterminated assembly dialect alternative"); 3677 break; 3678 } 3679 3680 /* Skip over any character after a percent sign. */ 3681 if (*p == '%' && p[1]) 3682 { 3683 p += 2; 3684 continue; 3685 } 3686 3687 if (*p++ == '}') 3688 break; 3689 } 3690 while (1); 3691 3692 *dialect = 0; 3693 } 3694 else 3695 putc (c, asm_out_file); 3696 break; 3697 3698 case '}': 3699 if (! *dialect) 3700 putc (c, asm_out_file); 3701 *dialect = 0; 3702 break; 3703 default: 3704 gcc_unreachable (); 3705 } 3706 3707 return p; 3708 } 3709 #endif 3710 3711 /* Output text from TEMPLATE to the assembler output file, 3712 obeying %-directions to substitute operands taken from 3713 the vector OPERANDS. 3714 3715 %N (for N a digit) means print operand N in usual manner. 3716 %lN means require operand N to be a CODE_LABEL or LABEL_REF 3717 and print the label name with no punctuation. 3718 %cN means require operand N to be a constant 3719 and print the constant expression with no punctuation. 3720 %aN means expect operand N to be a memory address 3721 (not a memory reference!) and print a reference 3722 to that address. 3723 %nN means expect operand N to be a constant 3724 and print a constant expression for minus the value 3725 of the operand, with no other punctuation. */ 3726 3727 void 3728 output_asm_insn (const char *templ, rtx *operands) 3729 { 3730 const char *p; 3731 int c; 3732 #ifdef ASSEMBLER_DIALECT 3733 int dialect = 0; 3734 #endif 3735 int oporder[MAX_RECOG_OPERANDS]; 3736 char opoutput[MAX_RECOG_OPERANDS]; 3737 int ops = 0; 3738 3739 /* An insn may return a null string template 3740 in a case where no assembler code is needed. */ 3741 if (*templ == 0) 3742 return; 3743 3744 memset (opoutput, 0, sizeof opoutput); 3745 p = templ; 3746 putc ('\t', asm_out_file); 3747 3748 #ifdef ASM_OUTPUT_OPCODE 3749 ASM_OUTPUT_OPCODE (asm_out_file, p); 3750 #endif 3751 3752 while ((c = *p++)) 3753 switch (c) 3754 { 3755 case '\n': 3756 if (flag_verbose_asm) 3757 output_asm_operand_names (operands, oporder, ops); 3758 if (flag_print_asm_name) 3759 output_asm_name (); 3760 3761 ops = 0; 3762 memset (opoutput, 0, sizeof opoutput); 3763 3764 putc (c, asm_out_file); 3765 #ifdef ASM_OUTPUT_OPCODE 3766 while ((c = *p) == '\t') 3767 { 3768 putc (c, asm_out_file); 3769 p++; 3770 } 3771 ASM_OUTPUT_OPCODE (asm_out_file, p); 3772 #endif 3773 break; 3774 3775 #ifdef ASSEMBLER_DIALECT 3776 case '{': 3777 case '}': 3778 case '|': 3779 p = do_assembler_dialects (p, &dialect); 3780 break; 3781 #endif 3782 3783 case '%': 3784 /* %% outputs a single %. %{, %} and %| print {, } and | respectively 3785 if ASSEMBLER_DIALECT defined and these characters have a special 3786 meaning as dialect delimiters.*/ 3787 if (*p == '%' 3788 #ifdef ASSEMBLER_DIALECT 3789 || *p == '{' || *p == '}' || *p == '|' 3790 #endif 3791 ) 3792 { 3793 putc (*p, asm_out_file); 3794 p++; 3795 } 3796 /* %= outputs a number which is unique to each insn in the entire 3797 compilation. This is useful for making local labels that are 3798 referred to more than once in a given insn. */ 3799 else if (*p == '=') 3800 { 3801 p++; 3802 fprintf (asm_out_file, "%d", insn_counter); 3803 } 3804 /* % followed by a letter and some digits 3805 outputs an operand in a special way depending on the letter. 3806 Letters `acln' are implemented directly. 3807 Other letters are passed to `output_operand' so that 3808 the TARGET_PRINT_OPERAND hook can define them. */ 3809 else if (ISALPHA (*p)) 3810 { 3811 int letter = *p++; 3812 unsigned long opnum; 3813 char *endptr; 3814 3815 opnum = strtoul (p, &endptr, 10); 3816 3817 if (endptr == p) 3818 output_operand_lossage ("operand number missing " 3819 "after %%-letter"); 3820 else if (this_is_asm_operands && opnum >= insn_noperands) 3821 output_operand_lossage ("operand number out of range"); 3822 else if (letter == 'l') 3823 output_asm_label (operands[opnum]); 3824 else if (letter == 'a') 3825 output_address (VOIDmode, operands[opnum]); 3826 else if (letter == 'c') 3827 { 3828 if (CONSTANT_ADDRESS_P (operands[opnum])) 3829 output_addr_const (asm_out_file, operands[opnum]); 3830 else 3831 output_operand (operands[opnum], 'c'); 3832 } 3833 else if (letter == 'n') 3834 { 3835 if (CONST_INT_P (operands[opnum])) 3836 fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, 3837 - INTVAL (operands[opnum])); 3838 else 3839 { 3840 putc ('-', asm_out_file); 3841 output_addr_const (asm_out_file, operands[opnum]); 3842 } 3843 } 3844 else 3845 output_operand (operands[opnum], letter); 3846 3847 if (!opoutput[opnum]) 3848 oporder[ops++] = opnum; 3849 opoutput[opnum] = 1; 3850 3851 p = endptr; 3852 c = *p; 3853 } 3854 /* % followed by a digit outputs an operand the default way. */ 3855 else if (ISDIGIT (*p)) 3856 { 3857 unsigned long opnum; 3858 char *endptr; 3859 3860 opnum = strtoul (p, &endptr, 10); 3861 if (this_is_asm_operands && opnum >= insn_noperands) 3862 output_operand_lossage ("operand number out of range"); 3863 else 3864 output_operand (operands[opnum], 0); 3865 3866 if (!opoutput[opnum]) 3867 oporder[ops++] = opnum; 3868 opoutput[opnum] = 1; 3869 3870 p = endptr; 3871 c = *p; 3872 } 3873 /* % followed by punctuation: output something for that 3874 punctuation character alone, with no operand. The 3875 TARGET_PRINT_OPERAND hook decides what is actually done. */ 3876 else if (targetm.asm_out.print_operand_punct_valid_p ((unsigned char) *p)) 3877 output_operand (NULL_RTX, *p++); 3878 else 3879 output_operand_lossage ("invalid %%-code"); 3880 break; 3881 3882 default: 3883 putc (c, asm_out_file); 3884 } 3885 3886 /* Write out the variable names for operands, if we know them. */ 3887 if (flag_verbose_asm) 3888 output_asm_operand_names (operands, oporder, ops); 3889 if (flag_print_asm_name) 3890 output_asm_name (); 3891 3892 putc ('\n', asm_out_file); 3893 } 3894 3895 /* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol. */ 3896 3897 void 3898 output_asm_label (rtx x) 3899 { 3900 char buf[256]; 3901 3902 if (GET_CODE (x) == LABEL_REF) 3903 x = LABEL_REF_LABEL (x); 3904 if (LABEL_P (x) 3905 || (NOTE_P (x) 3906 && NOTE_KIND (x) == NOTE_INSN_DELETED_LABEL)) 3907 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x)); 3908 else 3909 output_operand_lossage ("'%%l' operand isn't a label"); 3910 3911 assemble_name (asm_out_file, buf); 3912 } 3913 3914 /* Marks SYMBOL_REFs in x as referenced through use of assemble_external. */ 3915 3916 void 3917 mark_symbol_refs_as_used (rtx x) 3918 { 3919 subrtx_iterator::array_type array; 3920 FOR_EACH_SUBRTX (iter, array, x, ALL) 3921 { 3922 const_rtx x = *iter; 3923 if (GET_CODE (x) == SYMBOL_REF) 3924 if (tree t = SYMBOL_REF_DECL (x)) 3925 assemble_external (t); 3926 } 3927 } 3928 3929 /* Print operand X using machine-dependent assembler syntax. 3930 CODE is a non-digit that preceded the operand-number in the % spec, 3931 such as 'z' if the spec was `%z3'. CODE is 0 if there was no char 3932 between the % and the digits. 3933 When CODE is a non-letter, X is 0. 3934 3935 The meanings of the letters are machine-dependent and controlled 3936 by TARGET_PRINT_OPERAND. */ 3937 3938 void 3939 output_operand (rtx x, int code ATTRIBUTE_UNUSED) 3940 { 3941 if (x && GET_CODE (x) == SUBREG) 3942 x = alter_subreg (&x, true); 3943 3944 /* X must not be a pseudo reg. */ 3945 if (!targetm.no_register_allocation) 3946 gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER); 3947 3948 targetm.asm_out.print_operand (asm_out_file, x, code); 3949 3950 if (x == NULL_RTX) 3951 return; 3952 3953 mark_symbol_refs_as_used (x); 3954 } 3955 3956 /* Print a memory reference operand for address X using 3957 machine-dependent assembler syntax. */ 3958 3959 void 3960 output_address (machine_mode mode, rtx x) 3961 { 3962 bool changed = false; 3963 walk_alter_subreg (&x, &changed); 3964 targetm.asm_out.print_operand_address (asm_out_file, mode, x); 3965 } 3966 3967 /* Print an integer constant expression in assembler syntax. 3968 Addition and subtraction are the only arithmetic 3969 that may appear in these expressions. */ 3970 3971 void 3972 output_addr_const (FILE *file, rtx x) 3973 { 3974 char buf[256]; 3975 3976 restart: 3977 switch (GET_CODE (x)) 3978 { 3979 case PC: 3980 putc ('.', file); 3981 break; 3982 3983 case SYMBOL_REF: 3984 if (SYMBOL_REF_DECL (x)) 3985 assemble_external (SYMBOL_REF_DECL (x)); 3986 #ifdef ASM_OUTPUT_SYMBOL_REF 3987 ASM_OUTPUT_SYMBOL_REF (file, x); 3988 #else 3989 assemble_name (file, XSTR (x, 0)); 3990 #endif 3991 break; 3992 3993 case LABEL_REF: 3994 x = LABEL_REF_LABEL (x); 3995 /* Fall through. */ 3996 case CODE_LABEL: 3997 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x)); 3998 #ifdef ASM_OUTPUT_LABEL_REF 3999 ASM_OUTPUT_LABEL_REF (file, buf); 4000 #else 4001 assemble_name (file, buf); 4002 #endif 4003 break; 4004 4005 case CONST_INT: 4006 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x)); 4007 break; 4008 4009 case CONST: 4010 /* This used to output parentheses around the expression, 4011 but that does not work on the 386 (either ATT or BSD assembler). */ 4012 output_addr_const (file, XEXP (x, 0)); 4013 break; 4014 4015 case CONST_WIDE_INT: 4016 /* We do not know the mode here so we have to use a round about 4017 way to build a wide-int to get it printed properly. */ 4018 { 4019 wide_int w = wide_int::from_array (&CONST_WIDE_INT_ELT (x, 0), 4020 CONST_WIDE_INT_NUNITS (x), 4021 CONST_WIDE_INT_NUNITS (x) 4022 * HOST_BITS_PER_WIDE_INT, 4023 false); 4024 print_decs (w, file); 4025 } 4026 break; 4027 4028 case CONST_DOUBLE: 4029 if (CONST_DOUBLE_AS_INT_P (x)) 4030 { 4031 /* We can use %d if the number is one word and positive. */ 4032 if (CONST_DOUBLE_HIGH (x)) 4033 fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX, 4034 (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x), 4035 (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x)); 4036 else if (CONST_DOUBLE_LOW (x) < 0) 4037 fprintf (file, HOST_WIDE_INT_PRINT_HEX, 4038 (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x)); 4039 else 4040 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x)); 4041 } 4042 else 4043 /* We can't handle floating point constants; 4044 PRINT_OPERAND must handle them. */ 4045 output_operand_lossage ("floating constant misused"); 4046 break; 4047 4048 case CONST_FIXED: 4049 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_FIXED_VALUE_LOW (x)); 4050 break; 4051 4052 case PLUS: 4053 /* Some assemblers need integer constants to appear last (eg masm). */ 4054 if (CONST_INT_P (XEXP (x, 0))) 4055 { 4056 output_addr_const (file, XEXP (x, 1)); 4057 if (INTVAL (XEXP (x, 0)) >= 0) 4058 fprintf (file, "+"); 4059 output_addr_const (file, XEXP (x, 0)); 4060 } 4061 else 4062 { 4063 output_addr_const (file, XEXP (x, 0)); 4064 if (!CONST_INT_P (XEXP (x, 1)) 4065 || INTVAL (XEXP (x, 1)) >= 0) 4066 fprintf (file, "+"); 4067 output_addr_const (file, XEXP (x, 1)); 4068 } 4069 break; 4070 4071 case MINUS: 4072 /* Avoid outputting things like x-x or x+5-x, 4073 since some assemblers can't handle that. */ 4074 x = simplify_subtraction (x); 4075 if (GET_CODE (x) != MINUS) 4076 goto restart; 4077 4078 output_addr_const (file, XEXP (x, 0)); 4079 fprintf (file, "-"); 4080 if ((CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) >= 0) 4081 || GET_CODE (XEXP (x, 1)) == PC 4082 || GET_CODE (XEXP (x, 1)) == SYMBOL_REF) 4083 output_addr_const (file, XEXP (x, 1)); 4084 else 4085 { 4086 fputs (targetm.asm_out.open_paren, file); 4087 output_addr_const (file, XEXP (x, 1)); 4088 fputs (targetm.asm_out.close_paren, file); 4089 } 4090 break; 4091 4092 case ZERO_EXTEND: 4093 case SIGN_EXTEND: 4094 case SUBREG: 4095 case TRUNCATE: 4096 output_addr_const (file, XEXP (x, 0)); 4097 break; 4098 4099 default: 4100 if (targetm.asm_out.output_addr_const_extra (file, x)) 4101 break; 4102 4103 output_operand_lossage ("invalid expression as operand"); 4104 } 4105 } 4106 4107 /* Output a quoted string. */ 4108 4109 void 4110 output_quoted_string (FILE *asm_file, const char *string) 4111 { 4112 #ifdef OUTPUT_QUOTED_STRING 4113 OUTPUT_QUOTED_STRING (asm_file, string); 4114 #else 4115 char c; 4116 4117 putc ('\"', asm_file); 4118 while ((c = *string++) != 0) 4119 { 4120 if (ISPRINT (c)) 4121 { 4122 if (c == '\"' || c == '\\') 4123 putc ('\\', asm_file); 4124 putc (c, asm_file); 4125 } 4126 else 4127 fprintf (asm_file, "\\%03o", (unsigned char) c); 4128 } 4129 putc ('\"', asm_file); 4130 #endif 4131 } 4132 4133 /* Write a HOST_WIDE_INT number in hex form 0x1234, fast. */ 4134 4135 void 4136 fprint_whex (FILE *f, unsigned HOST_WIDE_INT value) 4137 { 4138 char buf[2 + CHAR_BIT * sizeof (value) / 4]; 4139 if (value == 0) 4140 putc ('0', f); 4141 else 4142 { 4143 char *p = buf + sizeof (buf); 4144 do 4145 *--p = "0123456789abcdef"[value % 16]; 4146 while ((value /= 16) != 0); 4147 *--p = 'x'; 4148 *--p = '0'; 4149 fwrite (p, 1, buf + sizeof (buf) - p, f); 4150 } 4151 } 4152 4153 /* Internal function that prints an unsigned long in decimal in reverse. 4154 The output string IS NOT null-terminated. */ 4155 4156 static int 4157 sprint_ul_rev (char *s, unsigned long value) 4158 { 4159 int i = 0; 4160 do 4161 { 4162 s[i] = "0123456789"[value % 10]; 4163 value /= 10; 4164 i++; 4165 /* alternate version, without modulo */ 4166 /* oldval = value; */ 4167 /* value /= 10; */ 4168 /* s[i] = "0123456789" [oldval - 10*value]; */ 4169 /* i++ */ 4170 } 4171 while (value != 0); 4172 return i; 4173 } 4174 4175 /* Write an unsigned long as decimal to a file, fast. */ 4176 4177 void 4178 fprint_ul (FILE *f, unsigned long value) 4179 { 4180 /* python says: len(str(2**64)) == 20 */ 4181 char s[20]; 4182 int i; 4183 4184 i = sprint_ul_rev (s, value); 4185 4186 /* It's probably too small to bother with string reversal and fputs. */ 4187 do 4188 { 4189 i--; 4190 putc (s[i], f); 4191 } 4192 while (i != 0); 4193 } 4194 4195 /* Write an unsigned long as decimal to a string, fast. 4196 s must be wide enough to not overflow, at least 21 chars. 4197 Returns the length of the string (without terminating '\0'). */ 4198 4199 int 4200 sprint_ul (char *s, unsigned long value) 4201 { 4202 int len = sprint_ul_rev (s, value); 4203 s[len] = '\0'; 4204 4205 std::reverse (s, s + len); 4206 return len; 4207 } 4208 4209 /* A poor man's fprintf, with the added features of %I, %R, %L, and %U. 4210 %R prints the value of REGISTER_PREFIX. 4211 %L prints the value of LOCAL_LABEL_PREFIX. 4212 %U prints the value of USER_LABEL_PREFIX. 4213 %I prints the value of IMMEDIATE_PREFIX. 4214 %O runs ASM_OUTPUT_OPCODE to transform what follows in the string. 4215 Also supported are %d, %i, %u, %x, %X, %o, %c, %s and %%. 4216 4217 We handle alternate assembler dialects here, just like output_asm_insn. */ 4218 4219 void 4220 asm_fprintf (FILE *file, const char *p, ...) 4221 { 4222 char buf[10]; 4223 char *q, c; 4224 #ifdef ASSEMBLER_DIALECT 4225 int dialect = 0; 4226 #endif 4227 va_list argptr; 4228 4229 va_start (argptr, p); 4230 4231 buf[0] = '%'; 4232 4233 while ((c = *p++)) 4234 switch (c) 4235 { 4236 #ifdef ASSEMBLER_DIALECT 4237 case '{': 4238 case '}': 4239 case '|': 4240 p = do_assembler_dialects (p, &dialect); 4241 break; 4242 #endif 4243 4244 case '%': 4245 c = *p++; 4246 q = &buf[1]; 4247 while (strchr ("-+ #0", c)) 4248 { 4249 *q++ = c; 4250 c = *p++; 4251 } 4252 while (ISDIGIT (c) || c == '.') 4253 { 4254 *q++ = c; 4255 c = *p++; 4256 } 4257 switch (c) 4258 { 4259 case '%': 4260 putc ('%', file); 4261 break; 4262 4263 case 'd': case 'i': case 'u': 4264 case 'x': case 'X': case 'o': 4265 case 'c': 4266 *q++ = c; 4267 *q = 0; 4268 fprintf (file, buf, va_arg (argptr, int)); 4269 break; 4270 4271 case 'w': 4272 /* This is a prefix to the 'd', 'i', 'u', 'x', 'X', and 4273 'o' cases, but we do not check for those cases. It 4274 means that the value is a HOST_WIDE_INT, which may be 4275 either `long' or `long long'. */ 4276 memcpy (q, HOST_WIDE_INT_PRINT, strlen (HOST_WIDE_INT_PRINT)); 4277 q += strlen (HOST_WIDE_INT_PRINT); 4278 *q++ = *p++; 4279 *q = 0; 4280 fprintf (file, buf, va_arg (argptr, HOST_WIDE_INT)); 4281 break; 4282 4283 case 'l': 4284 *q++ = c; 4285 #ifdef HAVE_LONG_LONG 4286 if (*p == 'l') 4287 { 4288 *q++ = *p++; 4289 *q++ = *p++; 4290 *q = 0; 4291 fprintf (file, buf, va_arg (argptr, long long)); 4292 } 4293 else 4294 #endif 4295 { 4296 *q++ = *p++; 4297 *q = 0; 4298 fprintf (file, buf, va_arg (argptr, long)); 4299 } 4300 4301 break; 4302 4303 case 's': 4304 *q++ = c; 4305 *q = 0; 4306 fprintf (file, buf, va_arg (argptr, char *)); 4307 break; 4308 4309 case 'O': 4310 #ifdef ASM_OUTPUT_OPCODE 4311 ASM_OUTPUT_OPCODE (asm_out_file, p); 4312 #endif 4313 break; 4314 4315 case 'R': 4316 #ifdef REGISTER_PREFIX 4317 fprintf (file, "%s", REGISTER_PREFIX); 4318 #endif 4319 break; 4320 4321 case 'I': 4322 #ifdef IMMEDIATE_PREFIX 4323 fprintf (file, "%s", IMMEDIATE_PREFIX); 4324 #endif 4325 break; 4326 4327 case 'L': 4328 #ifdef LOCAL_LABEL_PREFIX 4329 fprintf (file, "%s", LOCAL_LABEL_PREFIX); 4330 #endif 4331 break; 4332 4333 case 'U': 4334 fputs (user_label_prefix, file); 4335 break; 4336 4337 #ifdef ASM_FPRINTF_EXTENSIONS 4338 /* Uppercase letters are reserved for general use by asm_fprintf 4339 and so are not available to target specific code. In order to 4340 prevent the ASM_FPRINTF_EXTENSIONS macro from using them then, 4341 they are defined here. As they get turned into real extensions 4342 to asm_fprintf they should be removed from this list. */ 4343 case 'A': case 'B': case 'C': case 'D': case 'E': 4344 case 'F': case 'G': case 'H': case 'J': case 'K': 4345 case 'M': case 'N': case 'P': case 'Q': case 'S': 4346 case 'T': case 'V': case 'W': case 'Y': case 'Z': 4347 break; 4348 4349 ASM_FPRINTF_EXTENSIONS (file, argptr, p) 4350 #endif 4351 default: 4352 gcc_unreachable (); 4353 } 4354 break; 4355 4356 default: 4357 putc (c, file); 4358 } 4359 va_end (argptr); 4360 } 4361 4362 /* Return nonzero if this function has no function calls. */ 4363 4364 int 4365 leaf_function_p (void) 4366 { 4367 rtx_insn *insn; 4368 4369 /* Some back-ends (e.g. s390) want leaf functions to stay leaf 4370 functions even if they call mcount. */ 4371 if (crtl->profile && !targetm.keep_leaf_when_profiled ()) 4372 return 0; 4373 4374 for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 4375 { 4376 if (CALL_P (insn) 4377 && ! SIBLING_CALL_P (insn)) 4378 return 0; 4379 if (NONJUMP_INSN_P (insn) 4380 && GET_CODE (PATTERN (insn)) == SEQUENCE 4381 && CALL_P (XVECEXP (PATTERN (insn), 0, 0)) 4382 && ! SIBLING_CALL_P (XVECEXP (PATTERN (insn), 0, 0))) 4383 return 0; 4384 } 4385 4386 return 1; 4387 } 4388 4389 /* Return 1 if branch is a forward branch. 4390 Uses insn_shuid array, so it works only in the final pass. May be used by 4391 output templates to customary add branch prediction hints. 4392 */ 4393 int 4394 final_forward_branch_p (rtx_insn *insn) 4395 { 4396 int insn_id, label_id; 4397 4398 gcc_assert (uid_shuid); 4399 insn_id = INSN_SHUID (insn); 4400 label_id = INSN_SHUID (JUMP_LABEL (insn)); 4401 /* We've hit some insns that does not have id information available. */ 4402 gcc_assert (insn_id && label_id); 4403 return insn_id < label_id; 4404 } 4405 4406 /* On some machines, a function with no call insns 4407 can run faster if it doesn't create its own register window. 4408 When output, the leaf function should use only the "output" 4409 registers. Ordinarily, the function would be compiled to use 4410 the "input" registers to find its arguments; it is a candidate 4411 for leaf treatment if it uses only the "input" registers. 4412 Leaf function treatment means renumbering so the function 4413 uses the "output" registers instead. */ 4414 4415 #ifdef LEAF_REGISTERS 4416 4417 /* Return 1 if this function uses only the registers that can be 4418 safely renumbered. */ 4419 4420 int 4421 only_leaf_regs_used (void) 4422 { 4423 int i; 4424 const char *const permitted_reg_in_leaf_functions = LEAF_REGISTERS; 4425 4426 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 4427 if ((df_regs_ever_live_p (i) || global_regs[i]) 4428 && ! permitted_reg_in_leaf_functions[i]) 4429 return 0; 4430 4431 if (crtl->uses_pic_offset_table 4432 && pic_offset_table_rtx != 0 4433 && REG_P (pic_offset_table_rtx) 4434 && ! permitted_reg_in_leaf_functions[REGNO (pic_offset_table_rtx)]) 4435 return 0; 4436 4437 return 1; 4438 } 4439 4440 /* Scan all instructions and renumber all registers into those 4441 available in leaf functions. */ 4442 4443 static void 4444 leaf_renumber_regs (rtx_insn *first) 4445 { 4446 rtx_insn *insn; 4447 4448 /* Renumber only the actual patterns. 4449 The reg-notes can contain frame pointer refs, 4450 and renumbering them could crash, and should not be needed. */ 4451 for (insn = first; insn; insn = NEXT_INSN (insn)) 4452 if (INSN_P (insn)) 4453 leaf_renumber_regs_insn (PATTERN (insn)); 4454 } 4455 4456 /* Scan IN_RTX and its subexpressions, and renumber all regs into those 4457 available in leaf functions. */ 4458 4459 void 4460 leaf_renumber_regs_insn (rtx in_rtx) 4461 { 4462 int i, j; 4463 const char *format_ptr; 4464 4465 if (in_rtx == 0) 4466 return; 4467 4468 /* Renumber all input-registers into output-registers. 4469 renumbered_regs would be 1 for an output-register; 4470 they */ 4471 4472 if (REG_P (in_rtx)) 4473 { 4474 int newreg; 4475 4476 /* Don't renumber the same reg twice. */ 4477 if (in_rtx->used) 4478 return; 4479 4480 newreg = REGNO (in_rtx); 4481 /* Don't try to renumber pseudo regs. It is possible for a pseudo reg 4482 to reach here as part of a REG_NOTE. */ 4483 if (newreg >= FIRST_PSEUDO_REGISTER) 4484 { 4485 in_rtx->used = 1; 4486 return; 4487 } 4488 newreg = LEAF_REG_REMAP (newreg); 4489 gcc_assert (newreg >= 0); 4490 df_set_regs_ever_live (REGNO (in_rtx), false); 4491 df_set_regs_ever_live (newreg, true); 4492 SET_REGNO (in_rtx, newreg); 4493 in_rtx->used = 1; 4494 return; 4495 } 4496 4497 if (INSN_P (in_rtx)) 4498 { 4499 /* Inside a SEQUENCE, we find insns. 4500 Renumber just the patterns of these insns, 4501 just as we do for the top-level insns. */ 4502 leaf_renumber_regs_insn (PATTERN (in_rtx)); 4503 return; 4504 } 4505 4506 format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx)); 4507 4508 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++) 4509 switch (*format_ptr++) 4510 { 4511 case 'e': 4512 leaf_renumber_regs_insn (XEXP (in_rtx, i)); 4513 break; 4514 4515 case 'E': 4516 if (NULL != XVEC (in_rtx, i)) 4517 { 4518 for (j = 0; j < XVECLEN (in_rtx, i); j++) 4519 leaf_renumber_regs_insn (XVECEXP (in_rtx, i, j)); 4520 } 4521 break; 4522 4523 case 'S': 4524 case 's': 4525 case '0': 4526 case 'i': 4527 case 'w': 4528 case 'n': 4529 case 'u': 4530 break; 4531 4532 default: 4533 gcc_unreachable (); 4534 } 4535 } 4536 #endif 4537 4538 /* Turn the RTL into assembly. */ 4539 static unsigned int 4540 rest_of_handle_final (void) 4541 { 4542 const char *fnname = get_fnname_from_decl (current_function_decl); 4543 4544 assemble_start_function (current_function_decl, fnname); 4545 final_start_function (get_insns (), asm_out_file, optimize); 4546 final (get_insns (), asm_out_file, optimize); 4547 if (flag_ipa_ra) 4548 collect_fn_hard_reg_usage (); 4549 final_end_function (); 4550 4551 /* The IA-64 ".handlerdata" directive must be issued before the ".endp" 4552 directive that closes the procedure descriptor. Similarly, for x64 SEH. 4553 Otherwise it's not strictly necessary, but it doesn't hurt either. */ 4554 output_function_exception_table (fnname); 4555 4556 assemble_end_function (current_function_decl, fnname); 4557 4558 user_defined_section_attribute = false; 4559 4560 /* Free up reg info memory. */ 4561 free_reg_info (); 4562 4563 if (! quiet_flag) 4564 fflush (asm_out_file); 4565 4566 /* Write DBX symbols if requested. */ 4567 4568 /* Note that for those inline functions where we don't initially 4569 know for certain that we will be generating an out-of-line copy, 4570 the first invocation of this routine (rest_of_compilation) will 4571 skip over this code by doing a `goto exit_rest_of_compilation;'. 4572 Later on, wrapup_global_declarations will (indirectly) call 4573 rest_of_compilation again for those inline functions that need 4574 to have out-of-line copies generated. During that call, we 4575 *will* be routed past here. */ 4576 4577 timevar_push (TV_SYMOUT); 4578 if (!DECL_IGNORED_P (current_function_decl)) 4579 debug_hooks->function_decl (current_function_decl); 4580 timevar_pop (TV_SYMOUT); 4581 4582 /* Release the blocks that are linked to DECL_INITIAL() to free the memory. */ 4583 DECL_INITIAL (current_function_decl) = error_mark_node; 4584 4585 if (DECL_STATIC_CONSTRUCTOR (current_function_decl) 4586 && targetm.have_ctors_dtors) 4587 targetm.asm_out.constructor (XEXP (DECL_RTL (current_function_decl), 0), 4588 decl_init_priority_lookup 4589 (current_function_decl)); 4590 if (DECL_STATIC_DESTRUCTOR (current_function_decl) 4591 && targetm.have_ctors_dtors) 4592 targetm.asm_out.destructor (XEXP (DECL_RTL (current_function_decl), 0), 4593 decl_fini_priority_lookup 4594 (current_function_decl)); 4595 return 0; 4596 } 4597 4598 namespace { 4599 4600 const pass_data pass_data_final = 4601 { 4602 RTL_PASS, /* type */ 4603 "final", /* name */ 4604 OPTGROUP_NONE, /* optinfo_flags */ 4605 TV_FINAL, /* tv_id */ 4606 0, /* properties_required */ 4607 0, /* properties_provided */ 4608 0, /* properties_destroyed */ 4609 0, /* todo_flags_start */ 4610 0, /* todo_flags_finish */ 4611 }; 4612 4613 class pass_final : public rtl_opt_pass 4614 { 4615 public: 4616 pass_final (gcc::context *ctxt) 4617 : rtl_opt_pass (pass_data_final, ctxt) 4618 {} 4619 4620 /* opt_pass methods: */ 4621 virtual unsigned int execute (function *) { return rest_of_handle_final (); } 4622 4623 }; // class pass_final 4624 4625 } // anon namespace 4626 4627 rtl_opt_pass * 4628 make_pass_final (gcc::context *ctxt) 4629 { 4630 return new pass_final (ctxt); 4631 } 4632 4633 4634 static unsigned int 4635 rest_of_handle_shorten_branches (void) 4636 { 4637 /* Shorten branches. */ 4638 shorten_branches (get_insns ()); 4639 return 0; 4640 } 4641 4642 namespace { 4643 4644 const pass_data pass_data_shorten_branches = 4645 { 4646 RTL_PASS, /* type */ 4647 "shorten", /* name */ 4648 OPTGROUP_NONE, /* optinfo_flags */ 4649 TV_SHORTEN_BRANCH, /* tv_id */ 4650 0, /* properties_required */ 4651 0, /* properties_provided */ 4652 0, /* properties_destroyed */ 4653 0, /* todo_flags_start */ 4654 0, /* todo_flags_finish */ 4655 }; 4656 4657 class pass_shorten_branches : public rtl_opt_pass 4658 { 4659 public: 4660 pass_shorten_branches (gcc::context *ctxt) 4661 : rtl_opt_pass (pass_data_shorten_branches, ctxt) 4662 {} 4663 4664 /* opt_pass methods: */ 4665 virtual unsigned int execute (function *) 4666 { 4667 return rest_of_handle_shorten_branches (); 4668 } 4669 4670 }; // class pass_shorten_branches 4671 4672 } // anon namespace 4673 4674 rtl_opt_pass * 4675 make_pass_shorten_branches (gcc::context *ctxt) 4676 { 4677 return new pass_shorten_branches (ctxt); 4678 } 4679 4680 4681 static unsigned int 4682 rest_of_clean_state (void) 4683 { 4684 rtx_insn *insn, *next; 4685 FILE *final_output = NULL; 4686 int save_unnumbered = flag_dump_unnumbered; 4687 int save_noaddr = flag_dump_noaddr; 4688 4689 if (flag_dump_final_insns) 4690 { 4691 final_output = fopen (flag_dump_final_insns, "a"); 4692 if (!final_output) 4693 { 4694 error ("could not open final insn dump file %qs: %m", 4695 flag_dump_final_insns); 4696 flag_dump_final_insns = NULL; 4697 } 4698 else 4699 { 4700 flag_dump_noaddr = flag_dump_unnumbered = 1; 4701 if (flag_compare_debug_opt || flag_compare_debug) 4702 dump_flags |= TDF_NOUID; 4703 dump_function_header (final_output, current_function_decl, 4704 dump_flags); 4705 final_insns_dump_p = true; 4706 4707 for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 4708 if (LABEL_P (insn)) 4709 INSN_UID (insn) = CODE_LABEL_NUMBER (insn); 4710 else 4711 { 4712 if (NOTE_P (insn)) 4713 set_block_for_insn (insn, NULL); 4714 INSN_UID (insn) = 0; 4715 } 4716 } 4717 } 4718 4719 /* It is very important to decompose the RTL instruction chain here: 4720 debug information keeps pointing into CODE_LABEL insns inside the function 4721 body. If these remain pointing to the other insns, we end up preserving 4722 whole RTL chain and attached detailed debug info in memory. */ 4723 for (insn = get_insns (); insn; insn = next) 4724 { 4725 next = NEXT_INSN (insn); 4726 SET_NEXT_INSN (insn) = NULL; 4727 SET_PREV_INSN (insn) = NULL; 4728 4729 if (final_output 4730 && (!NOTE_P (insn) || 4731 (NOTE_KIND (insn) != NOTE_INSN_VAR_LOCATION 4732 && NOTE_KIND (insn) != NOTE_INSN_CALL_ARG_LOCATION 4733 && NOTE_KIND (insn) != NOTE_INSN_BLOCK_BEG 4734 && NOTE_KIND (insn) != NOTE_INSN_BLOCK_END 4735 && NOTE_KIND (insn) != NOTE_INSN_DELETED_DEBUG_LABEL))) 4736 print_rtl_single (final_output, insn); 4737 } 4738 4739 if (final_output) 4740 { 4741 flag_dump_noaddr = save_noaddr; 4742 flag_dump_unnumbered = save_unnumbered; 4743 final_insns_dump_p = false; 4744 4745 if (fclose (final_output)) 4746 { 4747 error ("could not close final insn dump file %qs: %m", 4748 flag_dump_final_insns); 4749 flag_dump_final_insns = NULL; 4750 } 4751 } 4752 4753 /* In case the function was not output, 4754 don't leave any temporary anonymous types 4755 queued up for sdb output. */ 4756 if (SDB_DEBUGGING_INFO && write_symbols == SDB_DEBUG) 4757 sdbout_types (NULL_TREE); 4758 4759 flag_rerun_cse_after_global_opts = 0; 4760 reload_completed = 0; 4761 epilogue_completed = 0; 4762 #ifdef STACK_REGS 4763 regstack_completed = 0; 4764 #endif 4765 4766 /* Clear out the insn_length contents now that they are no 4767 longer valid. */ 4768 init_insn_lengths (); 4769 4770 /* Show no temporary slots allocated. */ 4771 init_temp_slots (); 4772 4773 free_bb_for_insn (); 4774 4775 delete_tree_ssa (cfun); 4776 4777 /* We can reduce stack alignment on call site only when we are sure that 4778 the function body just produced will be actually used in the final 4779 executable. */ 4780 if (decl_binds_to_current_def_p (current_function_decl)) 4781 { 4782 unsigned int pref = crtl->preferred_stack_boundary; 4783 if (crtl->stack_alignment_needed > crtl->preferred_stack_boundary) 4784 pref = crtl->stack_alignment_needed; 4785 cgraph_node::rtl_info (current_function_decl) 4786 ->preferred_incoming_stack_boundary = pref; 4787 } 4788 4789 /* Make sure volatile mem refs aren't considered valid operands for 4790 arithmetic insns. We must call this here if this is a nested inline 4791 function, since the above code leaves us in the init_recog state, 4792 and the function context push/pop code does not save/restore volatile_ok. 4793 4794 ??? Maybe it isn't necessary for expand_start_function to call this 4795 anymore if we do it here? */ 4796 4797 init_recog_no_volatile (); 4798 4799 /* We're done with this function. Free up memory if we can. */ 4800 free_after_parsing (cfun); 4801 free_after_compilation (cfun); 4802 return 0; 4803 } 4804 4805 namespace { 4806 4807 const pass_data pass_data_clean_state = 4808 { 4809 RTL_PASS, /* type */ 4810 "*clean_state", /* name */ 4811 OPTGROUP_NONE, /* optinfo_flags */ 4812 TV_FINAL, /* tv_id */ 4813 0, /* properties_required */ 4814 0, /* properties_provided */ 4815 PROP_rtl, /* properties_destroyed */ 4816 0, /* todo_flags_start */ 4817 0, /* todo_flags_finish */ 4818 }; 4819 4820 class pass_clean_state : public rtl_opt_pass 4821 { 4822 public: 4823 pass_clean_state (gcc::context *ctxt) 4824 : rtl_opt_pass (pass_data_clean_state, ctxt) 4825 {} 4826 4827 /* opt_pass methods: */ 4828 virtual unsigned int execute (function *) 4829 { 4830 return rest_of_clean_state (); 4831 } 4832 4833 }; // class pass_clean_state 4834 4835 } // anon namespace 4836 4837 rtl_opt_pass * 4838 make_pass_clean_state (gcc::context *ctxt) 4839 { 4840 return new pass_clean_state (ctxt); 4841 } 4842 4843 /* Return true if INSN is a call to the current function. */ 4844 4845 static bool 4846 self_recursive_call_p (rtx_insn *insn) 4847 { 4848 tree fndecl = get_call_fndecl (insn); 4849 return (fndecl == current_function_decl 4850 && decl_binds_to_current_def_p (fndecl)); 4851 } 4852 4853 /* Collect hard register usage for the current function. */ 4854 4855 static void 4856 collect_fn_hard_reg_usage (void) 4857 { 4858 rtx_insn *insn; 4859 #ifdef STACK_REGS 4860 int i; 4861 #endif 4862 struct cgraph_rtl_info *node; 4863 HARD_REG_SET function_used_regs; 4864 4865 /* ??? To be removed when all the ports have been fixed. */ 4866 if (!targetm.call_fusage_contains_non_callee_clobbers) 4867 return; 4868 4869 CLEAR_HARD_REG_SET (function_used_regs); 4870 4871 for (insn = get_insns (); insn != NULL_RTX; insn = next_insn (insn)) 4872 { 4873 HARD_REG_SET insn_used_regs; 4874 4875 if (!NONDEBUG_INSN_P (insn)) 4876 continue; 4877 4878 if (CALL_P (insn) 4879 && !self_recursive_call_p (insn)) 4880 { 4881 if (!get_call_reg_set_usage (insn, &insn_used_regs, 4882 call_used_reg_set)) 4883 return; 4884 4885 IOR_HARD_REG_SET (function_used_regs, insn_used_regs); 4886 } 4887 4888 find_all_hard_reg_sets (insn, &insn_used_regs, false); 4889 IOR_HARD_REG_SET (function_used_regs, insn_used_regs); 4890 } 4891 4892 /* Be conservative - mark fixed and global registers as used. */ 4893 IOR_HARD_REG_SET (function_used_regs, fixed_reg_set); 4894 4895 #ifdef STACK_REGS 4896 /* Handle STACK_REGS conservatively, since the df-framework does not 4897 provide accurate information for them. */ 4898 4899 for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++) 4900 SET_HARD_REG_BIT (function_used_regs, i); 4901 #endif 4902 4903 /* The information we have gathered is only interesting if it exposes a 4904 register from the call_used_regs that is not used in this function. */ 4905 if (hard_reg_set_subset_p (call_used_reg_set, function_used_regs)) 4906 return; 4907 4908 node = cgraph_node::rtl_info (current_function_decl); 4909 gcc_assert (node != NULL); 4910 4911 COPY_HARD_REG_SET (node->function_used_regs, function_used_regs); 4912 node->function_used_regs_valid = 1; 4913 } 4914 4915 /* Get the declaration of the function called by INSN. */ 4916 4917 static tree 4918 get_call_fndecl (rtx_insn *insn) 4919 { 4920 rtx note, datum; 4921 4922 note = find_reg_note (insn, REG_CALL_DECL, NULL_RTX); 4923 if (note == NULL_RTX) 4924 return NULL_TREE; 4925 4926 datum = XEXP (note, 0); 4927 if (datum != NULL_RTX) 4928 return SYMBOL_REF_DECL (datum); 4929 4930 return NULL_TREE; 4931 } 4932 4933 /* Return the cgraph_rtl_info of the function called by INSN. Returns NULL for 4934 call targets that can be overwritten. */ 4935 4936 static struct cgraph_rtl_info * 4937 get_call_cgraph_rtl_info (rtx_insn *insn) 4938 { 4939 tree fndecl; 4940 4941 if (insn == NULL_RTX) 4942 return NULL; 4943 4944 fndecl = get_call_fndecl (insn); 4945 if (fndecl == NULL_TREE 4946 || !decl_binds_to_current_def_p (fndecl)) 4947 return NULL; 4948 4949 return cgraph_node::rtl_info (fndecl); 4950 } 4951 4952 /* Find hard registers used by function call instruction INSN, and return them 4953 in REG_SET. Return DEFAULT_SET in REG_SET if not found. */ 4954 4955 bool 4956 get_call_reg_set_usage (rtx_insn *insn, HARD_REG_SET *reg_set, 4957 HARD_REG_SET default_set) 4958 { 4959 if (flag_ipa_ra) 4960 { 4961 struct cgraph_rtl_info *node = get_call_cgraph_rtl_info (insn); 4962 if (node != NULL 4963 && node->function_used_regs_valid) 4964 { 4965 COPY_HARD_REG_SET (*reg_set, node->function_used_regs); 4966 AND_HARD_REG_SET (*reg_set, default_set); 4967 return true; 4968 } 4969 } 4970 4971 COPY_HARD_REG_SET (*reg_set, default_set); 4972 return false; 4973 } 4974