tree last = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
/* For functions marked as inline increase the maximum size to
- MAX_INLINE_INSNS (-finline-limit-<n>). For regular functions
- use the limit given by INTEGRATE_THRESHOLD. */
+ MAX_INLINE_INSNS_RTL (--param max-inline-insn-rtl=<n>). For
+ regular functions use the limit given by INTEGRATE_THRESHOLD.
+ Note that the RTL inliner is not used by the languages that use
+ the tree inliner (C, C++). */
int max_insns = (DECL_INLINE (fndecl))
- ? (MAX_INLINE_INSNS
+ ? (MAX_INLINE_INSNS_RTL
+ 8 * list_length (DECL_ARGUMENTS (fndecl)))
: INTEGRATE_THRESHOLD (fndecl);
return (rtx) (size_t) -1;
}
+ /* If there is a TARGET which is a readonly BLKmode MEM and DECL_RESULT
+ is also a mem, we are going to lose the readonly on the stores, so don't
+ inline. */
+ if (target != 0 && GET_CODE (target) == MEM && GET_MODE (target) == BLKmode
+ && RTX_UNCHANGING_P (target) && DECL_RTL_SET_P (DECL_RESULT (fndecl))
+ && GET_CODE (DECL_RTL (DECL_RESULT (fndecl))) == MEM)
+ return (rtx) (size_t) -1;
+
/* Extra arguments are valid, but will be ignored below, so we must
evaluate them here for side-effects. */
for (; actual; actual = TREE_CHAIN (actual))
else
arg_vals[i] = 0;
+ /* If the formal type was const but the actual was not, we might
+ end up here with an rtx wrongly tagged unchanging in the caller's
+ context. Fix that. */
+ if (arg_vals[i] != 0
+ && (GET_CODE (arg_vals[i]) == REG || GET_CODE (arg_vals[i]) == MEM)
+ && ! TREE_READONLY (TREE_VALUE (actual)))
+ RTX_UNCHANGING_P (arg_vals[i]) = 0;
+
if (arg_vals[i] != 0
&& (! TREE_READONLY (formal)
/* If the parameter is not read-only, copy our argument through
if (GET_CODE (parm_insns) == NOTE
&& NOTE_LINE_NUMBER (parm_insns) > 0)
{
- rtx note = emit_note (NOTE_SOURCE_FILE (parm_insns),
- NOTE_LINE_NUMBER (parm_insns));
+ rtx note = emit_line_note (NOTE_SOURCE_FILE (parm_insns),
+ NOTE_LINE_NUMBER (parm_insns));
if (note)
RTX_INTEGRATED_P (note) = 1;
}
&& ! (GET_CODE (XEXP (loc, 0)) == REG
&& REGNO (XEXP (loc, 0)) > LAST_VIRTUAL_REGISTER))
{
- rtx note = emit_note (DECL_SOURCE_FILE (formal),
- DECL_SOURCE_LINE (formal));
+ rtx note = emit_line_note (DECL_SOURCE_FILE (formal),
+ DECL_SOURCE_LINE (formal));
if (note)
RTX_INTEGRATED_P (note) = 1;
This line number note is still needed for debugging though, so we can't
delete it. */
if (flag_test_coverage)
- emit_note (0, NOTE_INSN_REPEATED_LINE_NUMBER);
+ emit_note (NULL, NOTE_INSN_REPEATED_LINE_NUMBER);
- emit_line_note (input_filename, lineno);
+ emit_line_note (input_filename, input_line);
/* If the function returns a BLKmode object in a register, copy it
out of the temp register into a BLKmode memory object. */
#else
try_constants (copy, map);
#endif
- INSN_SCOPE (copy) = INSN_SCOPE (insn);
+ INSN_LOCATOR (copy) = INSN_LOCATOR (insn);
break;
case JUMP_INSN:
cc0_insn = 0;
#endif
try_constants (copy, map);
- INSN_SCOPE (copy) = INSN_SCOPE (insn);
+ INSN_LOCATOR (copy) = INSN_LOCATOR (insn);
/* If this used to be a conditional jump insn but whose branch
direction is now know, we must do something special. */
SIBLING_CALL_P (copy) = SIBLING_CALL_P (insn);
CONST_OR_PURE_CALL_P (copy) = CONST_OR_PURE_CALL_P (insn);
- INSN_SCOPE (copy) = INSN_SCOPE (insn);
+ INSN_LOCATOR (copy) = INSN_LOCATOR (insn);
/* Because the USAGE information potentially contains objects other
than hard registers, we need to copy it. */
NOTE_INSN_DELETED notes aren't useful. */
- if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END
+ if (NOTE_LINE_NUMBER (insn) > 0)
+ copy = emit_line_note (NOTE_SOURCE_FILE (insn),
+ NOTE_LINE_NUMBER (insn));
+ else if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_BEG
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED)
{
- copy = emit_note (NOTE_SOURCE_FILE (insn),
- NOTE_LINE_NUMBER (insn));
- if (copy
- && (NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_BEG
- || NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_END)
+ copy = emit_note (NULL, NOTE_LINE_NUMBER (insn));
+ NOTE_DATA (copy) = NOTE_DATA (insn);
+ if ((NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_BEG
+ || NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_END)
&& NOTE_BLOCK (insn))
{
tree *mapped_block_p;
else
NOTE_BLOCK (copy) = *mapped_block_p;
}
- else if (copy
- && NOTE_LINE_NUMBER (copy) == NOTE_INSN_EXPECTED_VALUE)
+ else if (NOTE_LINE_NUMBER (copy) == NOTE_INSN_EXPECTED_VALUE)
NOTE_EXPECTED_VALUE (copy)
= copy_rtx_and_substitute (NOTE_EXPECTED_VALUE (insn),
map, 0);
copy_rtx_and_substitute (constant, map, for_lhs)),
0);
}
+ else if (TREE_CONSTANT_POOL_ADDRESS_P (orig) && inlining)
+ notice_rtl_inlining_of_deferred_constant ();
return orig;
apply_change_group ();
subst_constants (&PATTERN (insn), insn, map, 0);
apply_change_group ();
+
+ /* Enforce consistency between the addresses in the regular insn flow
+ and the ones in CALL_INSN_FUNCTION_USAGE lists, if any. */
+ if (GET_CODE (insn) == CALL_INSN && CALL_INSN_FUNCTION_USAGE (insn))
+ {
+ subst_constants (&CALL_INSN_FUNCTION_USAGE (insn), insn, map, 1);
+ apply_change_group ();
+ }
/* Show we don't know the value of anything stored or clobbered. */
note_stores (PATTERN (insn), mark_stores, NULL);
/* Make sure warnings emitted by the optimizers (e.g. control reaches
end of non-void function) is not wildly incorrect. */
- input_filename = DECL_SOURCE_FILE (fndecl);
- lineno = DECL_SOURCE_LINE (fndecl);
+ input_location = DECL_SOURCE_LOCATION (fndecl);
/* Compile this function all the way down to assembly code. As a
side effect this destroys the saved RTL representation, but