aboutsummaryrefslogtreecommitdiff
path: root/gcc/hsa-gen.c
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2017-09-11 11:09:26 +0200
committerMartin Jambor <jamborm@gcc.gnu.org>2017-09-11 11:09:26 +0200
commit635c99aaf7250ef13dbd7a6f02141cb735bdcc2f (patch)
treeb534647fe8cf86ea3c75931fae8433de321d57e3 /gcc/hsa-gen.c
parent15bac1919aab8a4fcbd0150e30f1bc53ae2b271f (diff)
downloadgcc-635c99aaf7250ef13dbd7a6f02141cb735bdcc2f.zip
gcc-635c99aaf7250ef13dbd7a6f02141cb735bdcc2f.tar.gz
gcc-635c99aaf7250ef13dbd7a6f02141cb735bdcc2f.tar.bz2
Make HSA resilient to side-effects of split_edge
2017-09-11 Martin Jambor <mjambor@suse.cz> PR hsa/82119 * hsa-gen.c (gen_hsa_phi_from_gimple_phi): Process ADDR_EXPRs in arguments in advance. * hsa-regalloc.c (naive_process_phi): New parameter predecessors, use it to find predecessor edges. (naive_outof_ssa): Collect vector of predecessors. From-SVN: r251964
Diffstat (limited to 'gcc/hsa-gen.c')
-rw-r--r--gcc/hsa-gen.c51
1 files changed, 38 insertions, 13 deletions
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index bd22762..6e054c0 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -5657,8 +5657,37 @@ gen_hsa_phi_from_gimple_phi (gimple *phi_stmt, hsa_bb *hbb)
hphi = new hsa_insn_phi (count, dest);
hphi->m_bb = hbb->m_bb;
- tree lhs = gimple_phi_result (phi_stmt);
+ auto_vec <tree, 8> aexprs;
+ auto_vec <hsa_op_reg *, 8> aregs;
+
+ /* Calling split_edge when processing a PHI node messes up with the order of
+ gimple phi node arguments (it moves the one associated with the edge to
+ the end). We need to keep the order of edges and arguments of HSA phi
+ node arguments consistent, so we do all required splitting as the first
+ step, and in reverse order as to not be affected by the re-orderings. */
+ for (unsigned j = count; j != 0; j--)
+ {
+ unsigned i = j - 1;
+ tree op = gimple_phi_arg_def (phi_stmt, i);
+ if (TREE_CODE (op) != ADDR_EXPR)
+ continue;
+ edge e = gimple_phi_arg_edge (as_a <gphi *> (phi_stmt), i);
+ hsa_bb *hbb_src = hsa_init_new_bb (split_edge (e));
+ hsa_op_address *addr = gen_hsa_addr (TREE_OPERAND (op, 0),
+ hbb_src);
+
+ hsa_op_reg *dest
+ = new hsa_op_reg (hsa_get_segment_addr_type (BRIG_SEGMENT_FLAT));
+ hsa_insn_basic *insn
+ = new hsa_insn_basic (2, BRIG_OPCODE_LDA, BRIG_TYPE_U64,
+ dest, addr);
+ hbb_src->append_insn (insn);
+ aexprs.safe_push (op);
+ aregs.safe_push (dest);
+ }
+
+ tree lhs = gimple_phi_result (phi_stmt);
for (unsigned i = 0; i < count; i++)
{
tree op = gimple_phi_arg_def (phi_stmt, i);
@@ -5684,18 +5713,14 @@ gen_hsa_phi_from_gimple_phi (gimple *phi_stmt, hsa_bb *hbb)
}
else if (TREE_CODE (op) == ADDR_EXPR)
{
- edge e = gimple_phi_arg_edge (as_a <gphi *> (phi_stmt), i);
- hsa_bb *hbb_src = hsa_init_new_bb (split_edge (e));
- hsa_op_address *addr = gen_hsa_addr (TREE_OPERAND (op, 0),
- hbb_src);
-
- hsa_op_reg *dest
- = new hsa_op_reg (hsa_get_segment_addr_type (BRIG_SEGMENT_FLAT));
- hsa_insn_basic *insn
- = new hsa_insn_basic (2, BRIG_OPCODE_LDA, BRIG_TYPE_U64,
- dest, addr);
- hbb_src->append_insn (insn);
-
+ hsa_op_reg *dest = NULL;
+ for (unsigned a_idx = 0; a_idx < aexprs.length (); a_idx++)
+ if (aexprs[a_idx] == op)
+ {
+ dest = aregs[a_idx];
+ break;
+ }
+ gcc_assert (dest);
hphi->set_op (i, dest);
}
else