summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2010-06-11 13:45:51 -0700
committerIan Romanick <ian.d.romanick@intel.com>2010-06-11 15:43:59 -0700
commit7825d3d15710fdfcfc503754862963aac8065480 (patch)
tree62db8330e13026e8b9ca5c9065974e4a9ad71135
parent0ad76c67675c35a65a79752058f53eee74947ba5 (diff)
Treat ?: with all constant subexpressions as a constant expression
-rw-r--r--ast_to_hir.cpp40
1 files changed, 25 insertions, 15 deletions
diff --git a/ast_to_hir.cpp b/ast_to_hir.cpp
index b8375b3..927a9e4 100644
--- a/ast_to_hir.cpp
+++ b/ast_to_hir.cpp
@@ -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;
}