i965: Prepare the break/cont uip/jip setting for compacted instructions.
The first cut at instruction compaction won't compact things that would change control flow jump distances, but we do need to still be able to walk the instruction stream, which involves jumping by 8 or 16 bytes between instructions. Reviewed-by: Paul Berry <stereotype441@gmail.com>
This commit is contained in:
parent
f2bd3e70b5
commit
f5e2706395
|
@ -2475,13 +2475,25 @@ void brw_urb_WRITE(struct brw_compile *p,
|
||||||
swizzle);
|
swizzle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
next_ip(struct brw_compile *p, int ip)
|
||||||
|
{
|
||||||
|
struct brw_instruction *insn = (void *)p->store + ip;
|
||||||
|
|
||||||
|
if (insn->header.cmpt_control)
|
||||||
|
return ip + 8;
|
||||||
|
else
|
||||||
|
return ip + 16;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
brw_find_next_block_end(struct brw_compile *p, int start)
|
brw_find_next_block_end(struct brw_compile *p, int start)
|
||||||
{
|
{
|
||||||
int ip;
|
int ip;
|
||||||
|
void *store = p->store;
|
||||||
|
|
||||||
for (ip = start + 1; ip < p->nr_insn; ip++) {
|
for (ip = next_ip(p, start); ip < p->next_insn_offset; ip = next_ip(p, ip)) {
|
||||||
struct brw_instruction *insn = &p->store[ip];
|
struct brw_instruction *insn = store + ip;
|
||||||
|
|
||||||
switch (insn->header.opcode) {
|
switch (insn->header.opcode) {
|
||||||
case BRW_OPCODE_ENDIF:
|
case BRW_OPCODE_ENDIF:
|
||||||
|
@ -2503,20 +2515,24 @@ brw_find_loop_end(struct brw_compile *p, int start)
|
||||||
{
|
{
|
||||||
struct intel_context *intel = &p->brw->intel;
|
struct intel_context *intel = &p->brw->intel;
|
||||||
int ip;
|
int ip;
|
||||||
int br = 2;
|
int scale = 8;
|
||||||
|
void *store = p->store;
|
||||||
|
|
||||||
for (ip = start + 1; ip < p->nr_insn; ip++) {
|
/* Always start after the instruction (such as a WHILE) we're trying to fix
|
||||||
struct brw_instruction *insn = &p->store[ip];
|
* up.
|
||||||
|
*/
|
||||||
|
for (ip = next_ip(p, start); ip < p->next_insn_offset; ip = next_ip(p, ip)) {
|
||||||
|
struct brw_instruction *insn = store + ip;
|
||||||
|
|
||||||
if (insn->header.opcode == BRW_OPCODE_WHILE) {
|
if (insn->header.opcode == BRW_OPCODE_WHILE) {
|
||||||
int jip = intel->gen == 6 ? insn->bits1.branch_gen6.jump_count
|
int jip = intel->gen == 6 ? insn->bits1.branch_gen6.jump_count
|
||||||
: insn->bits3.break_cont.jip;
|
: insn->bits3.break_cont.jip;
|
||||||
if (ip + jip / br <= start)
|
if (ip + jip * scale <= start)
|
||||||
return ip;
|
return ip;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(!"not reached");
|
assert(!"not reached");
|
||||||
return start + 1;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* After program generation, go back and update the UIP and JIP of
|
/* After program generation, go back and update the UIP and JIP of
|
||||||
|
@ -2527,24 +2543,37 @@ brw_set_uip_jip(struct brw_compile *p)
|
||||||
{
|
{
|
||||||
struct intel_context *intel = &p->brw->intel;
|
struct intel_context *intel = &p->brw->intel;
|
||||||
int ip;
|
int ip;
|
||||||
int br = 2;
|
int scale = 8;
|
||||||
|
void *store = p->store;
|
||||||
|
|
||||||
if (intel->gen < 6)
|
if (intel->gen < 6)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (ip = 0; ip < p->nr_insn; ip++) {
|
for (ip = 0; ip < p->next_insn_offset; ip = next_ip(p, ip)) {
|
||||||
struct brw_instruction *insn = &p->store[ip];
|
struct brw_instruction *insn = store + ip;
|
||||||
|
|
||||||
|
if (insn->header.cmpt_control) {
|
||||||
|
/* Fixups for compacted BREAK/CONTINUE not supported yet. */
|
||||||
|
assert(insn->header.opcode != BRW_OPCODE_BREAK &&
|
||||||
|
insn->header.opcode != BRW_OPCODE_CONTINUE &&
|
||||||
|
insn->header.opcode != BRW_OPCODE_HALT);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch (insn->header.opcode) {
|
switch (insn->header.opcode) {
|
||||||
case BRW_OPCODE_BREAK:
|
case BRW_OPCODE_BREAK:
|
||||||
insn->bits3.break_cont.jip = br * (brw_find_next_block_end(p, ip) - ip);
|
insn->bits3.break_cont.jip =
|
||||||
|
(brw_find_next_block_end(p, ip) - ip) / scale;
|
||||||
/* Gen7 UIP points to WHILE; Gen6 points just after it */
|
/* Gen7 UIP points to WHILE; Gen6 points just after it */
|
||||||
insn->bits3.break_cont.uip =
|
insn->bits3.break_cont.uip =
|
||||||
br * (brw_find_loop_end(p, ip) - ip + (intel->gen == 6 ? 1 : 0));
|
(brw_find_loop_end(p, ip) - ip +
|
||||||
|
(intel->gen == 6 ? 16 : 0)) / scale;
|
||||||
break;
|
break;
|
||||||
case BRW_OPCODE_CONTINUE:
|
case BRW_OPCODE_CONTINUE:
|
||||||
insn->bits3.break_cont.jip = br * (brw_find_next_block_end(p, ip) - ip);
|
insn->bits3.break_cont.jip =
|
||||||
insn->bits3.break_cont.uip = br * (brw_find_loop_end(p, ip) - ip);
|
(brw_find_next_block_end(p, ip) - ip) / scale;
|
||||||
|
insn->bits3.break_cont.uip =
|
||||||
|
(brw_find_loop_end(p, ip) - ip) / scale;
|
||||||
|
|
||||||
assert(insn->bits3.break_cont.uip != 0);
|
assert(insn->bits3.break_cont.uip != 0);
|
||||||
assert(insn->bits3.break_cont.jip != 0);
|
assert(insn->bits3.break_cont.jip != 0);
|
||||||
|
|
Loading…
Reference in New Issue