/* Instruction scheduling pass. This file computes dependencies between
instructions.
- Copyright (C) 1992-2019 Free Software Foundation, Inc.
+ Copyright (C) 1992-2020 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
and currently maintained by, Jim Wilson (wilson@cygnus.com)
#include "insn-attr.h"
#include "cfgbuild.h"
#include "sched-int.h"
-#include "params.h"
#include "cselib.h"
+#include "function-abi.h"
#ifdef INSN_SCHEDULING
reg_pressure_info[cl].change = 0;
}
- note_stores (PATTERN (insn), mark_insn_reg_clobber, insn);
+ note_stores (insn, mark_insn_reg_clobber, insn);
- note_stores (PATTERN (insn), mark_insn_reg_store, insn);
+ note_stores (insn, mark_insn_reg_store, insn);
if (AUTO_INC_DEC)
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
while (--i >= 0)
note_reg_use (regno + i);
}
- else if (ref == CLOBBER_HIGH)
- {
- gcc_assert (i == 1);
- /* We don't know the current state of the register, so have to treat
- the clobber high as a full clobber. */
- note_reg_clobber (regno);
- }
else
{
while (--i >= 0)
else if (ref == USE)
note_reg_use (regno);
else
- /* For CLOBBER_HIGH, we don't know the current state of the register,
- so have to treat it as a full clobber. */
note_reg_clobber (regno);
/* Pseudos that are REG_EQUIV to something may be replaced
/* Pending lists can't get larger with a readonly context. */
if (!deps->readonly
&& ((deps->pending_read_list_length + deps->pending_write_list_length)
- >= MAX_PENDING_LIST_LENGTH))
+ >= param_max_pending_list_length))
{
/* Flush all pending reads and writes to prevent the pending lists
from getting any larger. Insn scheduling runs too slowly when
{
if ((deps->pending_read_list_length
+ deps->pending_write_list_length)
- >= MAX_PENDING_LIST_LENGTH
+ >= param_max_pending_list_length
&& !DEBUG_INSN_P (insn))
flush_pending_lists (deps, insn, true, true);
add_insn_mem_dependence (deps, true, insn, x);
preprocess_constraints (insn);
alternative_mask preferred = get_preferred_alternatives (insn);
ira_implicitly_set_insn_hard_regs (temp, preferred);
- AND_COMPL_HARD_REG_SET (*temp, ira_no_alloc_regs);
+ *temp &= ~ira_no_alloc_regs;
}
/* Analyze an INSN with pattern X to find all dependencies. */
{
HARD_REG_SET temp;
get_implicit_reg_pending_clobbers (&temp, insn);
- IOR_HARD_REG_SET (implicit_reg_pending_clobbers, temp);
+ implicit_reg_pending_clobbers |= temp;
}
can_start_lhs_rhs_p = (NONJUMP_INSN_P (insn)
sub = COND_EXEC_CODE (sub);
code = GET_CODE (sub);
}
- else if (code == SET || code == CLOBBER || code == CLOBBER_HIGH)
+ else if (code == SET || code == CLOBBER)
sched_analyze_1 (deps, sub, insn);
else
sched_analyze_2 (deps, sub, insn);
{
if (GET_CODE (XEXP (link, 0)) == CLOBBER)
sched_analyze_1 (deps, XEXP (link, 0), insn);
- else if (GET_CODE (XEXP (link, 0)) == CLOBBER_HIGH)
- /* We could support CLOBBER_HIGH and treat it in the same way as
- HARD_REGNO_CALL_PART_CLOBBERED, but no port needs that yet. */
- gcc_unreachable ();
else if (GET_CODE (XEXP (link, 0)) != SET)
sched_analyze_2 (deps, XEXP (link, 0), insn);
}
EXECUTE_IF_SET_IN_REG_SET (reg_pending_clobbers, 0, i, rsi)
{
struct deps_reg *reg_last = &deps->reg_last[i];
- if (reg_last->uses_length >= MAX_PENDING_LIST_LENGTH
- || reg_last->clobbers_length >= MAX_PENDING_LIST_LENGTH)
+ if (reg_last->uses_length >= param_max_pending_list_length
+ || reg_last->clobbers_length >= param_max_pending_list_length)
{
add_dependence_list_and_free (deps, insn, ®_last->sets, 0,
REG_DEP_OUTPUT, false);
IOR_REG_SET (&deps->reg_last_in_use, reg_pending_uses);
IOR_REG_SET (&deps->reg_last_in_use, reg_pending_clobbers);
IOR_REG_SET (&deps->reg_last_in_use, reg_pending_sets);
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (TEST_HARD_REG_BIT (implicit_reg_pending_uses, i)
- || TEST_HARD_REG_BIT (implicit_reg_pending_clobbers, i))
- SET_REGNO_REG_SET (&deps->reg_last_in_use, i);
+ IOR_REG_SET_HRS (&deps->reg_last_in_use,
+ implicit_reg_pending_uses
+ | implicit_reg_pending_clobbers);
/* Set up the pending barrier found. */
deps->last_reg_pending_barrier = reg_pending_barrier;
&& sel_insn_is_speculation_check (insn)))
{
/* Keep the list a reasonable size. */
- if (deps->pending_flush_length++ >= MAX_PENDING_LIST_LENGTH)
- flush_pending_lists (deps, insn, true, true);
+ if (deps->pending_flush_length++ >= param_max_pending_list_length)
+ flush_pending_lists (deps, insn, true, true);
else
deps->pending_jump_insns
= alloc_INSN_LIST (insn, deps->pending_jump_insns);
}
else
{
+ function_abi callee_abi = insn_callee_abi (insn);
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
/* A call may read and modify global register variables. */
if (global_regs[i])
Since we only have a choice between 'might be clobbered'
and 'definitely not clobbered', we must include all
partly call-clobbered registers here. */
- else if (targetm.hard_regno_call_part_clobbered (insn, i,
- reg_raw_mode[i])
- || TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
+ else if (callee_abi.clobbers_at_least_part_of_reg_p (i))
SET_REGNO_REG_SET (reg_pending_clobbers, i);
/* We don't know what set of fixed registers might be used
by the function, but it is certain that the stack pointer