/* Compute maximum UID and allocate label_align / uid_shuid. */
max_uid = get_max_uid ();
+ /* Free uid_shuid before reallocating it. */
+ free (uid_shuid);
+
uid_shuid = xmalloc (max_uid * sizeof *uid_shuid);
if (max_labelno != max_label_num ())
}
/* First output the function prologue: code to set up the stack frame. */
- (*targetm.asm_out.function_prologue) (file, get_frame_size ());
+ targetm.asm_out.function_prologue (file, get_frame_size ());
/* If the machine represents the prologue as RTL, the profiling code must
be emitted when NOTE_INSN_PROLOGUE_END is scanned. */
int sval = current_function_returns_struct;
rtx svrtx = targetm.calls.struct_value_rtx (TREE_TYPE (current_function_decl), 1);
#if defined(STATIC_CHAIN_INCOMING_REGNUM) || defined(STATIC_CHAIN_REGNUM)
- int cxt = current_function_needs_context;
+ int cxt = cfun->static_chain_decl != NULL;
#endif
#endif /* ASM_OUTPUT_REG_PUSH */
int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
data_section ();
ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
- (*targetm.asm_out.internal_label) (file, "LP", current_function_funcdef_no);
+ targetm.asm_out.internal_label (file, "LP", current_function_funcdef_no);
assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
}
function_section (current_function_decl);
#if defined(ASM_OUTPUT_REG_PUSH)
- if (sval && svrtx != NULL_RTX && GET_CODE (svrtx) == REG)
+ if (sval && svrtx != NULL_RTX && REG_P (svrtx))
ASM_OUTPUT_REG_PUSH (file, REGNO (svrtx));
#endif
#endif
#if defined(ASM_OUTPUT_REG_PUSH)
- if (sval && svrtx != NULL_RTX && GET_CODE (svrtx) == REG)
+ if (sval && svrtx != NULL_RTX && REG_P (svrtx))
ASM_OUTPUT_REG_POP (file, REGNO (svrtx));
#endif
}
/* Finally, output the function epilogue:
code to restore the stack frame and return to the caller. */
- (*targetm.asm_out.function_epilogue) (asm_out_file, get_frame_size ());
+ targetm.asm_out.function_epilogue (asm_out_file, get_frame_size ());
/* And debug output. */
(*debug_hooks->end_epilogue) (last_linenum, last_filename);
for (insn = first; insn; insn = NEXT_INSN (insn))
if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
{
- if ((RTX_INTEGRATED_P (insn)
- && strcmp (NOTE_SOURCE_FILE (insn), main_input_filename) != 0)
- || (last != 0
- && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last)
- && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last)))
+ if (last != 0
+#ifdef USE_MAPPED_LOCATION
+ && NOTE_SOURCE_LOCATION (insn) == NOTE_SOURCE_LOCATION (last)
+#else
+ && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last)
+ && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last)
+#endif
+ )
{
delete_insn (insn); /* Use delete_note. */
continue;
ASM_WEAKEN_LABEL (file, name);
#endif
case LABEL_GLOBAL_ENTRY:
- (*targetm.asm_out.globalize_label) (file, name);
+ targetm.asm_out.globalize_label (file, name);
case LABEL_STATIC_ENTRY:
#ifdef ASM_OUTPUT_TYPE_DIRECTIVE
ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
}
}
+/* Return boolean indicating if there is a NOTE_INSN_UNLIKELY_EXECUTED_CODE
+ note in the instruction chain (going forward) between the current
+ instruction, and the next 'executable' instruction. */
+
+bool
+scan_ahead_for_unlikely_executed_note (rtx insn)
+{
+ rtx temp;
+ int bb_note_count = 0;
+
+ for (temp = insn; temp; temp = NEXT_INSN (temp))
+ {
+ if (GET_CODE (temp) == NOTE
+ && NOTE_LINE_NUMBER (temp) == NOTE_INSN_UNLIKELY_EXECUTED_CODE)
+ return true;
+ if (GET_CODE (temp) == NOTE
+ && NOTE_LINE_NUMBER (temp) == NOTE_INSN_BASIC_BLOCK)
+ {
+ bb_note_count++;
+ if (bb_note_count > 1)
+ return false;
+ }
+ if (INSN_P (temp))
+ return false;
+ }
+
+ return false;
+}
+
/* The final scan for one insn, INSN.
Args are same as in `final', except that INSN
is the insn being scanned.
case NOTE_INSN_EXPECTED_VALUE:
break;
+ case NOTE_INSN_UNLIKELY_EXECUTED_CODE:
+
+ /* The presence of this note indicates that this basic block
+ belongs in the "cold" section of the .o file. If we are
+ not already writing to the cold section we need to change
+ to it. */
+
+ unlikely_text_section ();
+ break;
+
case NOTE_INSN_BASIC_BLOCK:
+
+ /* If we are performing the optimization that partitions
+ basic blocks into hot & cold sections of the .o file,
+ then at the start of each new basic block, before
+ beginning to write code for the basic block, we need to
+ check to see whether the basic block belongs in the hot
+ or cold section of the .o file, and change the section we
+ are writing to appropriately. */
+
+ if (flag_reorder_blocks_and_partition
+ && in_unlikely_text_section()
+ && !scan_ahead_for_unlikely_executed_note (insn))
+ text_section ();
+
#ifdef IA64_UNWIND_INFO
IA64_UNWIND_EMIT (asm_out_file, insn);
#endif
break;
case NOTE_INSN_PROLOGUE_END:
- (*targetm.asm_out.function_end_prologue) (file);
+ targetm.asm_out.function_end_prologue (file);
profile_after_prologue (file);
if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE)
break;
case NOTE_INSN_EPILOGUE_BEG:
- (*targetm.asm_out.function_begin_epilogue) (file);
+ targetm.asm_out.function_begin_epilogue (file);
break;
case NOTE_INSN_FUNCTION_BEG:
if (LABEL_NAME (insn))
(*debug_hooks->label) (insn);
+ /* If we are doing the optimization that partitions hot & cold
+ basic blocks into separate sections of the .o file, we need
+ to ensure the jump table ends up in the correct section... */
+
+ if (flag_reorder_blocks_and_partition)
+ {
+ rtx tmp_table, tmp_label;
+ if (GET_CODE (insn) == CODE_LABEL
+ && tablejump_p (NEXT_INSN (insn), &tmp_label, &tmp_table))
+ {
+ /* Do nothing; Do NOT change the current section. */
+ }
+ else if (scan_ahead_for_unlikely_executed_note (insn))
+ unlikely_text_section ();
+ else
+ {
+ if (in_unlikely_text_section ())
+ text_section ();
+ }
+ }
+
if (app_on)
{
fputs (ASM_APP_OFF, file);
ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
NEXT_INSN (insn));
#else
- (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (insn));
+ targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
#endif
#endif
break;
if (LABEL_ALT_ENTRY_P (insn))
output_alternate_entry_point (file, insn);
else
- (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (insn));
+ targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
break;
default:
if (final_sequence == 0
&& prescan >= 0
&& GET_CODE (insn) == INSN && GET_CODE (body) == SET
- && GET_CODE (SET_SRC (body)) == REG
- && GET_CODE (SET_DEST (body)) == REG
+ && REG_P (SET_SRC (body))
+ && REG_P (SET_DEST (body))
&& REGNO (SET_SRC (body)) == REGNO (SET_DEST (body)))
break;
#endif
&& GET_CODE (body) == SET
&& SET_DEST (body) == pc_rtx
&& GET_CODE (SET_SRC (body)) == IF_THEN_ELSE
- && GET_RTX_CLASS (GET_CODE (XEXP (SET_SRC (body), 0))) == '<'
+ && COMPARISON_P (XEXP (SET_SRC (body), 0))
&& XEXP (XEXP (SET_SRC (body), 0), 0) == cc0_rtx
/* This is done during prescan; it is not done again
in final scan when prescan has been done. */
recog_data.operand[i] = alter_subreg (recog_data.operand_loc[i]);
else if (GET_CODE (recog_data.operand[i]) == PLUS
|| GET_CODE (recog_data.operand[i]) == MULT
- || GET_CODE (recog_data.operand[i]) == MEM)
+ || MEM_P (recog_data.operand[i]))
recog_data.operand[i] = walk_alter_subreg (recog_data.operand_loc[i]);
}
*recog_data.dup_loc[i] = alter_subreg (recog_data.dup_loc[i]);
else if (GET_CODE (*recog_data.dup_loc[i]) == PLUS
|| GET_CODE (*recog_data.dup_loc[i]) == MULT
- || GET_CODE (*recog_data.dup_loc[i]) == MEM)
+ || MEM_P (*recog_data.dup_loc[i]))
*recog_data.dup_loc[i] = walk_alter_subreg (recog_data.dup_loc[i]);
}
}
/* simplify_subreg does not remove subreg from volatile references.
We are required to. */
- if (GET_CODE (y) == MEM)
+ if (MEM_P (y))
*xp = adjust_address (y, GET_MODE (x), SUBREG_BYTE (x));
else
{
if (new != 0)
*xp = new;
/* Simplify_subreg can't handle some REG cases, but we have to. */
- else if (GET_CODE (y) == REG)
+ else if (REG_P (y))
{
unsigned int regno = subreg_hard_regno (x, 1);
*xp = gen_rtx_REG_offset (y, GET_MODE (x), regno, SUBREG_BYTE (x));
*paddressp = 0;
- if (GET_CODE (op) == REG)
+ if (REG_P (op))
return REG_EXPR (op);
- else if (GET_CODE (op) != MEM)
+ else if (!MEM_P (op))
return 0;
if (MEM_EXPR (op) != 0)
&& (expr = get_mem_expr_from_op (XEXP (op, 1), &inner_addressp)))
return expr;
- while (GET_RTX_CLASS (GET_CODE (op)) == '1'
- || GET_RTX_CLASS (GET_CODE (op)) == '2')
+ while (GET_RTX_CLASS (GET_CODE (op)) == RTX_UNARY
+ || GET_RTX_CLASS (GET_CODE (op)) == RTX_BIN_ARITH)
op = XEXP (op, 0);
expr = get_mem_expr_from_op (op, &inner_addressp);
/* If X is a pseudo-register, abort now rather than writing trash to the
assembler file. */
- if (x && GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
+ if (x && REG_P (x) && REGNO (x) >= FIRST_PSEUDO_REGISTER)
abort ();
PRINT_OPERAND (asm_out_file, x, code);
break;
case SYMBOL_REF:
+ if (SYMBOL_REF_DECL (x))
+ mark_decl_referenced (SYMBOL_REF_DECL (x));
#ifdef ASM_OUTPUT_SYMBOL_REF
ASM_OUTPUT_SYMBOL_REF (file, x);
#else
if (current_function_uses_pic_offset_table
&& pic_offset_table_rtx != 0
- && GET_CODE (pic_offset_table_rtx) == REG
+ && REG_P (pic_offset_table_rtx)
&& ! permitted_reg_in_leaf_functions[REGNO (pic_offset_table_rtx)])
return 0;
renumbered_regs would be 1 for an output-register;
they */
- if (GET_CODE (in_rtx) == REG)
+ if (REG_P (in_rtx))
{
int newreg;