aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2014-11-25 20:20:10 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2014-11-25 20:20:10 +0000
commit21c6c24fa95aaa9a6d936f99017b2e136095319d (patch)
treeda4ef88a5e4243661576c12a6bcec4bc39fdc7e0 /gcc
parent70edbbaed6e55b884891a0c53ebd974e9e7246be (diff)
downloadgcc-21c6c24fa95aaa9a6d936f99017b2e136095319d.zip
gcc-21c6c24fa95aaa9a6d936f99017b2e136095319d.tar.gz
gcc-21c6c24fa95aaa9a6d936f99017b2e136095319d.tar.bz2
re PR target/63527 (-fPIC uses 2 registers for GOT)
2014-11-25 Vladimir Makarov <vmakarov@redhat.com> PR target/63527 * ira-lives.c (process_bb_node_lives): Check and remove conflict of pic pseudo with pic hard reg. From-SVN: r218059
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/ira-lives.c35
2 files changed, 37 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 01cf1ae..849b70e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2014-11-25 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR target/63527
+ * ira-lives.c (process_bb_node_lives): Check and remove conflict
+ of pic pseudo with pic hard reg.
+
2014-11-25 Rohit <rohitarulraj@freescale.com>
PR bootstrap/63703
diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c
index 0604c47..368b118 100644
--- a/gcc/ira-lives.c
+++ b/gcc/ira-lives.c
@@ -1123,8 +1123,10 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
pessimistic, but it probably doesn't matter much in practice. */
FOR_BB_INSNS_REVERSE (bb, insn)
{
+ int regno;
+ ira_allocno_t a;
df_ref def, use;
- bool call_p;
+ bool call_p, clear_pic_use_conflict_p;
if (!NONDEBUG_INSN_P (insn))
continue;
@@ -1134,6 +1136,21 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
INSN_UID (insn), loop_tree_node->parent->loop_num,
curr_point);
+ call_p = CALL_P (insn);
+ clear_pic_use_conflict_p = false;
+ /* Processing insn usage in call insn can create conflict
+ with pic pseudo and pic hard reg and that is wrong.
+ Check this situation and fix it at the end of the insn
+ processing. */
+ if (call_p && pic_offset_table_rtx != NULL_RTX
+ && (regno = REGNO (pic_offset_table_rtx)) >= FIRST_PSEUDO_REGISTER
+ && (a = ira_curr_regno_allocno_map[regno]) != NULL)
+ clear_pic_use_conflict_p
+ = (find_regno_fusage (insn, USE, REAL_PIC_OFFSET_TABLE_REGNUM)
+ && ! TEST_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS
+ (ALLOCNO_OBJECT (a, 0)),
+ REAL_PIC_OFFSET_TABLE_REGNUM));
+
/* Mark each defined value as live. We need to do this for
unused values because they still conflict with quantities
that are live at the time of the definition.
@@ -1143,7 +1160,6 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
on a call-clobbered register. Marking the register as
live would stop us from allocating it to a call-crossing
allocno. */
- call_p = CALL_P (insn);
FOR_EACH_INSN_DEF (def, insn)
if (!call_p || !DF_REF_FLAGS_IS_SET (def, DF_REF_MAY_CLOBBER))
mark_ref_live (def);
@@ -1207,7 +1223,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
EXECUTE_IF_SET_IN_SPARSESET (objects_live, i)
{
ira_object_t obj = ira_object_id_map[i];
- ira_allocno_t a = OBJECT_ALLOCNO (obj);
+ a = OBJECT_ALLOCNO (obj);
int num = ALLOCNO_NUM (a);
HARD_REG_SET this_call_used_reg_set;
@@ -1257,7 +1273,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
make_early_clobber_and_input_conflicts ();
curr_point++;
-
+
/* Mark each used value as live. */
FOR_EACH_INSN_USE (use, insn)
mark_ref_live (use);
@@ -1286,6 +1302,17 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
}
}
+ if (clear_pic_use_conflict_p)
+ {
+ regno = REGNO (pic_offset_table_rtx);
+ a = ira_curr_regno_allocno_map[regno];
+ CLEAR_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (ALLOCNO_OBJECT (a, 0)),
+ REAL_PIC_OFFSET_TABLE_REGNUM);
+ CLEAR_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS
+ (ALLOCNO_OBJECT (a, 0)),
+ REAL_PIC_OFFSET_TABLE_REGNUM);
+ }
+
curr_point++;
}