Clone of mesa.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

loop_controls.cpp 8.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /*
  2. * Copyright © 2010 Intel Corporation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice (including the next
  12. * paragraph) shall be included in all copies or substantial portions of the
  13. * Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  18. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  21. * DEALINGS IN THE SOFTWARE.
  22. */
  23. #include <climits>
  24. #include "main/compiler.h"
  25. #include "glsl_types.h"
  26. #include "loop_analysis.h"
  27. #include "ir_hierarchical_visitor.h"
  28. /**
  29. * Find an initializer of a variable outside a loop
  30. *
  31. * Works backwards from the loop to find the pre-loop value of the variable.
  32. * This is used, for example, to find the initial value of loop induction
  33. * variables.
  34. *
  35. * \param loop Loop where \c var is an induction variable
  36. * \param var Variable whose initializer is to be found
  37. *
  38. * \return
  39. * The \c ir_rvalue assigned to the variable outside the loop. May return
  40. * \c NULL if no initializer can be found.
  41. */
  42. ir_rvalue *
  43. find_initial_value(ir_loop *loop, ir_variable *var)
  44. {
  45. for (exec_node *node = loop->prev;
  46. !node->is_head_sentinel();
  47. node = node->prev) {
  48. ir_instruction *ir = (ir_instruction *) node;
  49. switch (ir->ir_type) {
  50. case ir_type_call:
  51. case ir_type_loop:
  52. case ir_type_loop_jump:
  53. case ir_type_return:
  54. case ir_type_if:
  55. return NULL;
  56. case ir_type_function:
  57. case ir_type_function_signature:
  58. assert(!"Should not get here.");
  59. return NULL;
  60. case ir_type_assignment: {
  61. ir_assignment *assign = ir->as_assignment();
  62. ir_variable *assignee = assign->lhs->whole_variable_referenced();
  63. if (assignee == var)
  64. return (assign->condition != NULL) ? NULL : assign->rhs;
  65. break;
  66. }
  67. default:
  68. break;
  69. }
  70. }
  71. return NULL;
  72. }
  73. int
  74. calculate_iterations(ir_rvalue *from, ir_rvalue *to, ir_rvalue *increment,
  75. enum ir_expression_operation op)
  76. {
  77. if (from == NULL || to == NULL || increment == NULL)
  78. return -1;
  79. void *mem_ctx = talloc_init("%s", __func__);
  80. ir_expression *const sub =
  81. new(mem_ctx) ir_expression(ir_binop_sub, from->type, to, from);
  82. ir_expression *const div =
  83. new(mem_ctx) ir_expression(ir_binop_div, sub->type, sub, increment);
  84. ir_constant *iter = div->constant_expression_value();
  85. if (iter == NULL)
  86. return -1;
  87. if (!iter->type->is_integer()) {
  88. ir_rvalue *cast =
  89. new(mem_ctx) ir_expression(ir_unop_f2i, glsl_type::int_type, iter,
  90. NULL);
  91. iter = cast->constant_expression_value();
  92. }
  93. int iter_value = iter->get_int_component(0);
  94. /* Make sure that the calculated number of iterations satisfies the exit
  95. * condition. This is needed to catch off-by-one errors and some types of
  96. * ill-formed loops. For example, we need to detect that the following
  97. * loop does not have a maximum iteration count.
  98. *
  99. * for (float x = 0.0; x != 0.9; x += 0.2)
  100. * ;
  101. */
  102. const int bias[] = { -1, 0, 1 };
  103. bool valid_loop = false;
  104. for (unsigned i = 0; i < Elements(bias); i++) {
  105. iter = (increment->type->is_integer())
  106. ? new(mem_ctx) ir_constant(iter_value + bias[i])
  107. : new(mem_ctx) ir_constant(float(iter_value + bias[i]));
  108. ir_expression *const mul =
  109. new(mem_ctx) ir_expression(ir_binop_mul, increment->type, iter,
  110. increment);
  111. ir_expression *const add =
  112. new(mem_ctx) ir_expression(ir_binop_add, mul->type, mul, from);
  113. ir_expression *const cmp =
  114. new(mem_ctx) ir_expression(op, glsl_type::bool_type, add, to);
  115. ir_constant *const cmp_result = cmp->constant_expression_value();
  116. assert(cmp_result != NULL);
  117. if (cmp_result->get_bool_component(0)) {
  118. iter_value += bias[i];
  119. valid_loop = true;
  120. break;
  121. }
  122. }
  123. talloc_free(mem_ctx);
  124. return (valid_loop) ? iter_value : -1;
  125. }
  126. class loop_control_visitor : public ir_hierarchical_visitor {
  127. public:
  128. loop_control_visitor(loop_state *state)
  129. {
  130. this->state = state;
  131. this->progress = false;
  132. }
  133. virtual ir_visitor_status visit_leave(ir_loop *ir);
  134. loop_state *state;
  135. bool progress;
  136. };
  137. ir_visitor_status
  138. loop_control_visitor::visit_leave(ir_loop *ir)
  139. {
  140. loop_variable_state *const ls = this->state->get(ir);
  141. /* If we've entered a loop that hasn't been analyzed, something really,
  142. * really bad has happened.
  143. */
  144. if (ls == NULL) {
  145. assert(ls != NULL);
  146. return visit_continue;
  147. }
  148. /* Search the loop terminating conditions for one of the form 'i < c' where
  149. * i is a loop induction variable, c is a constant, and < is any relative
  150. * operator.
  151. */
  152. int max_iterations = ls->max_iterations;
  153. if(ir->from && ir->to && ir->increment)
  154. max_iterations = calculate_iterations(ir->from, ir->to, ir->increment, (ir_expression_operation)ir->cmp);
  155. if(max_iterations < 0)
  156. max_iterations = INT_MAX;
  157. foreach_list(node, &ls->terminators) {
  158. loop_terminator *t = (loop_terminator *) node;
  159. ir_if *if_stmt = t->ir;
  160. /* If-statements can be either 'if (expr)' or 'if (deref)'. We only care
  161. * about the former here.
  162. */
  163. ir_expression *cond = if_stmt->condition->as_expression();
  164. if (cond == NULL)
  165. continue;
  166. switch (cond->operation) {
  167. case ir_binop_less:
  168. case ir_binop_greater:
  169. case ir_binop_lequal:
  170. case ir_binop_gequal: {
  171. /* The expressions that we care about will either be of the form
  172. * 'counter < limit' or 'limit < counter'. Figure out which is
  173. * which.
  174. */
  175. ir_rvalue *counter = cond->operands[0]->as_dereference_variable();
  176. ir_constant *limit = cond->operands[1]->as_constant();
  177. enum ir_expression_operation cmp = cond->operation;
  178. if (limit == NULL) {
  179. counter = cond->operands[1]->as_dereference_variable();
  180. limit = cond->operands[0]->as_constant();
  181. switch (cmp) {
  182. case ir_binop_less: cmp = ir_binop_gequal; break;
  183. case ir_binop_greater: cmp = ir_binop_lequal; break;
  184. case ir_binop_lequal: cmp = ir_binop_greater; break;
  185. case ir_binop_gequal: cmp = ir_binop_less; break;
  186. default: assert(!"Should not get here.");
  187. }
  188. }
  189. if ((counter == NULL) || (limit == NULL))
  190. break;
  191. ir_variable *var = counter->variable_referenced();
  192. ir_rvalue *init = find_initial_value(ir, var);
  193. foreach_list(iv_node, &ls->induction_variables) {
  194. loop_variable *lv = (loop_variable *) iv_node;
  195. if (lv->var == var) {
  196. const int iterations = calculate_iterations(init, limit,
  197. lv->increment,
  198. cmp);
  199. if (iterations >= 0) {
  200. /* If the new iteration count is lower than the previously
  201. * believed iteration count, update the loop control values.
  202. */
  203. if (iterations < max_iterations) {
  204. ir->from = init->clone(ir, NULL);
  205. ir->to = limit->clone(ir, NULL);
  206. ir->increment = lv->increment->clone(ir, NULL);
  207. ir->counter = lv->var;
  208. ir->cmp = cmp;
  209. max_iterations = iterations;
  210. }
  211. /* Remove the conditional break statement. The loop
  212. * controls are now set such that the exit condition will be
  213. * satisfied.
  214. */
  215. if_stmt->remove();
  216. assert(ls->num_loop_jumps > 0);
  217. ls->num_loop_jumps--;
  218. this->progress = true;
  219. }
  220. break;
  221. }
  222. }
  223. break;
  224. }
  225. default:
  226. break;
  227. }
  228. }
  229. /* If we have proven the one of the loop exit conditions is satisifed before
  230. * running the loop once, remove the loop.
  231. */
  232. if (max_iterations == 0)
  233. ir->remove();
  234. else
  235. ls->max_iterations = max_iterations;
  236. return visit_continue;
  237. }
  238. bool
  239. set_loop_controls(exec_list *instructions, loop_state *ls)
  240. {
  241. loop_control_visitor v(ls);
  242. v.run(instructions);
  243. return v.progress;
  244. }