X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Floop_unroll.cpp;h=3434fde62926026b8a0d9bbf8aab07bebcd75c7f;hb=1fafd008392d5240dc36d0c72978cef62e21b4b1;hp=46000524ba105fdc56358d32261b44dc952711d5;hpb=772b25e1f366edc857e77b8c1ccdc5297d82cc41;p=mesa.git diff --git a/src/glsl/loop_unroll.cpp b/src/glsl/loop_unroll.cpp index 46000524ba1..3434fde6292 100644 --- a/src/glsl/loop_unroll.cpp +++ b/src/glsl/loop_unroll.cpp @@ -50,6 +50,38 @@ is_break(ir_instruction *ir) && ((ir_loop_jump *) ir)->is_break(); } +class loop_unroll_count : public ir_hierarchical_visitor { +public: + int nodes; + bool fail; + + loop_unroll_count(exec_list *list) + { + nodes = 0; + fail = false; + + run(list); + } + + virtual ir_visitor_status visit_enter(ir_assignment *ir) + { + nodes++; + return visit_continue; + } + + virtual ir_visitor_status visit_enter(ir_expression *ir) + { + nodes++; + return visit_continue; + } + + virtual ir_visitor_status visit_enter(ir_loop *ir) + { + fail = true; + return visit_continue; + } +}; + ir_visitor_status loop_unroll_visitor::visit_leave(ir_loop *ir) @@ -78,6 +110,13 @@ loop_unroll_visitor::visit_leave(ir_loop *ir) if (iterations > (int) max_iterations) return visit_continue; + /* Don't try to unroll nested loops and loops with a huge body. + */ + loop_unroll_count count(&ir->body_instructions); + + if (count.fail || count.nodes * iterations > (int)max_iterations * 5) + return visit_continue; + if (ls->num_loop_jumps > 1) return visit_continue; else if (ls->num_loop_jumps) { @@ -150,7 +189,7 @@ loop_unroll_visitor::visit_leave(ir_loop *ir) */ break_ir->remove(); - void *const mem_ctx = talloc_parent(ir); + void *const mem_ctx = ralloc_parent(ir); ir_instruction *ir_to_replace = ir; for (int i = 0; i < iterations; i++) { @@ -182,7 +221,7 @@ loop_unroll_visitor::visit_leave(ir_loop *ir) } } - void *const mem_ctx = talloc_parent(ir); + void *const mem_ctx = ralloc_parent(ir); for (int i = 0; i < iterations; i++) { exec_list copy_list;