mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-01 19:50:25 +01:00
gallivm: Simplify if/then/else implementation.
No need for for a flow stack anymore.
This commit is contained in:
parent
1949f8c315
commit
d0ea464159
5 changed files with 34 additions and 91 deletions
|
|
@ -61,23 +61,12 @@ struct lp_build_flow_skip
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* if/else/endif.
|
||||
*/
|
||||
struct lp_build_flow_if
|
||||
{
|
||||
LLVMValueRef condition;
|
||||
LLVMBasicBlockRef entry_block, true_block, false_block, merge_block;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Union of all possible flow constructs' data
|
||||
*/
|
||||
union lp_build_flow_construct_data
|
||||
{
|
||||
struct lp_build_flow_skip skip;
|
||||
struct lp_build_flow_if ifthen;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -468,24 +457,16 @@ lp_build_loop_end_cond(LLVMBuilderRef builder,
|
|||
|
||||
Is built with:
|
||||
|
||||
LLVMValueRef x = LLVMGetUndef(); // or something else
|
||||
// x needs an alloca variable
|
||||
x = lp_build_alloca(builder, type, "x");
|
||||
|
||||
flow = lp_build_flow_create(builder);
|
||||
|
||||
lp_build_flow_scope_begin(flow);
|
||||
lp_build_if(ctx, builder, cond);
|
||||
LLVMBuildStore(LLVMBuildAdd(1, 2), x);
|
||||
lp_build_else(ctx);
|
||||
LLVMBuildStore(LLVMBuildAdd(2, 3). x);
|
||||
lp_build_endif(ctx);
|
||||
|
||||
// x needs a phi node
|
||||
lp_build_flow_scope_declare(flow, &x);
|
||||
|
||||
lp_build_if(ctx, flow, builder, cond);
|
||||
x = LLVMAdd(1, 2);
|
||||
lp_build_else(ctx);
|
||||
x = LLVMAdd(2, 3);
|
||||
lp_build_endif(ctx);
|
||||
|
||||
lp_build_flow_scope_end(flow);
|
||||
|
||||
lp_build_flow_destroy(flow);
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -494,22 +475,14 @@ lp_build_loop_end_cond(LLVMBuilderRef builder,
|
|||
* Begin an if/else/endif construct.
|
||||
*/
|
||||
void
|
||||
lp_build_if(struct lp_build_if_state *ctx,
|
||||
struct lp_build_flow_context *flow,
|
||||
lp_build_if(struct lp_build_if_state *ifthen,
|
||||
LLVMBuilderRef builder,
|
||||
LLVMValueRef condition)
|
||||
{
|
||||
LLVMBasicBlockRef block = LLVMGetInsertBlock(builder);
|
||||
struct lp_build_flow_if *ifthen;
|
||||
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
ctx->builder = builder;
|
||||
ctx->flow = flow;
|
||||
|
||||
/* push/create new scope */
|
||||
ifthen = &lp_build_flow_push(flow, LP_BUILD_FLOW_IF)->ifthen;
|
||||
assert(ifthen);
|
||||
|
||||
memset(ifthen, 0, sizeof *ifthen);
|
||||
ifthen->builder = builder;
|
||||
ifthen->condition = condition;
|
||||
ifthen->entry_block = block;
|
||||
|
||||
|
|
@ -529,19 +502,13 @@ lp_build_if(struct lp_build_if_state *ctx,
|
|||
* Begin else-part of a conditional
|
||||
*/
|
||||
void
|
||||
lp_build_else(struct lp_build_if_state *ctx)
|
||||
lp_build_else(struct lp_build_if_state *ifthen)
|
||||
{
|
||||
struct lp_build_flow_context *flow = ctx->flow;
|
||||
struct lp_build_flow_if *ifthen;
|
||||
|
||||
ifthen = &lp_build_flow_peek(flow, LP_BUILD_FLOW_IF)->ifthen;
|
||||
assert(ifthen);
|
||||
|
||||
/* create/insert false_block before the merge block */
|
||||
ifthen->false_block = LLVMInsertBasicBlock(ifthen->merge_block, "if-false-block");
|
||||
|
||||
/* successive code goes into the else block */
|
||||
LLVMPositionBuilderAtEnd(ctx->builder, ifthen->false_block);
|
||||
LLVMPositionBuilderAtEnd(ifthen->builder, ifthen->false_block);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -549,39 +516,33 @@ lp_build_else(struct lp_build_if_state *ctx)
|
|||
* End a conditional.
|
||||
*/
|
||||
void
|
||||
lp_build_endif(struct lp_build_if_state *ctx)
|
||||
lp_build_endif(struct lp_build_if_state *ifthen)
|
||||
{
|
||||
struct lp_build_flow_context *flow = ctx->flow;
|
||||
struct lp_build_flow_if *ifthen;
|
||||
|
||||
ifthen = &lp_build_flow_pop(flow, LP_BUILD_FLOW_IF)->ifthen;
|
||||
assert(ifthen);
|
||||
|
||||
/* Insert branch to the merge block from current block */
|
||||
LLVMBuildBr(ctx->builder, ifthen->merge_block);
|
||||
LLVMBuildBr(ifthen->builder, ifthen->merge_block);
|
||||
|
||||
/***
|
||||
*** Now patch in the various branch instructions.
|
||||
***/
|
||||
|
||||
/* Insert the conditional branch instruction at the end of entry_block */
|
||||
LLVMPositionBuilderAtEnd(ctx->builder, ifthen->entry_block);
|
||||
LLVMPositionBuilderAtEnd(ifthen->builder, ifthen->entry_block);
|
||||
if (ifthen->false_block) {
|
||||
/* we have an else clause */
|
||||
LLVMBuildCondBr(ctx->builder, ifthen->condition,
|
||||
LLVMBuildCondBr(ifthen->builder, ifthen->condition,
|
||||
ifthen->true_block, ifthen->false_block);
|
||||
}
|
||||
else {
|
||||
/* no else clause */
|
||||
LLVMBuildCondBr(ctx->builder, ifthen->condition,
|
||||
LLVMBuildCondBr(ifthen->builder, ifthen->condition,
|
||||
ifthen->true_block, ifthen->merge_block);
|
||||
}
|
||||
|
||||
/* Insert branch from end of true_block to merge_block */
|
||||
if (ifthen->false_block) {
|
||||
/* Append an unconditional Br(anch) instruction on the true_block */
|
||||
LLVMPositionBuilderAtEnd(ctx->builder, ifthen->true_block);
|
||||
LLVMBuildBr(ctx->builder, ifthen->merge_block);
|
||||
LLVMPositionBuilderAtEnd(ifthen->builder, ifthen->true_block);
|
||||
LLVMBuildBr(ifthen->builder, ifthen->merge_block);
|
||||
}
|
||||
else {
|
||||
/* No else clause.
|
||||
|
|
@ -591,7 +552,7 @@ lp_build_endif(struct lp_build_if_state *ctx)
|
|||
}
|
||||
|
||||
/* Resume building code at end of the ifthen->merge_block */
|
||||
LLVMPositionBuilderAtEnd(ctx->builder, ifthen->merge_block);
|
||||
LLVMPositionBuilderAtEnd(ifthen->builder, ifthen->merge_block);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -130,16 +130,22 @@ lp_build_loop_end_cond(LLVMBuilderRef builder,
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* if/else/endif.
|
||||
*/
|
||||
struct lp_build_if_state
|
||||
{
|
||||
LLVMBuilderRef builder;
|
||||
struct lp_build_flow_context *flow;
|
||||
LLVMValueRef condition;
|
||||
LLVMBasicBlockRef entry_block;
|
||||
LLVMBasicBlockRef true_block;
|
||||
LLVMBasicBlockRef false_block;
|
||||
LLVMBasicBlockRef merge_block;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
lp_build_if(struct lp_build_if_state *ctx,
|
||||
struct lp_build_flow_context *flow,
|
||||
LLVMBuilderRef builder,
|
||||
LLVMValueRef condition);
|
||||
|
||||
|
|
|
|||
|
|
@ -925,19 +925,16 @@ lp_build_cube_lookup(struct lp_build_sample_context *bld,
|
|||
rz_pos = LLVMBuildFCmp(bld->builder, LLVMRealUGE, rz, float_bld->zero, "");
|
||||
|
||||
{
|
||||
struct lp_build_flow_context *flow_ctx;
|
||||
struct lp_build_if_state if_ctx;
|
||||
LLVMValueRef face_s_var;
|
||||
LLVMValueRef face_t_var;
|
||||
LLVMValueRef face_var;
|
||||
|
||||
flow_ctx = lp_build_flow_create(bld->builder);
|
||||
|
||||
face_s_var = lp_build_alloca(bld->builder, bld->coord_bld.vec_type, "face_s_var");
|
||||
face_t_var = lp_build_alloca(bld->builder, bld->coord_bld.vec_type, "face_t_var");
|
||||
face_var = lp_build_alloca(bld->builder, bld->int_bld.vec_type, "face_var");
|
||||
|
||||
lp_build_if(&if_ctx, flow_ctx, bld->builder, arx_ge_ary_arz);
|
||||
lp_build_if(&if_ctx, bld->builder, arx_ge_ary_arz);
|
||||
{
|
||||
/* +/- X face */
|
||||
LLVMValueRef sign = lp_build_sgn(float_bld, rx);
|
||||
|
|
@ -957,7 +954,7 @@ lp_build_cube_lookup(struct lp_build_sample_context *bld,
|
|||
|
||||
ary_ge_arx_arz = LLVMBuildAnd(bld->builder, ary_ge_arx, ary_ge_arz, "");
|
||||
|
||||
lp_build_if(&if_ctx2, flow_ctx, bld->builder, ary_ge_arx_arz);
|
||||
lp_build_if(&if_ctx2, bld->builder, ary_ge_arx_arz);
|
||||
{
|
||||
/* +/- Y face */
|
||||
LLVMValueRef sign = lp_build_sgn(float_bld, ry);
|
||||
|
|
@ -989,7 +986,6 @@ lp_build_cube_lookup(struct lp_build_sample_context *bld,
|
|||
}
|
||||
|
||||
lp_build_endif(&if_ctx);
|
||||
lp_build_flow_destroy(flow_ctx);
|
||||
|
||||
*face_s = LLVMBuildLoad(bld->builder, face_s_var, "face_s");
|
||||
*face_t = LLVMBuildLoad(bld->builder, face_t_var, "face_t");
|
||||
|
|
|
|||
|
|
@ -833,12 +833,9 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
|
|||
if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
|
||||
LLVMValueRef h16_scale = LLVMConstReal(LLVMFloatType(), 256.0);
|
||||
LLVMTypeRef i32_type = LLVMIntType(32);
|
||||
struct lp_build_flow_context *flow_ctx;
|
||||
struct lp_build_if_state if_ctx;
|
||||
LLVMValueRef need_lerp;
|
||||
|
||||
flow_ctx = lp_build_flow_create(builder);
|
||||
|
||||
lod_fpart = LLVMBuildFMul(builder, lod_fpart, h16_scale, "");
|
||||
lod_fpart = LLVMBuildFPToSI(builder, lod_fpart, i32_type, "lod_fpart.fixed16");
|
||||
|
||||
|
|
@ -847,7 +844,7 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
|
|||
lod_fpart, LLVMConstNull(i32_type),
|
||||
"need_lerp");
|
||||
|
||||
lp_build_if(&if_ctx, flow_ctx, builder, need_lerp);
|
||||
lp_build_if(&if_ctx, builder, need_lerp);
|
||||
{
|
||||
struct lp_build_context h16_bld;
|
||||
|
||||
|
|
@ -887,8 +884,6 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
|
|||
LLVMBuildStore(builder, colors0_hi, colors_hi_var);
|
||||
}
|
||||
lp_build_endif(&if_ctx);
|
||||
|
||||
lp_build_flow_destroy(flow_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1028,17 +1023,14 @@ lp_build_sample_aos(struct lp_build_sample_context *bld,
|
|||
/* Emit conditional to choose min image filter or mag image filter
|
||||
* depending on the lod being > 0 or <= 0, respectively.
|
||||
*/
|
||||
struct lp_build_flow_context *flow_ctx;
|
||||
struct lp_build_if_state if_ctx;
|
||||
LLVMValueRef minify;
|
||||
|
||||
flow_ctx = lp_build_flow_create(builder);
|
||||
|
||||
/* minify = lod >= 0.0 */
|
||||
minify = LLVMBuildICmp(builder, LLVMIntSGE,
|
||||
lod_ipart, int_bld->zero, "");
|
||||
|
||||
lp_build_if(&if_ctx, flow_ctx, builder, minify);
|
||||
lp_build_if(&if_ctx, builder, minify);
|
||||
{
|
||||
/* Use the minification filter */
|
||||
lp_build_sample_mipmap(bld,
|
||||
|
|
@ -1057,8 +1049,6 @@ lp_build_sample_aos(struct lp_build_sample_context *bld,
|
|||
packed_lo, packed_hi);
|
||||
}
|
||||
lp_build_endif(&if_ctx);
|
||||
|
||||
lp_build_flow_destroy(flow_ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -881,19 +881,16 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
|
|||
}
|
||||
|
||||
if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
|
||||
struct lp_build_flow_context *flow_ctx;
|
||||
struct lp_build_if_state if_ctx;
|
||||
LLVMValueRef need_lerp;
|
||||
|
||||
flow_ctx = lp_build_flow_create(builder);
|
||||
|
||||
/* need_lerp = lod_fpart > 0 */
|
||||
need_lerp = LLVMBuildFCmp(builder, LLVMRealUGT,
|
||||
lod_fpart,
|
||||
bld->float_bld.zero,
|
||||
"need_lerp");
|
||||
|
||||
lp_build_if(&if_ctx, flow_ctx, builder, need_lerp);
|
||||
lp_build_if(&if_ctx, builder, need_lerp);
|
||||
{
|
||||
/* sample the second mipmap level */
|
||||
lp_build_mipmap_level_sizes(bld, ilevel1,
|
||||
|
|
@ -926,8 +923,6 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
|
|||
}
|
||||
}
|
||||
lp_build_endif(&if_ctx);
|
||||
|
||||
lp_build_flow_destroy(flow_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1063,17 +1058,14 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
|
|||
/* Emit conditional to choose min image filter or mag image filter
|
||||
* depending on the lod being > 0 or <= 0, respectively.
|
||||
*/
|
||||
struct lp_build_flow_context *flow_ctx;
|
||||
struct lp_build_if_state if_ctx;
|
||||
LLVMValueRef minify;
|
||||
|
||||
flow_ctx = lp_build_flow_create(builder);
|
||||
|
||||
/* minify = lod >= 0.0 */
|
||||
minify = LLVMBuildICmp(builder, LLVMIntSGE,
|
||||
lod_ipart, int_bld->zero, "");
|
||||
|
||||
lp_build_if(&if_ctx, flow_ctx, builder, minify);
|
||||
lp_build_if(&if_ctx, builder, minify);
|
||||
{
|
||||
/* Use the minification filter */
|
||||
lp_build_sample_mipmap(bld, unit,
|
||||
|
|
@ -1092,8 +1084,6 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
|
|||
texels);
|
||||
}
|
||||
lp_build_endif(&if_ctx);
|
||||
|
||||
lp_build_flow_destroy(flow_ctx);
|
||||
}
|
||||
|
||||
for (chan = 0; chan < 4; ++chan) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue