From 7825d3d15710fdfcfc503754862963aac8065480 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 11 Jun 2010 13:45:51 -0700 Subject: [PATCH] Treat ?: with all constant subexpressions as a constant expression --- ast_to_hir.cpp | 40 +++++++++++++++++++++++++--------------- 1 file 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; } -- 2.7.4