OSDN Git Service

glsl: Remove ir_binop_greater and ir_binop_lequal expressions
authorIan Romanick <ian.d.romanick@intel.com>
Fri, 8 May 2015 19:55:00 +0000 (12:55 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Mon, 30 Oct 2017 16:27:09 +0000 (09:27 -0700)
NIR does not have these instructions.  TGSI and Mesa IR both implement
them using < and >=, repsectively.  Removing them deletes a bunch of
code and means I don't have to add code to the SPIR-V generator for
them.

v2: Rebase on 2+ years of change... and fix a major bug added in the
rebase.

   text    data     bss     dec     hex filename
8255291  268856  294072 8818219  868e2b 32-bit i965_dri.so before
8254235  268856  294072 8817163  868a0b 32-bit i965_dri.so after
7815339  345592  420592 8581523  82f193 64-bit i965_dri.so before
7813995  345560  420592 8580147  82ec33 64-bit i965_dri.so after

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
14 files changed:
src/compiler/glsl/ast_to_hir.cpp
src/compiler/glsl/builtin_functions.cpp
src/compiler/glsl/glsl_to_nir.cpp
src/compiler/glsl/ir.cpp
src/compiler/glsl/ir_builder.cpp
src/compiler/glsl/ir_builder_print_visitor.cpp
src/compiler/glsl/ir_expression_operation.py
src/compiler/glsl/ir_validate.cpp
src/compiler/glsl/loop_analysis.cpp
src/compiler/glsl/opt_algebraic.cpp
src/compiler/glsl/tests/lower_jumps/create_test_cases.py
src/intel/compiler/brw_shader.cpp
src/mesa/program/ir_to_mesa.cpp
src/mesa/state_tracker/st_glsl_to_tgsi.cpp

index 6090ee9..441404f 100644 (file)
@@ -1337,8 +1337,8 @@ ast_expression::do_hir(exec_list *instructions,
       ir_binop_lshift,
       ir_binop_rshift,
       ir_binop_less,
-      ir_binop_greater,
-      ir_binop_lequal,
+      ir_binop_less,    /* This is correct.  See the ast_greater case below. */
+      ir_binop_gequal,  /* This is correct.  See the ast_lequal case below. */
       ir_binop_gequal,
       ir_binop_all_equal,
       ir_binop_any_nequal,
@@ -1487,6 +1487,15 @@ ast_expression::do_hir(exec_list *instructions,
       assert(type->is_error()
              || (type->is_boolean() && type->is_scalar()));
 
+      /* Like NIR, GLSL IR does not have opcodes for > or <=.  Instead, swap
+       * the arguments and use < or >=.
+       */
+      if (this->oper == ast_greater || this->oper == ast_lequal) {
+         ir_rvalue *const tmp = op[0];
+         op[0] = op[1];
+         op[1] = tmp;
+      }
+
       result = new(ctx) ir_expression(operations[this->oper], type,
                                       op[0], op[1]);
       error_emitted = type->is_error();
index 9df9671..530cdc0 100644 (file)
@@ -744,7 +744,8 @@ private:
                                 ir_expression_operation opcode,
                                 const glsl_type *return_type,
                                 const glsl_type *param0_type,
-                                const glsl_type *param1_type);
+                                const glsl_type *param1_type,
+                                bool swap_operands = false);
 
 #define B0(X) ir_function_signature *_##X();
 #define B1(X) ir_function_signature *_##X(const glsl_type *);
@@ -3634,12 +3635,18 @@ builtin_builder::binop(builtin_available_predicate avail,
                        ir_expression_operation opcode,
                        const glsl_type *return_type,
                        const glsl_type *param0_type,
-                       const glsl_type *param1_type)
+                       const glsl_type *param1_type,
+                       bool swap_operands)
 {
    ir_variable *x = in_var(param0_type, "x");
    ir_variable *y = in_var(param1_type, "y");
    MAKE_SIG(return_type, avail, 2, x, y);
-   body.emit(ret(expr(opcode, x, y)));
+
+   if (swap_operands)
+      body.emit(ret(expr(opcode, y, x)));
+   else
+      body.emit(ret(expr(opcode, x, y)));
+
    return sig;
 }
 
@@ -4972,16 +4979,18 @@ ir_function_signature *
 builtin_builder::_lessThanEqual(builtin_available_predicate avail,
                                 const glsl_type *type)
 {
-   return binop(avail, ir_binop_lequal,
-                glsl_type::bvec(type->vector_elements), type, type);
+   return binop(avail, ir_binop_gequal,
+                glsl_type::bvec(type->vector_elements), type, type,
+                true);
 }
 
 ir_function_signature *
 builtin_builder::_greaterThan(builtin_available_predicate avail,
                               const glsl_type *type)
 {
-   return binop(avail, ir_binop_greater,
-                glsl_type::bvec(type->vector_elements), type, type);
+   return binop(avail, ir_binop_less,
+                glsl_type::bvec(type->vector_elements), type, type,
+                true);
 }
 
 ir_function_signature *
