From 67ae89e4177df755503660f088366bf22ded1fbf Mon Sep 17 00:00:00 2001 From: "kmillikin@chromium.org" Date: Fri, 31 Oct 2008 11:55:06 +0000 Subject: [PATCH] Simplify the way we materialize boolean values that are not yet pushed on the stack frame. Review URL: http://codereview.chromium.org/8764 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@671 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/codegen-arm.cc | 36 +++++++++++++++--------------------- src/codegen-ia32.cc | 37 +++++++++++++++---------------------- 2 files changed, 30 insertions(+), 43 deletions(-) diff --git a/src/codegen-arm.cc b/src/codegen-arm.cc index 35522b19ad..b39180ed82 100644 --- a/src/codegen-arm.cc +++ b/src/codegen-arm.cc @@ -359,47 +359,41 @@ void CodeGenerator::Load(Expression* x, TypeofState typeof_state) { Label false_target; LoadCondition(x, typeof_state, &true_target, &false_target, false); + // Materialize boolean values on the stack frame if necessary. if (has_cc()) { - // convert cc_reg_ into a bool - Label loaded, materialize_true; - __ b(cc_reg_, &materialize_true); + // The value we want is in the cc register. Since complicated + // conditions can require more than one test, there may also be branches + // to true_target and false_target. + Label loaded; + __ b(cc_reg_, &true_target); + __ bind(&false_target); __ mov(r0, Operand(Factory::false_value())); __ push(r0); __ b(&loaded); - __ bind(&materialize_true); + __ bind(&true_target); __ mov(r0, Operand(Factory::true_value())); __ push(r0); __ bind(&loaded); cc_reg_ = al; - } + } else { + // Optimization of boolean-valued expressions whose value is statically + // known may have generated an unconditional jump to either of the + // targets (but not both) and failed to leave a value in either the cc + // register or on top of the frame. + ASSERT(!(true_target.is_linked() && false_target.is_linked())); - if (true_target.is_linked() || false_target.is_linked()) { - // we have at least one condition value - // that has been "translated" into a branch, - // thus it needs to be loaded explicitly again - Label loaded; - __ b(&loaded); // don't lose current TOS - bool both = true_target.is_linked() && false_target.is_linked(); - // reincarnate "true", if necessary if (true_target.is_linked()) { __ bind(&true_target); __ mov(r0, Operand(Factory::true_value())); __ push(r0); } - // if both "true" and "false" need to be reincarnated, - // jump across code for "false" - if (both) - __ b(&loaded); - // reincarnate "false", if necessary + if (false_target.is_linked()) { __ bind(&false_target); __ mov(r0, Operand(Factory::false_value())); __ push(r0); } - // everything is loaded at this point - __ bind(&loaded); } - ASSERT(!has_cc()); } diff --git a/src/codegen-ia32.cc b/src/codegen-ia32.cc index eaac989061..d53e22548d 100644 --- a/src/codegen-ia32.cc +++ b/src/codegen-ia32.cc @@ -474,44 +474,37 @@ void CodeGenerator::Load(Expression* x, TypeofState typeof_state) { Label false_target; LoadCondition(x, typeof_state, &true_target, &false_target, false); + // Materialize boolean values on the stack frame if necessary. if (has_cc()) { - // convert cc_reg_ into a bool - - Label loaded, materialize_true; - __ j(cc_reg_, &materialize_true); + // The value we want is in the cc register. Since complicated + // conditions can require more than one test, there may also be branches + // to true_target and false_target. + Label loaded; + __ j(cc_reg_, &true_target); + __ bind(&false_target); frame_->Push(Immediate(Factory::false_value())); __ jmp(&loaded); - __ bind(&materialize_true); + __ bind(&true_target); frame_->Push(Immediate(Factory::true_value())); __ bind(&loaded); cc_reg_ = no_condition; - } + } else { + // Optimization of boolean-valued expressions whose value is statically + // known may have generated an unconditional jump to either of the + // targets (but not both) and failed to leave a value in either the cc + // register or on top of the frame. + ASSERT(!(true_target.is_linked() && false_target.is_linked())); - if (true_target.is_linked() || false_target.is_linked()) { - // we have at least one condition value - // that has been "translated" into a branch, - // thus it needs to be loaded explicitly again - Label loaded; - __ jmp(&loaded); // don't lose current TOS - bool both = true_target.is_linked() && false_target.is_linked(); - // reincarnate "true", if necessary if (true_target.is_linked()) { __ bind(&true_target); frame_->Push(Immediate(Factory::true_value())); } - // if both "true" and "false" need to be reincarnated, - // jump across code for "false" - if (both) - __ jmp(&loaded); - // reincarnate "false", if necessary + if (false_target.is_linked()) { __ bind(&false_target); frame_->Push(Immediate(Factory::false_value())); } - // everything is loaded at this point - __ bind(&loaded); } - ASSERT(!has_cc()); }