* [hsa] Fix register allocator
@ 2015-06-25 16:15 Martin Liška
0 siblings, 0 replies; only message in thread
From: Martin Liška @ 2015-06-25 16:15 UTC (permalink / raw)
To: GCC Patches; +Cc: Michael Matz, Martin Jambor
[-- Attachment #1: Type: text/plain, Size: 208 bytes --]
Hi.
The following patch fixes HSA register allocator which hasn't visited
all insns that belong to a call block insn. As a result, the allocator
hasn't passed correct registers to a called function.
Martin
[-- Attachment #2: 0001-HSA-Fix-register-allocator.patch --]
[-- Type: text/x-patch, Size: 5942 bytes --]
From 1d0f5dce43f7af5a65bbfb5aef9545a3f1c0af27 Mon Sep 17 00:00:00 2001
From: mliska <mliska@suse.cz>
Date: Mon, 22 Jun 2015 17:53:25 +0200
Subject: [PATCH 1/3] HSA: Fix register allocator.
gcc/ChangeLog:
2015-06-23 Martin Liska <mliska@suse.cz>
* hsa-regalloc.c (visit_insn): New function.
(linear_scan_regalloc): Use the newly added function and
visit also all insns that belong to a call block insn.
(merge_live_range_for_insn): Likewise.
(linear_scan_regalloc): Likewise.
---
gcc/hsa-regalloc.c | 119 +++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 89 insertions(+), 30 deletions(-)
diff --git a/gcc/hsa-regalloc.c b/gcc/hsa-regalloc.c
index 2535c73..0a8b77c 100644
--- a/gcc/hsa-regalloc.c
+++ b/gcc/hsa-regalloc.c
@@ -504,6 +504,65 @@ spill_at_interval (hsa_op_reg *reg, vec<hsa_op_reg*> *active)
cand->spill_sym->name_number = cand->order;
}
+/* Visit instruction INSN and fill in vector IND2REG if the instruction
+ contains a register (in memory). Number all insns by a global counter,
+ passed by INSN_ORDER argument. */
+
+static void
+visit_insn (hsa_insn_basic *insn, vec<hsa_op_reg*> &ind2reg, int &insn_order)
+{
+ int opi;
+ insn->number = insn_order++;
+ for (opi = 0; opi < HSA_OPERANDS_PER_INSN && insn->operands[opi]; opi++)
+ {
+ hsa_op_reg **regaddr = insn_reg_addr (insn, opi);
+ if (regaddr)
+ ind2reg[(*regaddr)->order] = *regaddr;
+ }
+}
+
+/* Remove definition in INSN according to bitmap WORK list. */
+
+static void
+remove_def_in_insn (bitmap &work, hsa_insn_basic *insn)
+{
+ int opi;
+ int ndefs = hsa_num_def_ops (insn);
+ for (opi = 0; opi < ndefs && insn->operands[opi]; opi++)
+ {
+ hsa_op_reg **regaddr = insn_reg_addr (insn, opi);
+ if (regaddr)
+ bitmap_clear_bit (work, (*regaddr)->order);
+ }
+ for (; opi < HSA_OPERANDS_PER_INSN && insn->operands[opi]; opi++)
+ {
+ hsa_op_reg **regaddr = insn_reg_addr (insn, opi);
+ if (regaddr)
+ bitmap_set_bit (work, (*regaddr)->order);
+ }
+}
+
+/* Merge live range for an instruction INSN. */
+
+static void
+merge_live_range_for_insn (hsa_insn_basic *insn)
+{
+ int opi;
+ int ndefs = hsa_num_def_ops (insn);
+ for (opi = 0; opi < HSA_OPERANDS_PER_INSN && insn->operands[opi]; opi++)
+ {
+ hsa_op_reg **regaddr = insn_reg_addr (insn, opi);
+ if (regaddr)
+ {
+ hsa_op_reg *reg = *regaddr;
+ if (opi < ndefs)
+ note_lr_begin (reg, insn->number);
+ else
+ note_lr_end (reg, insn->number);
+ }
+ }
+}
+
/* Given the global register state CLASSES allocate all HSA virtual
registers either to hardregs or to a spill symbol. */
@@ -536,13 +595,16 @@ linear_scan_regalloc (struct reg_class_desc *classes)
hsa_insn_basic *insn;
for (insn = hbb->first_insn; insn; insn = insn->next)
{
- int opi;
- insn->number = insn_order++;
- for (opi = 0; opi < HSA_OPERANDS_PER_INSN && insn->operands[opi]; opi++)
+ visit_insn (insn, ind2reg, insn_order);
+
+ if (is_a <hsa_insn_call_block *> (insn))
{
- hsa_op_reg **regaddr = insn_reg_addr (insn, opi);
- if (regaddr)
- ind2reg[(*regaddr)->order] = *regaddr;
+ /* HSA call block insn contains insns that are used for passing
+ arguments and getting a return value, if returned. */
+ hsa_insn_call_block *call = dyn_cast <hsa_insn_call_block *>
+ (insn);
+ for (unsigned j = 0; j < call->input_arg_insns.length (); j++)
+ visit_insn (call->input_arg_insns[j], ind2reg, insn_order);
}
}
}
@@ -588,19 +650,17 @@ linear_scan_regalloc (struct reg_class_desc *classes)
hsa_insn_basic *insn;
for (insn = hbb->last_insn; insn; insn = insn->prev)
{
- int opi;
- int ndefs = hsa_num_def_ops (insn);
- for (opi = 0; opi < ndefs && insn->operands[opi]; opi++)
- {
- hsa_op_reg **regaddr = insn_reg_addr (insn, opi);
- if (regaddr)
- bitmap_clear_bit (work, (*regaddr)->order);
- }
- for (; opi < HSA_OPERANDS_PER_INSN && insn->operands[opi]; opi++)
+ remove_def_in_insn (work, insn);
+ if (is_a <hsa_insn_call_block *> (insn))
{
- hsa_op_reg **regaddr = insn_reg_addr (insn, opi);
- if (regaddr)
- bitmap_set_bit (work, (*regaddr)->order);
+ /* HSA call block insn contains insns that are used for
+ passing arguments and getting a return value,
+ if returned. */
+ hsa_insn_call_block *call = dyn_cast <hsa_insn_call_block *>
+ (insn);
+
+ for (int j = call->input_arg_insns.length () - 1; j >= 0; j--)
+ remove_def_in_insn (work, call->input_arg_insns[j]);
}
}
@@ -634,19 +694,17 @@ linear_scan_regalloc (struct reg_class_desc *classes)
for (insn = hbb->last_insn; insn; insn = insn->prev)
{
- int opi;
- int ndefs = hsa_num_def_ops (insn);
- for (opi = 0; opi < HSA_OPERANDS_PER_INSN && insn->operands[opi]; opi++)
+ merge_live_range_for_insn (insn);
+
+ if (is_a <hsa_insn_call_block *> (insn))
{
- hsa_op_reg **regaddr = insn_reg_addr (insn, opi);
- if (regaddr)
- {
- hsa_op_reg *reg = *regaddr;
- if (opi < ndefs)
- note_lr_begin (reg, insn->number);
- else
- note_lr_end (reg, insn->number);
- }
+ /* HSA call block insn contains insns that are used for passing
+ arguments and getting a return value, if returned. */
+ hsa_insn_call_block *call = dyn_cast <hsa_insn_call_block *>
+ (insn);
+
+ for (int j = call->input_arg_insns.length () - 1; j >= 0; j--)
+ merge_live_range_for_insn (call->input_arg_insns[j]);
}
}
if (hbb->first_insn)
@@ -660,6 +718,7 @@ linear_scan_regalloc (struct reg_class_desc *classes)
ind2reg[i]->lr_begin = 0;
/* Sort all intervals by increasing start point. */
+ gcc_assert (ind2reg.length () == (size_t) hsa_cfun.reg_count);
ind2reg.qsort (cmp_begin);
for (i = 0; i < 4; i++)
active[i].reserve_exact (hsa_cfun.reg_count);
--
2.1.4
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2015-06-25 16:08 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-25 16:15 [hsa] Fix register allocator Martin Liška
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).