index c659a25..a7dfe57 100644 (file)
@@ -1799,30 +1799,6 @@ nir_visitor::visit(ir_expression *ir)
          result = nir_slt(&b, srcs[0], srcs[1]);
       }
       break;
-   case ir_binop_greater:
-      if (supports_ints) {
-         if (type_is_float(types[0]))
-            result = nir_flt(&b, srcs[1], srcs[0]);
-         else if (type_is_signed(types[0]))
-            result = nir_ilt(&b, srcs[1], srcs[0]);
-         else
-            result = nir_ult(&b, srcs[1], srcs[0]);
-      } else {
-         result = nir_slt(&b, srcs[1], srcs[0]);
-      }
-      break;
-   case ir_binop_lequal:
-      if (supports_ints) {
-         if (type_is_float(types[0]))
-            result = nir_fge(&b, srcs[1], srcs[0]);
-         else if (type_is_signed(types[0]))
-            result = nir_ige(&b, srcs[1], srcs[0]);
-         else
-            result = nir_uge(&b, srcs[1], srcs[0]);
-      } else {
-         result = nir_slt(&b, srcs[1], srcs[0]);
-      }
-      break;
    case ir_binop_gequal:
       if (supports_ints) {
          if (type_is_float(types[0]))
index 18bf1eb..2c61dd9 100644 (file)
@@ -487,10 +487,8 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1)
 
    case ir_binop_equal:
    case ir_binop_nequal:
-   case ir_binop_lequal:
    case ir_binop_gequal:
    case ir_binop_less:
-   case ir_binop_greater:
       assert(op0->type == op1->type);
       this->type = glsl_type::get_instance(GLSL_TYPE_BOOL,
                                           op0->type->vector_elements, 1);
index 8d61533..416d8c7 100644 (file)
@@ -371,13 +371,13 @@ less(operand a, operand b)
 ir_expression*
 greater(operand a, operand b)
 {
-   return expr(ir_binop_greater, a, b);
+   return expr(ir_binop_less, b, a);
 }
 
 ir_expression*
 lequal(operand a, operand b)
 {
-   return expr(ir_binop_lequal, a, b);
+   return expr(ir_binop_gequal, b, a);
 }
 
 ir_expression*
index 3e30c5d..dfe4bb2 100644 (file)
@@ -551,8 +551,6 @@ ir_builder_print_visitor::print_without_declaration(const ir_expression *ir)
    case ir_binop_mul:
    case ir_binop_imul_high:
    case ir_binop_less:
-   case ir_binop_greater:
-   case ir_binop_lequal:
    case ir_binop_gequal:
    case ir_binop_equal:
    case ir_binop_nequal:
