gallivm: implement loops
This commit is contained in:
parent
242893cce2
commit
18d406e8a8
|
@ -308,7 +308,7 @@ lp_build_flow_scope_end(struct lp_build_flow_context *flow)
|
|||
* Note: this function has no dependencies on the flow code and could
|
||||
* be used elsewhere.
|
||||
*/
|
||||
static LLVMBasicBlockRef
|
||||
LLVMBasicBlockRef
|
||||
lp_build_insert_new_block(LLVMBuilderRef builder, const char *name)
|
||||
{
|
||||
LLVMBasicBlockRef current_block;
|
||||
|
|
|
@ -145,7 +145,9 @@ lp_build_else(struct lp_build_if_state *ctx);
|
|||
|
||||
void
|
||||
lp_build_endif(struct lp_build_if_state *ctx);
|
||||
|
||||
|
||||
LLVMBasicBlockRef
|
||||
lp_build_insert_new_block(LLVMBuilderRef builder, const char *name);
|
||||
|
||||
|
||||
#endif /* !LP_BLD_FLOW_H */
|
||||
|
|
|
@ -95,6 +95,19 @@ struct lp_exec_mask {
|
|||
int cond_stack_size;
|
||||
LLVMValueRef cond_mask;
|
||||
|
||||
LLVMValueRef break_stack[LP_TGSI_MAX_NESTING];
|
||||
int break_stack_size;
|
||||
LLVMValueRef break_mask;
|
||||
|
||||
LLVMValueRef cont_stack[LP_TGSI_MAX_NESTING];
|
||||
int cont_stack_size;
|
||||
LLVMValueRef cont_mask;
|
||||
|
||||
LLVMBasicBlockRef loop_stack[LP_TGSI_MAX_NESTING];
|
||||
int loop_stack_size;
|
||||
LLVMBasicBlockRef loop_block;
|
||||
|
||||
|
||||
LLVMValueRef exec_mask;
|
||||
};
|
||||
|
||||
|
@ -145,14 +158,33 @@ static void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context
|
|||
mask->bld = bld;
|
||||
mask->has_mask = FALSE;
|
||||
mask->cond_stack_size = 0;
|
||||
mask->loop_stack_size = 0;
|
||||
mask->break_stack_size = 0;
|
||||
mask->cont_stack_size = 0;
|
||||
|
||||
mask->int_vec_type = lp_build_int_vec_type(mask->bld->type);
|
||||
}
|
||||
|
||||
static void lp_exec_mask_update(struct lp_exec_mask *mask)
|
||||
{
|
||||
mask->exec_mask = mask->cond_mask;
|
||||
mask->has_mask = (mask->cond_stack_size > 0);
|
||||
if (mask->loop_stack_size) {
|
||||
/*for loops we need to update the entire mask at
|
||||
* runtime */
|
||||
LLVMValueRef tmp;
|
||||
tmp = LLVMBuildAnd(mask->bld->builder,
|
||||
mask->cont_mask,
|
||||
mask->break_mask,
|
||||
"maskcb");
|
||||
mask->exec_mask = LLVMBuildAnd(mask->bld->builder,
|
||||
mask->cond_mask,
|
||||
tmp,
|
||||
"maskfull");
|
||||
} else
|
||||
mask->exec_mask = mask->cond_mask;
|
||||
|
||||
|
||||
mask->has_mask = (mask->cond_stack_size > 0 ||
|
||||
mask->loop_stack_size > 0);
|
||||
}
|
||||
|
||||
static void lp_exec_mask_cond_push(struct lp_exec_mask *mask,
|
||||
|
@ -189,6 +221,102 @@ static void lp_exec_mask_cond_pop(struct lp_exec_mask *mask)
|
|||
lp_exec_mask_update(mask);
|
||||
}
|
||||
|
||||
static void lp_exec_bgnloop(struct lp_exec_mask *mask)
|
||||
{
|
||||
|
||||
if (mask->cont_stack_size == 0)
|
||||
mask->cont_mask = LLVMConstAllOnes(mask->int_vec_type);
|
||||
if (mask->cont_stack_size == 0)
|
||||
mask->break_mask = LLVMConstAllOnes(mask->int_vec_type);
|
||||
if (mask->cond_stack_size == 0)
|
||||
mask->cond_mask = LLVMConstAllOnes(mask->int_vec_type);
|
||||
mask->loop_stack[mask->loop_stack_size++] = mask->loop_block;
|
||||
mask->loop_block = lp_build_insert_new_block(mask->bld->builder, "bgnloop");
|
||||
LLVMBuildBr(mask->bld->builder, mask->loop_block);
|
||||
LLVMPositionBuilderAtEnd(mask->bld->builder, mask->loop_block);
|
||||
|
||||
lp_exec_mask_update(mask);
|
||||
}
|
||||
|
||||
static void lp_exec_break(struct lp_exec_mask *mask)
|
||||
{
|
||||
LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder,
|
||||
mask->exec_mask,
|
||||
"break");
|
||||
|
||||
mask->break_stack[mask->break_stack_size++] = mask->break_mask;
|
||||
if (mask->break_stack_size > 1) {
|
||||
mask->break_mask = LLVMBuildAnd(mask->bld->builder,
|
||||
mask->break_mask,
|
||||
exec_mask, "break_full");
|
||||
} else
|
||||
mask->break_mask = exec_mask;
|
||||
|
||||
lp_exec_mask_update(mask);
|
||||
}
|
||||
|
||||
static void lp_exec_continue(struct lp_exec_mask *mask)
|
||||
{
|
||||
LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder,
|
||||
mask->exec_mask,
|
||||
"");
|
||||
|
||||
mask->cont_stack[mask->cont_stack_size++] = mask->cont_mask;
|
||||
if (mask->cont_stack_size > 1) {
|
||||
mask->cont_mask = LLVMBuildAnd(mask->bld->builder,
|
||||
mask->cont_mask,
|
||||
exec_mask, "");
|
||||
} else
|
||||
mask->cont_mask = exec_mask;
|
||||
|
||||
lp_exec_mask_update(mask);
|
||||
}
|
||||
|
||||
|
||||
static void lp_exec_endloop(struct lp_exec_mask *mask)
|
||||
{
|
||||
LLVMBasicBlockRef endloop;
|
||||
LLVMValueRef i1cond;
|
||||
|
||||
{ /* convert our soa vector into i1 */
|
||||
int i;
|
||||
LLVMValueRef packed = 0;
|
||||
for (i = 0; i < mask->bld->type.length; ++i) {
|
||||
LLVMValueRef component = LLVMBuildExtractElement(
|
||||
mask->bld->builder,
|
||||
mask->break_mask,
|
||||
LLVMConstInt(LLVMInt32Type(), i, 0), "");
|
||||
if (packed)
|
||||
packed = LLVMBuildOr(mask->bld->builder,
|
||||
packed, component, "");
|
||||
else
|
||||
packed = component;
|
||||
}
|
||||
i1cond = LLVMBuildICmp(mask->bld->builder, LLVMIntNE,
|
||||
packed,
|
||||
LLVMConstNull(LLVMTypeOf(packed)),
|
||||
"");
|
||||
}
|
||||
|
||||
endloop = lp_build_insert_new_block(mask->bld->builder, "endloop");
|
||||
|
||||
LLVMBuildCondBr(mask->bld->builder,
|
||||
i1cond, endloop, mask->loop_block);
|
||||
|
||||
LLVMPositionBuilderAtEnd(mask->bld->builder, endloop);
|
||||
|
||||
mask->loop_block = mask->loop_stack[--mask->loop_stack_size];
|
||||
/* pop the break mask */
|
||||
if (mask->cont_stack_size) {
|
||||
mask->cont_mask = mask->cont_stack[--mask->cont_stack_size];
|
||||
}
|
||||
if (mask->break_stack_size) {
|
||||
mask->break_mask = mask->cont_stack[--mask->break_stack_size];
|
||||
}
|
||||
|
||||
lp_exec_mask_update(mask);
|
||||
}
|
||||
|
||||
static void lp_exec_mask_store(struct lp_exec_mask *mask,
|
||||
LLVMValueRef val,
|
||||
LLVMValueRef dst)
|
||||
|
@ -1363,10 +1491,9 @@ emit_instruction(
|
|||
case TGSI_OPCODE_TXP:
|
||||
emit_tex( bld, inst, FALSE, TRUE, dst0 );
|
||||
break;
|
||||
|
||||
|
||||
case TGSI_OPCODE_BRK:
|
||||
/* FIXME */
|
||||
return 0;
|
||||
lp_exec_break(&bld->exec_mask);
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_IF:
|
||||
|
@ -1380,6 +1507,10 @@ emit_instruction(
|
|||
return 0;
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_BGNLOOP:
|
||||
lp_exec_bgnloop(&bld->exec_mask);
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_REP:
|
||||
/* deprecated */
|
||||
assert(0);
|
||||
|
@ -1400,6 +1531,10 @@ emit_instruction(
|
|||
return 0;
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_ENDLOOP:
|
||||
lp_exec_endloop(&bld->exec_mask);
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_ENDREP:
|
||||
/* deprecated */
|
||||
assert(0);
|
||||
|
@ -1499,8 +1634,7 @@ emit_instruction(
|
|||
break;
|
||||
|
||||
case TGSI_OPCODE_CONT:
|
||||
/* FIXME */
|
||||
return 0;
|
||||
lp_exec_continue(&bld->exec_mask);
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_EMIT:
|
||||
|
@ -1603,7 +1737,14 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
|
|||
assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if (0) {
|
||||
LLVMBasicBlockRef block = LLVMGetInsertBlock(builder);
|
||||
LLVMValueRef function = LLVMGetBasicBlockParent(block);
|
||||
debug_printf("11111111111111111111111111111 \n");
|
||||
tgsi_dump(tokens, 0);
|
||||
LLVMDumpValue(function);
|
||||
debug_printf("2222222222222222222222222222 \n");
|
||||
}
|
||||
tgsi_parse_free( &parse );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue