comparison gcc/final.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 /* Convert RTL to assembler code and output it, for GNU compiler. 1 /* Convert RTL to assembler code and output it, for GNU compiler.
2 Copyright (C) 1987-2018 Free Software Foundation, Inc. 2 Copyright (C) 1987-2020 Free Software Foundation, Inc.
3 3
4 This file is part of GCC. 4 This file is part of GCC.
5 5
6 GCC is free software; you can redistribute it and/or modify it under 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 7 the terms of the GNU General Public License as published by the Free
73 #include "cfgrtl.h" 73 #include "cfgrtl.h"
74 #include "debug.h" 74 #include "debug.h"
75 #include "tree-pass.h" 75 #include "tree-pass.h"
76 #include "tree-ssa.h" 76 #include "tree-ssa.h"
77 #include "cfgloop.h" 77 #include "cfgloop.h"
78 #include "params.h"
79 #include "stringpool.h" 78 #include "stringpool.h"
80 #include "attribs.h" 79 #include "attribs.h"
81 #include "asan.h" 80 #include "asan.h"
82 #include "rtl-iter.h" 81 #include "rtl-iter.h"
83 #include "print-rtl.h" 82 #include "print-rtl.h"
83 #include "function-abi.h"
84 84
85 #ifdef XCOFF_DEBUGGING_INFO 85 #ifdef XCOFF_DEBUGGING_INFO
86 #include "xcoffout.h" /* Needed for external data declarations. */ 86 #include "xcoffout.h" /* Needed for external data declarations. */
87 #endif 87 #endif
88 88
126 static int last_discriminator; 126 static int last_discriminator;
127 127
128 /* Discriminator to be written to assembly for current instruction. 128 /* Discriminator to be written to assembly for current instruction.
129 Note: actual usage depends on loc_discriminator_kind setting. */ 129 Note: actual usage depends on loc_discriminator_kind setting. */
130 static int discriminator; 130 static int discriminator;
131 static inline int compute_discriminator (location_t loc);
131 132
132 /* Discriminator identifying current basic block among others sharing 133 /* Discriminator identifying current basic block among others sharing
133 the same locus. */ 134 the same locus. */
134 static int bb_discriminator; 135 static int bb_discriminator;
135 136
147 148
148 /* Override filename, line and column number. */ 149 /* Override filename, line and column number. */
149 static const char *override_filename; 150 static const char *override_filename;
150 static int override_linenum; 151 static int override_linenum;
151 static int override_columnnum; 152 static int override_columnnum;
153 static int override_discriminator;
152 154
153 /* Whether to force emission of a line note before the next insn. */ 155 /* Whether to force emission of a line note before the next insn. */
154 static bool force_source_line = false; 156 static bool force_source_line = false;
155 157
156 extern const int length_unit_log; /* This is defined in insn-attrtab.c. */ 158 extern const int length_unit_log; /* This is defined in insn-attrtab.c. */
226 #if HAVE_cc0 228 #if HAVE_cc0
227 static int alter_cond (rtx); 229 static int alter_cond (rtx);
228 #endif 230 #endif
229 static int align_fuzz (rtx, rtx, int, unsigned); 231 static int align_fuzz (rtx, rtx, int, unsigned);
230 static void collect_fn_hard_reg_usage (void); 232 static void collect_fn_hard_reg_usage (void);
231 static tree get_call_fndecl (rtx_insn *);
232 233
233 /* Initialize data in final at the beginning of a compilation. */ 234 /* Initialize data in final at the beginning of a compilation. */
234 235
235 void 236 void
236 init_final (const char *filename ATTRIBUTE_UNUSED) 237 init_final (const char *filename ATTRIBUTE_UNUSED)
602 if (! INSN_ADDRESSES_SET_P ()) 603 if (! INSN_ADDRESSES_SET_P ())
603 return 0; 604 return 0;
604 605
605 rtx_insn *seq = NEXT_INSN (PREV_INSN (branch)); 606 rtx_insn *seq = NEXT_INSN (PREV_INSN (branch));
606 seq_uid = INSN_UID (seq); 607 seq_uid = INSN_UID (seq);
607 if (!JUMP_P (branch)) 608 if (!jump_to_label_p (branch))
608 /* This can happen for example on the PA; the objective is to know the 609 /* This can happen for example on the PA; the objective is to know the
609 offset to address something in front of the start of the function. 610 offset to address something in front of the start of the function.
610 Thus, we can treat it like a backward branch. 611 Thus, we can treat it like a backward branch.
611 We assume here that FUNCTION_BOUNDARY / BITS_PER_UNIT is larger than 612 We assume here that FUNCTION_BOUNDARY / BITS_PER_UNIT is larger than
612 any alignment we'd encounter, so we skip the call to align_fuzz. */ 613 any alignment we'd encounter, so we skip the call to align_fuzz. */
653 dump_flow_info (dump_file, TDF_DETAILS); 654 dump_flow_info (dump_file, TDF_DETAILS);
654 flow_loops_dump (dump_file, NULL, 1); 655 flow_loops_dump (dump_file, NULL, 1);
655 } 656 }
656 loop_optimizer_init (AVOID_CFG_MODIFICATIONS); 657 loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
657 profile_count count_threshold = cfun->cfg->count_max.apply_scale 658 profile_count count_threshold = cfun->cfg->count_max.apply_scale
658 (1, PARAM_VALUE (PARAM_ALIGN_THRESHOLD)); 659 (1, param_align_threshold);
659 660
660 if (dump_file) 661 if (dump_file)
661 { 662 {
662 fprintf (dump_file, "count_max: "); 663 fprintf (dump_file, "count_max: ");
663 cfun->cfg->count_max.dump (dump_file); 664 cfun->cfg->count_max.dump (dump_file);
739 && single_succ (bb) == EXIT_BLOCK_PTR_FOR_FN (cfun)) 740 && single_succ (bb) == EXIT_BLOCK_PTR_FOR_FN (cfun))
740 && optimize_bb_for_speed_p (bb) 741 && optimize_bb_for_speed_p (bb)
741 && branch_count + fallthru_count > count_threshold 742 && branch_count + fallthru_count > count_threshold
742 && (branch_count 743 && (branch_count
743 > fallthru_count.apply_scale 744 > fallthru_count.apply_scale
744 (PARAM_VALUE (PARAM_ALIGN_LOOP_ITERATIONS), 1))) 745 (param_align_loop_iterations, 1)))
745 { 746 {
746 align_flags alignment = LOOP_ALIGN (label); 747 align_flags alignment = LOOP_ALIGN (label);
747 if (dump_file) 748 if (dump_file)
748 fprintf (dump_file, " internal loop alignment added.\n"); 749 fprintf (dump_file, " internal loop alignment added.\n");
749 max_alignment = align_flags::max (max_alignment, alignment); 750 max_alignment = align_flags::max (max_alignment, alignment);
2340 if (locus_ptr != NULL) 2341 if (locus_ptr != NULL)
2341 { 2342 {
2342 override_filename = LOCATION_FILE (*locus_ptr); 2343 override_filename = LOCATION_FILE (*locus_ptr);
2343 override_linenum = LOCATION_LINE (*locus_ptr); 2344 override_linenum = LOCATION_LINE (*locus_ptr);
2344 override_columnnum = LOCATION_COLUMN (*locus_ptr); 2345 override_columnnum = LOCATION_COLUMN (*locus_ptr);
2346 override_discriminator = compute_discriminator (*locus_ptr);
2345 } 2347 }
2346 } 2348 }
2347 break; 2349 break;
2348 2350
2349 case NOTE_INSN_BLOCK_END: 2351 case NOTE_INSN_BLOCK_END:
2377 if (locus_ptr != NULL) 2379 if (locus_ptr != NULL)
2378 { 2380 {
2379 override_filename = LOCATION_FILE (*locus_ptr); 2381 override_filename = LOCATION_FILE (*locus_ptr);
2380 override_linenum = LOCATION_LINE (*locus_ptr); 2382 override_linenum = LOCATION_LINE (*locus_ptr);
2381 override_columnnum = LOCATION_COLUMN (*locus_ptr); 2383 override_columnnum = LOCATION_COLUMN (*locus_ptr);
2384 override_discriminator = compute_discriminator (*locus_ptr);
2382 } 2385 }
2383 else 2386 else
2384 { 2387 {
2385 override_filename = NULL; 2388 override_filename = NULL;
2386 override_linenum = 0; 2389 override_linenum = 0;
2387 override_columnnum = 0; 2390 override_columnnum = 0;
2391 override_discriminator = 0;
2388 } 2392 }
2389 } 2393 }
2390 break; 2394 break;
2391 2395
2392 case NOTE_INSN_DELETED_LABEL: 2396 case NOTE_INSN_DELETED_LABEL:
2423 } 2427 }
2424 break; 2428 break;
2425 2429
2426 case NOTE_INSN_INLINE_ENTRY: 2430 case NOTE_INSN_INLINE_ENTRY:
2427 gcc_checking_assert (cfun->debug_nonbind_markers); 2431 gcc_checking_assert (cfun->debug_nonbind_markers);
2428 if (!DECL_IGNORED_P (current_function_decl)) 2432 if (!DECL_IGNORED_P (current_function_decl)
2433 && notice_source_line (insn, NULL))
2429 { 2434 {
2430 if (!notice_source_line (insn, NULL))
2431 break;
2432 (*debug_hooks->inline_entry) (LOCATION_BLOCK 2435 (*debug_hooks->inline_entry) (LOCATION_BLOCK
2433 (NOTE_MARKER_LOCATION (insn))); 2436 (NOTE_MARKER_LOCATION (insn)));
2434 goto output_source_line; 2437 goto output_source_line;
2435 } 2438 }
2436 break; 2439 break;
3183 return *inst; 3186 return *inst;
3184 } 3187 }
3185 3188
3186 /* Set DISCRIMINATOR to the appropriate value, possibly derived from LOC. */ 3189 /* Set DISCRIMINATOR to the appropriate value, possibly derived from LOC. */
3187 3190
3188 static inline void 3191 static inline int
3189 maybe_set_discriminator (location_t loc) 3192 compute_discriminator (location_t loc)
3190 { 3193 {
3194 int discriminator;
3195
3191 if (!decl_to_instance_map) 3196 if (!decl_to_instance_map)
3192 discriminator = bb_discriminator; 3197 discriminator = bb_discriminator;
3193 else 3198 else
3194 { 3199 {
3195 tree block = LOCATION_BLOCK (loc); 3200 tree block = LOCATION_BLOCK (loc);
3207 else 3212 else
3208 decl = block_ultimate_origin (block); 3213 decl = block_ultimate_origin (block);
3209 3214
3210 discriminator = map_decl_to_instance (decl); 3215 discriminator = map_decl_to_instance (decl);
3211 } 3216 }
3217
3218 return discriminator;
3212 } 3219 }
3213 3220
3214 /* Return whether a source line note needs to be emitted before INSN. 3221 /* Return whether a source line note needs to be emitted before INSN.
3215 Sets IS_STMT to TRUE if the line should be marked as a possible 3222 Sets IS_STMT to TRUE if the line should be marked as a possible
3216 breakpoint location. */ 3223 breakpoint location. */
3232 return false; 3239 return false;
3233 } 3240 }
3234 filename = xloc.file; 3241 filename = xloc.file;
3235 linenum = xloc.line; 3242 linenum = xloc.line;
3236 columnnum = xloc.column; 3243 columnnum = xloc.column;
3237 maybe_set_discriminator (loc); 3244 discriminator = compute_discriminator (loc);
3238 force_source_line = true; 3245 force_source_line = true;
3239 } 3246 }
3240 else if (override_filename) 3247 else if (override_filename)
3241 { 3248 {
3242 filename = override_filename; 3249 filename = override_filename;
3243 linenum = override_linenum; 3250 linenum = override_linenum;
3244 columnnum = override_columnnum; 3251 columnnum = override_columnnum;
3252 discriminator = override_discriminator;
3245 } 3253 }
3246 else if (INSN_HAS_LOCATION (insn)) 3254 else if (INSN_HAS_LOCATION (insn))
3247 { 3255 {
3248 expanded_location xloc = insn_location (insn); 3256 expanded_location xloc = insn_location (insn);
3249 filename = xloc.file; 3257 filename = xloc.file;
3250 linenum = xloc.line; 3258 linenum = xloc.line;
3251 columnnum = xloc.column; 3259 columnnum = xloc.column;
3252 maybe_set_discriminator (INSN_LOCATION (insn)); 3260 discriminator = compute_discriminator (INSN_LOCATION (insn));
3253 } 3261 }
3254 else 3262 else
3255 { 3263 {
3256 filename = NULL; 3264 filename = NULL;
3257 linenum = 0; 3265 linenum = 0;
3258 columnnum = 0; 3266 columnnum = 0;
3267 discriminator = 0;
3259 } 3268 }
3260 3269
3261 if (filename == NULL) 3270 if (filename == NULL)
3262 return false; 3271 return false;
3263 3272
4646 rtx_insn *first = get_insns (); 4655 rtx_insn *first = get_insns ();
4647 int seen = 0; 4656 int seen = 0;
4648 final_start_function_1 (&first, asm_out_file, &seen, optimize); 4657 final_start_function_1 (&first, asm_out_file, &seen, optimize);
4649 final_1 (first, asm_out_file, seen, optimize); 4658 final_1 (first, asm_out_file, seen, optimize);
4650 if (flag_ipa_ra 4659 if (flag_ipa_ra
4651 && !lookup_attribute ("noipa", DECL_ATTRIBUTES (current_function_decl))) 4660 && !lookup_attribute ("noipa", DECL_ATTRIBUTES (current_function_decl))
4661 /* Functions with naked attributes are supported only with basic asm
4662 statements in the body, thus for supported use cases the information
4663 on clobbered registers is not available. */
4664 && !lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)))
4652 collect_fn_hard_reg_usage (); 4665 collect_fn_hard_reg_usage ();
4653 final_end_function (); 4666 final_end_function ();
4654 4667
4655 /* The IA-64 ".handlerdata" directive must be issued before the ".endp" 4668 /* The IA-64 ".handlerdata" directive must be issued before the ".endp"
4656 directive that closes the procedure descriptor. Similarly, for x64 SEH. 4669 directive that closes the procedure descriptor. Similarly, for x64 SEH.
4888 delete_tree_ssa (cfun); 4901 delete_tree_ssa (cfun);
4889 4902
4890 /* We can reduce stack alignment on call site only when we are sure that 4903 /* We can reduce stack alignment on call site only when we are sure that
4891 the function body just produced will be actually used in the final 4904 the function body just produced will be actually used in the final
4892 executable. */ 4905 executable. */
4893 if (decl_binds_to_current_def_p (current_function_decl)) 4906 if (flag_ipa_stack_alignment
4907 && decl_binds_to_current_def_p (current_function_decl))
4894 { 4908 {
4895 unsigned int pref = crtl->preferred_stack_boundary; 4909 unsigned int pref = crtl->preferred_stack_boundary;
4896 if (crtl->stack_alignment_needed > crtl->preferred_stack_boundary) 4910 if (crtl->stack_alignment_needed > crtl->preferred_stack_boundary)
4897 pref = crtl->stack_alignment_needed; 4911 pref = crtl->stack_alignment_needed;
4898 cgraph_node::rtl_info (current_function_decl) 4912 cgraph_node::rtl_info (current_function_decl)
4977 4991
4978 /* ??? To be removed when all the ports have been fixed. */ 4992 /* ??? To be removed when all the ports have been fixed. */
4979 if (!targetm.call_fusage_contains_non_callee_clobbers) 4993 if (!targetm.call_fusage_contains_non_callee_clobbers)
4980 return; 4994 return;
4981 4995
4982 CLEAR_HARD_REG_SET (function_used_regs);
4983
4984 for (insn = get_insns (); insn != NULL_RTX; insn = next_insn (insn))
4985 {
4986 HARD_REG_SET insn_used_regs;
4987
4988 if (!NONDEBUG_INSN_P (insn))
4989 continue;
4990
4991 if (CALL_P (insn)
4992 && !self_recursive_call_p (insn))
4993 {
4994 if (!get_call_reg_set_usage (insn, &insn_used_regs,
4995 call_used_reg_set))
4996 return;
4997
4998 IOR_HARD_REG_SET (function_used_regs, insn_used_regs);
4999 }
5000
5001 find_all_hard_reg_sets (insn, &insn_used_regs, false);
5002 IOR_HARD_REG_SET (function_used_regs, insn_used_regs);
5003 }
5004
5005 /* Be conservative - mark fixed and global registers as used. */ 4996 /* Be conservative - mark fixed and global registers as used. */
5006 IOR_HARD_REG_SET (function_used_regs, fixed_reg_set); 4997 function_used_regs = fixed_reg_set;
5007 4998
5008 #ifdef STACK_REGS 4999 #ifdef STACK_REGS
5009 /* Handle STACK_REGS conservatively, since the df-framework does not 5000 /* Handle STACK_REGS conservatively, since the df-framework does not
5010 provide accurate information for them. */ 5001 provide accurate information for them. */
5011 5002
5012 for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++) 5003 for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
5013 SET_HARD_REG_BIT (function_used_regs, i); 5004 SET_HARD_REG_BIT (function_used_regs, i);
5014 #endif 5005 #endif
5015 5006
5016 /* The information we have gathered is only interesting if it exposes a 5007 for (insn = get_insns (); insn != NULL_RTX; insn = next_insn (insn))
5017 register from the call_used_regs that is not used in this function. */ 5008 {
5018 if (hard_reg_set_subset_p (call_used_reg_set, function_used_regs)) 5009 HARD_REG_SET insn_used_regs;
5019 return; 5010
5011 if (!NONDEBUG_INSN_P (insn))
5012 continue;
5013
5014 if (CALL_P (insn)
5015 && !self_recursive_call_p (insn))
5016 function_used_regs
5017 |= insn_callee_abi (insn).full_and_partial_reg_clobbers ();
5018
5019 find_all_hard_reg_sets (insn, &insn_used_regs, false);
5020 function_used_regs |= insn_used_regs;
5021
5022 if (hard_reg_set_subset_p (crtl->abi->full_and_partial_reg_clobbers (),
5023 function_used_regs))
5024 return;
5025 }
5026
5027 /* Mask out fully-saved registers, so that they don't affect equality
5028 comparisons between function_abis. */
5029 function_used_regs &= crtl->abi->full_and_partial_reg_clobbers ();
5020 5030
5021 node = cgraph_node::rtl_info (current_function_decl); 5031 node = cgraph_node::rtl_info (current_function_decl);
5022 gcc_assert (node != NULL); 5032 gcc_assert (node != NULL);
5023 5033
5024 COPY_HARD_REG_SET (node->function_used_regs, function_used_regs); 5034 node->function_used_regs = function_used_regs;
5025 node->function_used_regs_valid = 1; 5035 }
5026 }
5027
5028 /* Get the declaration of the function called by INSN. */
5029
5030 static tree
5031 get_call_fndecl (rtx_insn *insn)
5032 {
5033 rtx note, datum;
5034
5035 note = find_reg_note (insn, REG_CALL_DECL, NULL_RTX);
5036 if (note == NULL_RTX)
5037 return NULL_TREE;
5038
5039 datum = XEXP (note, 0);
5040 if (datum != NULL_RTX)
5041 return SYMBOL_REF_DECL (datum);
5042
5043 return NULL_TREE;
5044 }
5045
5046 /* Return the cgraph_rtl_info of the function called by INSN. Returns NULL for
5047 call targets that can be overwritten. */
5048
5049 static struct cgraph_rtl_info *
5050 get_call_cgraph_rtl_info (rtx_insn *insn)
5051 {
5052 tree fndecl;
5053
5054 if (insn == NULL_RTX)
5055 return NULL;
5056
5057 fndecl = get_call_fndecl (insn);
5058 if (fndecl == NULL_TREE
5059 || !decl_binds_to_current_def_p (fndecl))
5060 return NULL;
5061
5062 return cgraph_node::rtl_info (fndecl);
5063 }
5064
5065 /* Find hard registers used by function call instruction INSN, and return them
5066 in REG_SET. Return DEFAULT_SET in REG_SET if not found. */
5067
5068 bool
5069 get_call_reg_set_usage (rtx_insn *insn, HARD_REG_SET *reg_set,
5070 HARD_REG_SET default_set)
5071 {
5072 if (flag_ipa_ra)
5073 {
5074 struct cgraph_rtl_info *node = get_call_cgraph_rtl_info (insn);
5075 if (node != NULL
5076 && node->function_used_regs_valid)
5077 {
5078 COPY_HARD_REG_SET (*reg_set, node->function_used_regs);
5079 AND_HARD_REG_SET (*reg_set, default_set);
5080 return true;
5081 }
5082 }
5083
5084 COPY_HARD_REG_SET (*reg_set, default_set);
5085 return false;
5086 }