index 52f2550..d854292 100644 (file)
@@ -602,8 +602,6 @@ ir_expression_operation = [
    # Binary comparison operators which return a boolean vector.
    # The type of both operands must be equal.
    operation("less", 2, printable_name="<", source_types=numeric_types, dest_type=bool_type, c_expression="{src0} < {src1}"),
-   operation("greater", 2, printable_name=">", source_types=numeric_types, dest_type=bool_type, c_expression="{src0} > {src1}"),
-   operation("lequal", 2, printable_name="<=", source_types=numeric_types, dest_type=bool_type, c_expression="{src0} <= {src1}"),
    operation("gequal", 2, printable_name=">=", source_types=numeric_types, dest_type=bool_type, c_expression="{src0} >= {src1}"),
    operation("equal", 2, printable_name="==", source_types=all_types, dest_type=bool_type, c_expression="{src0} == {src1}"),
    operation("nequal", 2, printable_name="!=", source_types=all_types, dest_type=bool_type, c_expression="{src0} != {src1}"),
index e368224..aa07f8a 100644 (file)
@@ -647,8 +647,6 @@ ir_validate::visit_leave(ir_expression *ir)
       break;
 
    case ir_binop_less:
-   case ir_binop_greater:
-   case ir_binop_lequal:
    case ir_binop_gequal:
    case ir_binop_equal:
    case ir_binop_nequal:
index 2979e09..0fb6e9f 100644 (file)
@@ -87,7 +87,8 @@ find_initial_value(ir_loop *loop, ir_variable *var)
 
 static int
 calculate_iterations(ir_rvalue *from, ir_rvalue *to, ir_rvalue *increment,
-                     enum ir_expression_operation op, bool continue_from_then)
+                     enum ir_expression_operation op, bool continue_from_then,
+                     bool swap_compare_operands)
 {
    if (from == NULL || to == NULL || increment == NULL)
       return -1;
@@ -154,8 +155,9 @@ calculate_iterations(ir_rvalue *from, ir_rvalue *to, ir_rvalue *increment,
       ir_expression *const add =
          new(mem_ctx) ir_expression(ir_binop_add, mul->type, mul, from);
 
-      ir_expression *cmp =
-         new(mem_ctx) ir_expression(op, glsl_type::bool_type, add, to);
+      ir_expression *cmp = swap_compare_operands
+         ? new(mem_ctx) ir_expression(op, glsl_type::bool_type, to, add)
+         : new(mem_ctx) ir_expression(op, glsl_type::bool_type, add, to);
       if (continue_from_then)
          cmp = new(mem_ctx) ir_expression(ir_unop_logic_not, cmp);
 
@@ -582,8 +584,6 @@ loop_analysis::visit_leave(ir_loop *ir)
 
       switch (cond->operation) {
       case ir_binop_less:
-      case ir_binop_greater:
-      case ir_binop_lequal:
       case ir_binop_gequal: {
         /* The expressions that we care about will either be of the form
          * 'counter < limit' or 'limit < counter'.  Figure out which is
@@ -592,18 +592,12 @@ loop_analysis::visit_leave(ir_loop *ir)
         ir_rvalue *counter = cond->operands[0]->as_dereference_variable();
         ir_constant *limit = cond->operands[1]->as_constant();
         enum ir_expression_operation cmp = cond->operation;
+         bool swap_compare_operands = false;
 
         if (limit == NULL) {
            counter = cond->operands[1]->as_dereference_variable();
            limit = cond->operands[0]->as_constant();
-
-           switch (cmp) {
-           case ir_binop_less:    cmp = ir_binop_greater; break;
-           case ir_binop_greater: cmp = ir_binop_less;    break;
-           case ir_binop_lequal:  cmp = ir_binop_gequal;  break;
-           case ir_binop_gequal:  cmp = ir_binop_lequal;  break;
-           default: assert(!"Should not get here.");
-           }
+            swap_compare_operands = true;
         }
 
         if ((counter == NULL) || (limit == NULL))
@@ -616,7 +610,8 @@ loop_analysis::visit_leave(ir_loop *ir)
          loop_variable *lv = ls->get(var);
          if (lv != NULL && lv->is_induction_var()) {
             t->iterations = calculate_iterations(init, limit, lv->increment,
-                                                 cmp, t->continue_from_then);
+                                                 cmp, t->continue_from_then,
+                                                 swap_compare_operands);
 
             if (incremented_before_terminator(ir, var, t->ir)) {
                t->iterations--;
index 31d1f74..ce5f265 100644 (file)
@@ -438,8 +438,6 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
 
       switch (op_expr[0]->operation) {
       case ir_binop_less:    new_op = ir_binop_gequal;  break;
-      case ir_binop_greater: new_op = ir_binop_lequal;  break;
-      case ir_binop_lequal:  new_op = ir_binop_greater; break;
       case ir_binop_gequal:  new_op = ir_binop_less;    break;
       case ir_binop_equal:   new_op = ir_binop_nequal;  break;
       case ir_binop_nequal:  new_op = ir_binop_equal;   break;
@@ -697,8 +695,6 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
       break;
 
    case ir_binop_less:
-   case ir_binop_lequal:
-   case ir_binop_greater:
    case ir_binop_gequal:
    case ir_binop_equal:
    case ir_binop_nequal:
index 623487e..88a74a3 100644 (file)
@@ -84,7 +84,7 @@ def const_bool(value):
 
 def gt_zero(var_name):
     """Create Construct the expression var_name > 0"""
-    return ['expression', 'bool', '>', ['var_ref', var_name], const_float(0)]
+    return ['expression', 'bool', '<', const_float(0), ['var_ref', var_name]]
 
 
 # The following functions can be used to build complex control flow
index 7d62479..ddb941c 100644 (file)
@@ -76,10 +76,6 @@ brw_conditional_for_comparison(unsigned int op)
    switch (op) {
    case ir_binop_less:
       return BRW_CONDITIONAL_L;
-   case ir_binop_greater:
-      return BRW_CONDITIONAL_G;
-   case ir_binop_lequal:
-      return BRW_CONDITIONAL_LE;
    case ir_binop_gequal:
       return BRW_CONDITIONAL_GE;
    case ir_binop_equal:
index e4803aa..aa33063 100644 (file)
@@ -1135,22 +1135,6 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
    case ir_binop_less:
       emit(ir, OPCODE_SLT, result_dst, op[0], op[1]);
       break;
-   case ir_binop_greater:
-      /* Negating the operands (as opposed to switching the order of the
-       * operands) produces the correct result when both are +/-Inf.
-       */
-      op[0].negate = ~op[0].negate;
-      op[1].negate = ~op[1].negate;
-      emit(ir, OPCODE_SLT, result_dst, op[0], op[1]);
-      break;
-   case ir_binop_lequal:
-      /* Negating the operands (as opposed to switching the order of the
-       * operands) produces the correct result when both are +/-Inf.
-       */
-      op[0].negate = ~op[0].negate;
-      op[1].negate = ~op[1].negate;
-      emit(ir, OPCODE_SGE, result_dst, op[0], op[1]);
-      break;
    case ir_binop_gequal:
       emit(ir, OPCODE_SGE, result_dst, op[0], op[1]);
       break;
@@ -1758,10 +1742,6 @@ ir_to_mesa_visitor::process_move_condition(ir_rvalue *ir)
       /*      a is -  0  +            -  0  +
        * (a <  0)  T  F  F  ( a < 0)  T  F  F
        * (0 <  a)  F  F  T  (-a < 0)  F  F  T
-       * (a <= 0)  T  T  F  (-a < 0)  F  F  T  (swap order of other operands)
-       * (0 <= a)  F  T  T  ( a < 0)  T  F  F  (swap order of other operands)
-       * (a >  0)  F  F  T  (-a < 0)  F  F  T
-       * (0 >  a)  T  F  F  ( a < 0)  T  F  F
        * (a >= 0)  F  T  T  ( a < 0)  T  F  F  (swap order of other operands)
        * (0 >= a)  T  T  F  (-a < 0)  F  F  T  (swap order of other operands)
        *
@@ -1775,16 +1755,6 @@ ir_to_mesa_visitor::process_move_condition(ir_rvalue *ir)
            negate = zero_on_left;
            break;
 
-        case ir_binop_greater:
-           switch_order = false;
-           negate = !zero_on_left;
-           break;
-
-        case ir_binop_lequal:
-           switch_order = true;
-           negate = !zero_on_left;
-           break;
-
         case ir_binop_gequal:
            switch_order = true;
            negate = zero_on_left;
index eaed052..54e1961 100644 (file)
@@ -1499,12 +1499,6 @@ glsl_to_tgsi_visitor::visit_expression(ir_expression* ir, st_src_reg *op)
    case ir_binop_less:
       emit_asm(ir, TGSI_OPCODE_SLT, result_dst, op[0], op[1]);
       break;
-   case ir_binop_greater:
-      emit_asm(ir, TGSI_OPCODE_SLT, result_dst, op[1], op[0]);
-      break;
-   case ir_binop_lequal:
-      emit_asm(ir, TGSI_OPCODE_SGE, result_dst, op[1], op[0]);
-      break;
    case ir_binop_gequal:
       emit_asm(ir, TGSI_OPCODE_SGE, result_dst, op[0], op[1]);
       break;
@@ -2807,10 +2801,6 @@ glsl_to_tgsi_visitor::process_move_condition(ir_rvalue *ir)
       /*      a is -  0  +            -  0  +
        * (a <  0)  T  F  F  ( a < 0)  T  F  F
        * (0 <  a)  F  F  T  (-a < 0)  F  F  T
-       * (a <= 0)  T  T  F  (-a < 0)  F  F  T  (swap order of other operands)
-       * (0 <= a)  F  T  T  ( a < 0)  T  F  F  (swap order of other operands)
-       * (a >  0)  F  F  T  (-a < 0)  F  F  T
-       * (0 >  a)  T  F  F  ( a < 0)  T  F  F
        * (a >= 0)  F  T  T  ( a < 0)  T  F  F  (swap order of other operands)
        * (0 >= a)  T  T  F  (-a < 0)  F  F  T  (swap order of other operands)
        *
@@ -2824,16 +2814,6 @@ glsl_to_tgsi_visitor::process_move_condition(ir_rvalue *ir)
             negate = zero_on_left;
             break;
 
-         case ir_binop_greater:
-            switch_order = false;
-            negate = !zero_on_left;
-            break;
-
-         case ir_binop_lequal:
-            switch_order = true;
-            negate = !zero_on_left;
-            break;
-
          case ir_binop_gequal:
             switch_order = true;
             negate = zero_on_left;