Treat ?: with all constant subexpressions as a constant expression
authorIan Romanick <ian.d.romanick@intel.com>
Fri, 11 Jun 2010 20:45:51 +0000 (13:45 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Fri, 11 Jun 2010 22:43:59 +0000 (15:43 -0700)
ast_to_hir.cpp

index b8375b3..927a9e4 100644 (file)
@@ -1028,25 +1028,35 @@ ast_expression::hir(exec_list *instructions,
         type = op[1]->type;
       }
 
-      ir_variable *const tmp = generate_temporary(type,
-                                                 instructions, state);
+      ir_constant *cond_val = op[0]->constant_expression_value();
+      ir_constant *then_val = op[1]->constant_expression_value();
+      ir_constant *else_val = op[2]->constant_expression_value();
+
+      if (then_instructions.is_empty()
+         && else_instructions.is_empty()
+         && (cond_val != NULL) && (then_val != NULL) && (else_val != NULL)) {
+        result = (cond_val->value.b[0]) ? then_val : else_val;
+      } else {
+        ir_variable *const tmp = generate_temporary(type,
+                                                    instructions, state);
 
-      ir_if *const stmt = new ir_if(op[0]);
-      instructions->push_tail(stmt);
+        ir_if *const stmt = new ir_if(op[0]);
+        instructions->push_tail(stmt);
 
-      then_instructions.move_nodes_to(& stmt->then_instructions);
-      ir_dereference *const then_deref = new ir_dereference_variable(tmp);
-      ir_assignment *const then_assign =
-        new ir_assignment(then_deref, op[1], NULL);
-      stmt->then_instructions.push_tail(then_assign);
+        then_instructions.move_nodes_to(& stmt->then_instructions);
+        ir_dereference *const then_deref = new ir_dereference_variable(tmp);
+        ir_assignment *const then_assign =
+           new ir_assignment(then_deref, op[1], NULL);
+        stmt->then_instructions.push_tail(then_assign);
 
-      else_instructions.move_nodes_to(& stmt->else_instructions);
-      ir_dereference *const else_deref = new ir_dereference_variable(tmp);
-      ir_assignment *const else_assign =
-        new ir_assignment(else_deref, op[2], NULL);
-      stmt->else_instructions.push_tail(else_assign);
+        else_instructions.move_nodes_to(& stmt->else_instructions);
+        ir_dereference *const else_deref = new ir_dereference_variable(tmp);
+        ir_assignment *const else_assign =
+           new ir_assignment(else_deref, op[2], NULL);
+        stmt->else_instructions.push_tail(else_assign);
 
-      result = new ir_dereference_variable(tmp);
+        result = new ir_dereference_variable(tmp);
+      }
       break;
    }