/* Integrated Register Allocator. Changing code and generating moves.
- Copyright (C) 2006-2014 Free Software Foundation, Inc.
+ Copyright (C) 2006-2019 Free Software Foundation, Inc.
Contributed by Vladimir Makarov <vmakarov@redhat.com>.
This file is part of GCC.
#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "tm.h"
-#include "regs.h"
+#include "backend.h"
#include "rtl.h"
-#include "tm_p.h"
-#include "target.h"
-#include "flags.h"
-#include "obstack.h"
-#include "bitmap.h"
-#include "hard-reg-set.h"
-#include "basic-block.h"
-#include "expr.h"
-#include "recog.h"
-#include "params.h"
-#include "reload.h"
+#include "tree.h"
+#include "predict.h"
#include "df.h"
+#include "insn-config.h"
+#include "regs.h"
+#include "memmodel.h"
+#include "ira.h"
#include "ira-int.h"
+#include "cfgrtl.h"
+#include "cfgbuild.h"
+#include "expr.h"
+#include "reload.h"
+#include "cfgloop.h"
/* Data used to emit live range split insns and to flattening IR. */
return result;
}
+static bool
+change_regs_in_insn (rtx_insn **insn_ptr)
+{
+ rtx rtx = *insn_ptr;
+ bool result = change_regs (&rtx);
+ *insn_ptr = as_a <rtx_insn *> (rtx);
+ return result;
+}
+
/* Attach MOVE to the edge E. The move is attached to the head of the
list if HEAD_P is TRUE. */
static void
int regno;
bool used_p;
ira_allocno_t allocno, parent_allocno, *map;
- rtx insn, original_reg;
+ rtx_insn *insn;
+ rtx original_reg;
enum reg_class aclass, pclass;
ira_loop_tree_node_t parent;
if (node->bb != NULL)
{
FOR_BB_INSNS (node->bb, insn)
- if (INSN_P (insn) && change_regs (&insn))
+ if (INSN_P (insn) && change_regs_in_insn (&insn))
{
df_insn_rescan (insn);
df_notes_rescan (insn);
/* don't create copies because reload can spill an
allocno set by copy although the allocno will not
get memory slot. */
- || ira_equiv_no_lvalue_p (regno)))
+ || ira_equiv_no_lvalue_p (regno)
+ || (pic_offset_table_rtx != NULL
+ && (ALLOCNO_REGNO (allocno)
+ == (int) REGNO (pic_offset_table_rtx)))))
continue;
original_reg = allocno_emit_reg (allocno);
if (parent_allocno == NULL
if (list == NULL)
return NULL;
- /* Creat move deps. */
+ /* Create move deps. */
curr_tick++;
for (move = list; move != NULL; move = move->next)
{
to = move->to;
if ((hard_regno = ALLOCNO_HARD_REGNO (to)) < 0)
continue;
- nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (to)];
+ nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (to));
for (i = 0; i < nregs; i++)
{
hard_regno_last_set[hard_regno + i] = move;
to = move->to;
if ((hard_regno = ALLOCNO_HARD_REGNO (from)) >= 0)
{
- nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (from)];
+ nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (from));
for (n = i = 0; i < nregs; i++)
if (hard_regno_last_set_check[hard_regno + i] == curr_tick
&& (ALLOCNO_REGNO (hard_regno_last_set[hard_regno + i]->to)
move->deps_num = n;
}
}
- /* Toplogical sorting: */
+ /* Topological sorting: */
move_vec.truncate (0);
for (move = list; move != NULL; move = move->next)
traverse_moves (move);
to = move->to;
if ((hard_regno = ALLOCNO_HARD_REGNO (from)) >= 0)
{
- nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (from)];
+ nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (from));
for (i = 0; i < nregs; i++)
if (hard_regno_last_set_check[hard_regno + i] == curr_tick
&& ALLOCNO_HARD_REGNO
}
if ((hard_regno = ALLOCNO_HARD_REGNO (to)) < 0)
continue;
- nregs = hard_regno_nregs[hard_regno][ALLOCNO_MODE (to)];
+ nregs = hard_regno_nregs (hard_regno, ALLOCNO_MODE (to));
for (i = 0; i < nregs; i++)
{
hard_regno_last_set[hard_regno + i] = move;
int to_regno, from_regno, cost, regno;
rtx_insn *result, *insn;
rtx set;
- enum machine_mode mode;
+ machine_mode mode;
enum reg_class aclass;
grow_reg_equivs ();
basic_block bb;
edge_iterator ei;
edge e;
- rtx_insn *insns, *tmp;
+ rtx_insn *insns, *tmp, *next;
FOR_EACH_BB_FN (bb, cfun)
{
if (at_bb_start[bb->index] != NULL)
{
at_bb_start[bb->index] = modify_move_list (at_bb_start[bb->index]);
- insns = emit_move_list (at_bb_start[bb->index],
- REG_FREQ_FROM_BB (bb));
+ insns
+ = emit_move_list (at_bb_start[bb->index], REG_FREQ_FROM_BB (bb));
tmp = BB_HEAD (bb);
if (LABEL_P (tmp))
tmp = NEXT_INSN (tmp);
if (NOTE_INSN_BASIC_BLOCK_P (tmp))
tmp = NEXT_INSN (tmp);
+ /* Make sure to put the location of TMP or a subsequent instruction
+ to avoid inheriting the location of the previous instruction. */
+ next = tmp;
+ while (next && !NONDEBUG_INSN_P (next))
+ next = NEXT_INSN (next);
+ if (next)
+ set_insn_locations (insns, INSN_LOCATION (next));
if (tmp == BB_HEAD (bb))
emit_insn_before (insns, tmp);
- else if (tmp != NULL_RTX)
+ else if (tmp)
emit_insn_after (insns, PREV_INSN (tmp));
else
emit_insn_after (insns, get_last_insn ());