ir3: branch stuff

This commit is contained in:
Amber 2023-11-30 12:39:25 +01:00
parent 945288ffae
commit 830ee87cff
5 changed files with 50 additions and 6 deletions

View File

@ -617,6 +617,7 @@ enum ir3_branch_type {
IR3_BRANCH_ALL, /* subgroupAll(condition) */
IR3_BRANCH_GETONE, /* subgroupElect() */
IR3_BRANCH_SHPS, /* preamble start */
IR3_BRANCH_AND,
};
struct ir3_block {
@ -645,6 +646,7 @@ struct ir3_block {
* the else.
*/
struct ir3_instruction *condition;
struct ir3_instruction *condition2;
struct ir3_block *successors[2];
struct ir3_block *physical_successors[2];

View File

@ -3687,8 +3687,20 @@ emit_if(struct ir3_context *ctx, nir_if *nif)
ctx->block->condition = NULL;
ctx->block->brtype = IR3_BRANCH_SHPS;
} else {
ctx->block->condition = ir3_get_predicate(ctx, condition);
ctx->block->brtype = IR3_BRANCH_COND;
if (condition->opc == OPC_AND_B) {
//ir3_print_instr(condition);
//ctx->block->brtype = IR3_BRANCH_COND;
ctx->block->brtype = IR3_BRANCH_AND;
/*condition->dsts[0]->num = regid(REG_P0, 0);
condition->dsts[0]->flags &= ~IR3_REG_SSA;
ctx->block->condition = condition;*/
ctx->block->condition = ir3_get_predicate(ctx, ssa(condition->srcs[0]));
ctx->block->condition2 = ir3_get_predicate2(ctx, ssa(condition->srcs[1]));
} else {
ctx->block->condition = ir3_get_predicate(ctx, condition);
ctx->block->brtype = IR3_BRANCH_COND;
}
}
emit_cf_list(ctx, &nif->then_list);

View File

@ -483,7 +483,27 @@ ir3_get_predicate(struct ir3_context *ctx, struct ir3_instruction *src)
cond->cat2.condition = IR3_COND_NE;
/* condition always goes in predicate register: */
cond->dsts[0]->num = regid(REG_P0, 0);
cond->dsts[0]->num = regid(REG_P0, 1);
cond->dsts[0]->flags &= ~IR3_REG_SSA;
return cond;
}
struct ir3_instruction *
ir3_get_predicate2(struct ir3_context *ctx, struct ir3_instruction *src)
{
struct ir3_block *b = ctx->block;
struct ir3_instruction *cond;
/* NOTE: only cmps.*.* can write p0.x: */
struct ir3_instruction *zero =
create_immed_typed(b, 0, is_half(src) ? TYPE_U16 : TYPE_U32);
cond = ir3_CMPS_S(b, src, 0, zero, 0);
cond->cat2.condition = IR3_COND_NE;
/* condition always goes in predicate register: */
cond->dsts[0]->num = regid(REG_P0, 1);
cond->dsts[0]->flags &= ~IR3_REG_SSA;
return cond;

View File

@ -243,6 +243,9 @@ struct ir3_instruction *ir3_get_addr1(struct ir3_context *ctx,
struct ir3_instruction *ir3_get_predicate(struct ir3_context *ctx,
struct ir3_instruction *src);
struct ir3_instruction *ir3_get_predicate2(struct ir3_context *ctx,
struct ir3_instruction *src);
void ir3_declare_array(struct ir3_context *ctx, nir_intrinsic_instr *decl);
struct ir3_array *ir3_get_array(struct ir3_context *ctx, nir_def *reg);
struct ir3_instruction *ir3_create_array_load(struct ir3_context *ctx,

View File

@ -792,15 +792,15 @@ block_sched(struct ir3 *ir)
/* create "else" branch first (since "then" block should
* frequently/always end up being a fall-thru):
*/
br1 = ir3_instr_create(block, OPC_B, 0, 1);
br1 = ir3_instr_create(block, OPC_B, 0, block->brtype == IR3_BRANCH_AND ? 2 : 1);
ir3_src_create(br1, regid(REG_P0, 0), 0)->def =
block->condition->dsts[0];
br1->cat0.inv1 = true;
br1->cat0.target = block->successors[1];
/* "then" branch: */
br2 = ir3_instr_create(block, OPC_B, 0, 1);
ir3_src_create(br2, regid(REG_P0, 0), 0)->def =
br2 = ir3_instr_create(block, OPC_B, 0, block->brtype == IR3_BRANCH_AND ? 2 : 1);
ir3_src_create(br2, regid(REG_P0, 1), 0)->def =
block->condition->dsts[0];
br2->cat0.target = block->successors[0];
@ -816,6 +816,13 @@ block_sched(struct ir3 *ir)
br1->cat0.brtype = BRANCH_ALL;
br2->cat0.brtype = BRANCH_ANY;
break;
case IR3_BRANCH_AND:
br1->cat0.brtype = br2->cat0.brtype = BRANCH_AND;
ir3_src_create(br1, regid(REG_P0, 0), 0)->def =
block->condition2->dsts[0];
ir3_src_create(br2, regid(REG_P0, 1), 0)->def =
block->condition2->dsts[0];
break;
case IR3_BRANCH_GETONE:
case IR3_BRANCH_SHPS:
unreachable("can't get here");