Don't use environment values at certain deoptimize-instructions.

If a HDeoptimize does not cut away parts of the control-flow-graph
we don't need to insert uses to correctly elimiate dead phis since
the full function is visible to the optimizing compiler.

This is a small improvement of the change r7221 which fixed a problem
when deoptimizing on never executed case-clauses.
Review URL: http://codereview.chromium.org/7012010

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7877 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
fschneider@chromium.org 2011-05-12 14:56:56 +00:00
parent 58161ce6ed
commit 5f29f9bd8e
3 changed files with 17 additions and 9 deletions

View File

@ -862,6 +862,11 @@ class HDeoptimize: public HControlInstruction {
DECLARE_CONCRETE_INSTRUCTION(Deoptimize) DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
enum UseEnvironment {
kNoUses,
kUseAll
};
protected: protected:
virtual void InternalSetOperandAt(int index, HValue* value) { virtual void InternalSetOperandAt(int index, HValue* value) {
values_[index] = value; values_[index] = value;

View File

@ -115,12 +115,13 @@ void HBasicBlock::AddInstruction(HInstruction* instr) {
} }
HDeoptimize* HBasicBlock::CreateDeoptimize() { HDeoptimize* HBasicBlock::CreateDeoptimize(
HDeoptimize::UseEnvironment has_uses) {
ASSERT(HasEnvironment()); ASSERT(HasEnvironment());
if (has_uses == HDeoptimize::kNoUses) return new(zone()) HDeoptimize(0);
HEnvironment* environment = last_environment(); HEnvironment* environment = last_environment();
HDeoptimize* instr = new(zone()) HDeoptimize(environment->length()); HDeoptimize* instr = new(zone()) HDeoptimize(environment->length());
for (int i = 0; i < environment->length(); i++) { for (int i = 0; i < environment->length(); i++) {
HValue* val = environment->values()->at(i); HValue* val = environment->values()->at(i);
instr->AddEnvironmentValue(val); instr->AddEnvironmentValue(val);
@ -2490,7 +2491,9 @@ void HGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
// Unconditionally deoptimize on the first non-smi compare. // Unconditionally deoptimize on the first non-smi compare.
clause->RecordTypeFeedback(oracle()); clause->RecordTypeFeedback(oracle());
if (!clause->IsSmiCompare()) { if (!clause->IsSmiCompare()) {
current_block()->FinishExitWithDeoptimization(); // Finish with deoptimize and add uses of enviroment values to
// account for invisible uses.
current_block()->FinishExitWithDeoptimization(HDeoptimize::kUseAll);
set_current_block(NULL); set_current_block(NULL);
break; break;
} }
@ -3237,7 +3240,7 @@ void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr,
// know about and do not want to handle ones we've never seen. Otherwise // know about and do not want to handle ones we've never seen. Otherwise
// use a generic IC. // use a generic IC.
if (count == types->length() && FLAG_deoptimize_uncommon_cases) { if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
current_block()->FinishExitWithDeoptimization(); current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
} else { } else {
HInstruction* instr = BuildStoreNamedGeneric(object, name, value); HInstruction* instr = BuildStoreNamedGeneric(object, name, value);
instr->set_position(expr->position()); instr->set_position(expr->position());
@ -3916,7 +3919,7 @@ void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
// know about and do not want to handle ones we've never seen. Otherwise // know about and do not want to handle ones we've never seen. Otherwise
// use a generic IC. // use a generic IC.
if (count == types->length() && FLAG_deoptimize_uncommon_cases) { if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
current_block()->FinishExitWithDeoptimization(); current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
} else { } else {
HValue* context = environment()->LookupContext(); HValue* context = environment()->LookupContext();
HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count); HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count);

View File

@ -125,8 +125,8 @@ class HBasicBlock: public ZoneObject {
void AddSimulate(int id) { AddInstruction(CreateSimulate(id)); } void AddSimulate(int id) { AddInstruction(CreateSimulate(id)); }
void AssignCommonDominator(HBasicBlock* other); void AssignCommonDominator(HBasicBlock* other);
void FinishExitWithDeoptimization() { void FinishExitWithDeoptimization(HDeoptimize::UseEnvironment has_uses) {
FinishExit(CreateDeoptimize()); FinishExit(CreateDeoptimize(has_uses));
} }
// Add the inlined function exit sequence, adding an HLeaveInlined // Add the inlined function exit sequence, adding an HLeaveInlined
@ -153,7 +153,7 @@ class HBasicBlock: public ZoneObject {
void AddDominatedBlock(HBasicBlock* block); void AddDominatedBlock(HBasicBlock* block);
HSimulate* CreateSimulate(int id); HSimulate* CreateSimulate(int id);
HDeoptimize* CreateDeoptimize(); HDeoptimize* CreateDeoptimize(HDeoptimize::UseEnvironment has_uses);
int block_id_; int block_id_;
HGraph* graph_; HGraph* graph_;