bld->zero = LLVMConstNull(bld->vec_type);
bld->one = lp_build_one(gallivm, type);
}
+
+
+/**
+ * Count the number of instructions in a function.
+ */
+unsigned
+lp_build_count_instructions(LLVMValueRef function)
+{
+ unsigned num_instrs = 0;
+ LLVMBasicBlockRef block;
+
+ block = LLVMGetFirstBasicBlock(function);
+ while (block) {
+ LLVMValueRef instr;
+ instr = LLVMGetFirstInstruction(block);
+ while (instr) {
+ ++num_instrs;
+
+ instr = LLVMGetNextInstruction(instr);
+ }
+ block = LLVMGetNextBasicBlock(block);
+ }
+
+ return num_instrs;
+}
LLVMWriteBitcodeToFile(gallivm->module, "llvmpipe.bc");
}
+ variant->nr_instrs += lp_build_count_instructions(function);
/*
* Translate the LLVM IR into machine code.
*/
/* remove from context's list */
remove_from_list(&variant->list_item_global);
lp->nr_fs_variants--;
+ lp->nr_fs_instrs -= variant->nr_instrs;
FREE(variant);
}
/* variant not found, create it now */
int64_t t0, t1, dt;
unsigned i;
+ unsigned variants_to_cull;
+
+ if (0) {
+ debug_printf("%u variants,\t%u instrs,\t%u instrs/variant\n",
+ lp->nr_fs_variants,
+ lp->nr_fs_instrs,
+ lp->nr_fs_variants ? lp->nr_fs_instrs / lp->nr_fs_variants : 0);
+ }
/* First, check if we've exceeded the max number of shader variants.
* If so, free 25% of them (the least recently used ones).
*/
- if (lp->nr_fs_variants >= LP_MAX_SHADER_VARIANTS) {
+ variants_to_cull = lp->nr_fs_variants >= LP_MAX_SHADER_VARIANTS ? LP_MAX_SHADER_VARIANTS / 4 : 0;
+
+ if (variants_to_cull ||
+ lp->nr_fs_instrs >= LP_MAX_SHADER_INSTRUCTIONS) {
struct pipe_context *pipe = &lp->pipe;
/*
* pending for destruction on flush.
*/
- if (lp->nr_fs_variants >= LP_MAX_SHADER_VARIANTS) {
- for (i = 0; i < LP_MAX_SHADER_VARIANTS / 4; i++) {
- struct lp_fs_variant_list_item *item;
- if (is_empty_list(&lp->fs_variants_list)) {
- break;
- }
- item = last_elem(&lp->fs_variants_list);
- assert(item);
- assert(item->base);
- llvmpipe_remove_shader_variant(lp, item->base);
+ for (i = 0; i < variants_to_cull || lp->nr_fs_instrs >= LP_MAX_SHADER_INSTRUCTIONS; i++) {
+ struct lp_fs_variant_list_item *item;
+ if (is_empty_list(&lp->fs_variants_list)) {
+ break;
}
+ item = last_elem(&lp->fs_variants_list);
+ assert(item);
+ assert(item->base);
+ llvmpipe_remove_shader_variant(lp, item->base);
}
}
insert_at_head(&shader->variants, &variant->list_item_local);
insert_at_head(&lp->fs_variants_list, &variant->list_item_global);
lp->nr_fs_variants++;
+ lp->nr_fs_instrs += variant->nr_instrs;
shader->variants_cached++;
}
}