Index: src/ia32/lithium-ia32.cc |
=================================================================== |
--- src/ia32/lithium-ia32.cc (revision 10404) |
+++ src/ia32/lithium-ia32.cc (working copy) |
@@ -1,4 +1,4 @@ |
-// Copyright 2011 the V8 project authors. All rights reserved. |
+// Copyright 2012 the V8 project authors. All rights reserved. |
// Redistribution and use in source and binary forms, with or without |
// modification, are permitted provided that the following conditions are |
// met: |
@@ -1047,22 +1047,31 @@ |
LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { |
- HValue* v = instr->value(); |
- if (v->EmitAtUses()) { |
- ASSERT(v->IsConstant()); |
- ASSERT(!v->representation().IsDouble()); |
- HBasicBlock* successor = HConstant::cast(v)->ToBoolean() |
+ HValue* value = instr->value(); |
+ if (value->EmitAtUses()) { |
+ ASSERT(value->IsConstant()); |
+ ASSERT(!value->representation().IsDouble()); |
+ HBasicBlock* successor = HConstant::cast(value)->ToBoolean() |
? instr->FirstSuccessor() |
: instr->SecondSuccessor(); |
return new(zone()) LGoto(successor->block_id()); |
} |
+ |
+ // Untagged integers or doubles, smis and booleans don't require a |
+ // deoptimization environment nor a temp register. |
+ Representation rep = value->representation(); |
+ HType type = value->type(); |
+ if (!rep.IsTagged() || type.IsSmi() || type.IsBoolean()) { |
+ return new(zone()) LBranch(UseRegister(value), NULL); |
+ } |
+ |
ToBooleanStub::Types expected = instr->expected_input_types(); |
// We need a temporary register when we have to access the map *or* we have |
// no type info yet, in which case we handle all cases (including the ones |
// involving maps). |
bool needs_temp = expected.NeedsMap() || expected.IsEmpty(); |
LOperand* temp = needs_temp ? TempRegister() : NULL; |
- return AssignEnvironment(new(zone()) LBranch(UseRegister(v), temp)); |
+ return AssignEnvironment(new(zone()) LBranch(UseRegister(value), temp)); |
} |
@@ -1388,7 +1397,11 @@ |
temp = TempRegister(); |
} |
LMulI* mul = new(zone()) LMulI(left, right, temp); |
- return AssignEnvironment(DefineSameAsFirst(mul)); |
+ if (instr->CheckFlag(HValue::kCanOverflow) || |
+ instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
+ AssignEnvironment(mul); |
+ } |
+ return DefineSameAsFirst(mul); |
} else if (instr->representation().IsDouble()) { |
return DoArithmeticD(Token::MUL, instr); |
} else { |
@@ -1456,6 +1469,15 @@ |
} |
+LInstruction* LChunkBuilder::DoRandom(HRandom* instr) { |
+ ASSERT(instr->representation().IsDouble()); |
+ ASSERT(instr->global_object()->representation().IsTagged()); |
+ LOperand* global_object = UseFixed(instr->global_object(), eax); |
+ LRandom* result = new(zone()) LRandom(global_object); |
+ return MarkAsCall(DefineFixedDouble(result, xmm1), instr); |
+} |
+ |
+ |
LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { |
ASSERT(instr->left()->representation().IsTagged()); |
ASSERT(instr->right()->representation().IsTagged()); |
@@ -1588,9 +1610,9 @@ |
LInstruction* LChunkBuilder::DoClassOfTestAndBranch( |
HClassOfTestAndBranch* instr) { |
ASSERT(instr->value()->representation().IsTagged()); |
- return new(zone()) LClassOfTestAndBranch(UseTempRegister(instr->value()), |
- TempRegister(), |
- TempRegister()); |
+ return new(zone()) LClassOfTestAndBranch(UseRegister(instr->value()), |
+ TempRegister(), |
+ TempRegister()); |
} |
@@ -1616,7 +1638,7 @@ |
LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { |
LOperand* object = UseRegister(instr->value()); |
LValueOf* result = new(zone()) LValueOf(object, TempRegister()); |
- return AssignEnvironment(DefineSameAsFirst(result)); |
+ return DefineSameAsFirst(result); |
} |
@@ -1660,7 +1682,11 @@ |
if (from.IsTagged()) { |
if (to.IsDouble()) { |
LOperand* value = UseRegister(instr->value()); |
- LNumberUntagD* res = new(zone()) LNumberUntagD(value); |
+ // Temp register only necessary for minus zero check. |
+ LOperand* temp = instr->deoptimize_on_minus_zero() |
+ ? TempRegister() |
+ : NULL; |
+ LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp); |
return AssignEnvironment(DefineAsRegister(res)); |
} else { |
ASSERT(to.IsInteger32()); |
@@ -1956,7 +1982,8 @@ |
LOperand* obj = UseRegisterAtStart(instr->object()); |
LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
LLoadKeyedFastElement* result = new(zone()) LLoadKeyedFastElement(obj, key); |
- return AssignEnvironment(DefineAsRegister(result)); |
+ if (instr->RequiresHoleCheck()) AssignEnvironment(result); |
+ return DefineAsRegister(result); |
} |