Fix approximation of CanDeoptimize() and other small store elimination fixes.

R=titzer@chromium.org

Review URL: https://codereview.chromium.org/222263002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20468 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 18308b38
...@@ -842,104 +842,133 @@ void HInstruction::Verify() { ...@@ -842,104 +842,133 @@ void HInstruction::Verify() {
#endif #endif
static bool HasPrimitiveRepresentation(HValue* instr) {
return instr->representation().IsInteger32() ||
instr->representation().IsDouble();
}
bool HInstruction::CanDeoptimize() { bool HInstruction::CanDeoptimize() {
// TODO(titzer): make this a virtual method? // TODO(titzer): make this a virtual method?
switch (opcode()) { switch (opcode()) {
case HValue::kAbnormalExit:
case HValue::kAccessArgumentsAt: case HValue::kAccessArgumentsAt:
case HValue::kApplyArguments: case HValue::kAllocate:
case HValue::kArgumentsElements: case HValue::kArgumentsElements:
case HValue::kArgumentsLength: case HValue::kArgumentsLength:
case HValue::kArgumentsObject: case HValue::kArgumentsObject:
case HValue::kBlockEntry:
case HValue::kBoundsCheckBaseIndexInformation: case HValue::kBoundsCheckBaseIndexInformation:
case HValue::kCallFunction:
case HValue::kCallJSFunction:
case HValue::kCallNew:
case HValue::kCallNewArray:
case HValue::kCallStub:
case HValue::kCallWithDescriptor:
case HValue::kCapturedObject: case HValue::kCapturedObject:
case HValue::kClampToUint8: case HValue::kClassOfTestAndBranch:
case HValue::kCompareGeneric:
case HValue::kCompareHoleAndBranch:
case HValue::kCompareMap:
case HValue::kCompareMinusZeroAndBranch:
case HValue::kCompareNumericAndBranch:
case HValue::kCompareObjectEqAndBranch:
case HValue::kConstant: case HValue::kConstant:
case HValue::kConstructDouble:
case HValue::kContext: case HValue::kContext:
case HValue::kDateField:
case HValue::kDebugBreak: case HValue::kDebugBreak:
case HValue::kDeclareGlobals: case HValue::kDeclareGlobals:
case HValue::kDiv: case HValue::kDoubleBits:
case HValue::kDummyUse: case HValue::kDummyUse:
case HValue::kEnterInlined: case HValue::kEnterInlined:
case HValue::kEnvironmentMarker: case HValue::kEnvironmentMarker:
case HValue::kForInCacheArray: case HValue::kForceRepresentation:
case HValue::kForInPrepareMap:
case HValue::kFunctionLiteral:
case HValue::kGetCachedArrayIndex: case HValue::kGetCachedArrayIndex:
case HValue::kGoto: case HValue::kGoto:
case HValue::kHasCachedArrayIndexAndBranch:
case HValue::kHasInstanceTypeAndBranch:
case HValue::kInnerAllocatedObject: case HValue::kInnerAllocatedObject:
case HValue::kInstanceOf: case HValue::kInstanceOf:
case HValue::kInstanceOfKnownGlobal: case HValue::kInstanceOfKnownGlobal:
case HValue::kInvokeFunction: case HValue::kIsConstructCallAndBranch:
case HValue::kIsObjectAndBranch:
case HValue::kIsSmiAndBranch:
case HValue::kIsStringAndBranch:
case HValue::kIsUndetectableAndBranch:
case HValue::kLeaveInlined: case HValue::kLeaveInlined:
case HValue::kLoadContextSlot:
case HValue::kLoadFieldByIndex: case HValue::kLoadFieldByIndex:
case HValue::kLoadFunctionPrototype:
case HValue::kLoadGlobalCell:
case HValue::kLoadGlobalGeneric: case HValue::kLoadGlobalGeneric:
case HValue::kLoadKeyed:
case HValue::kLoadKeyedGeneric:
case HValue::kLoadNamedField: case HValue::kLoadNamedField:
case HValue::kLoadNamedGeneric: case HValue::kLoadNamedGeneric:
case HValue::kLoadRoot: case HValue::kLoadRoot:
case HValue::kMapEnumLength: case HValue::kMapEnumLength:
case HValue::kMathFloorOfDiv:
case HValue::kMathMinMax: case HValue::kMathMinMax:
case HValue::kMod:
case HValue::kMul:
case HValue::kOsrEntry:
case HValue::kParameter: case HValue::kParameter:
case HValue::kPower: case HValue::kPhi:
case HValue::kPushArgument: case HValue::kPushArgument:
case HValue::kRegExpLiteral:
case HValue::kReturn:
case HValue::kRor: case HValue::kRor:
case HValue::kSar: case HValue::kSar:
case HValue::kSeqStringGetChar: case HValue::kSeqStringGetChar:
case HValue::kStoreCodeEntry:
case HValue::kStoreKeyed:
case HValue::kStoreNamedGeneric:
case HValue::kStringCharCodeAt:
case HValue::kStringCharFromCode:
case HValue::kThisFunction:
case HValue::kTypeofIsAndBranch:
case HValue::kUnknownOSRValue:
case HValue::kUseConst:
return false;
case HValue::kAdd:
case HValue::kApplyArguments:
case HValue::kBitwise:
case HValue::kBoundsCheck:
case HValue::kBranch:
case HValue::kCallRuntime:
case HValue::kChange:
case HValue::kCheckHeapObject:
case HValue::kCheckInstanceType:
case HValue::kCheckMapValue:
case HValue::kCheckMaps:
case HValue::kCheckSmi:
case HValue::kCheckValue:
case HValue::kClampToUint8:
case HValue::kDateField:
case HValue::kDeoptimize:
case HValue::kDiv:
case HValue::kForInCacheArray:
case HValue::kForInPrepareMap:
case HValue::kFunctionLiteral:
case HValue::kInvokeFunction:
case HValue::kLoadContextSlot:
case HValue::kLoadFunctionPrototype:
case HValue::kLoadGlobalCell:
case HValue::kLoadKeyed:
case HValue::kLoadKeyedGeneric:
case HValue::kMathFloorOfDiv:
case HValue::kMod:
case HValue::kMul:
case HValue::kOsrEntry:
case HValue::kPower:
case HValue::kSeqStringSetChar: case HValue::kSeqStringSetChar:
case HValue::kShl: case HValue::kShl:
case HValue::kShr: case HValue::kShr:
case HValue::kSimulate: case HValue::kSimulate:
case HValue::kStackCheck: case HValue::kStackCheck:
case HValue::kStoreCodeEntry:
case HValue::kStoreContextSlot: case HValue::kStoreContextSlot:
case HValue::kStoreGlobalCell: case HValue::kStoreGlobalCell:
case HValue::kStoreKeyed:
case HValue::kStoreKeyedGeneric: case HValue::kStoreKeyedGeneric:
case HValue::kStoreNamedField: case HValue::kStoreNamedField:
case HValue::kStoreNamedGeneric:
case HValue::kStringAdd: case HValue::kStringAdd:
case HValue::kStringCharCodeAt: case HValue::kStringCompareAndBranch:
case HValue::kStringCharFromCode:
case HValue::kSub: case HValue::kSub:
case HValue::kThisFunction:
case HValue::kToFastProperties: case HValue::kToFastProperties:
case HValue::kTransitionElementsKind: case HValue::kTransitionElementsKind:
case HValue::kTrapAllocationMemento: case HValue::kTrapAllocationMemento:
case HValue::kTypeof: case HValue::kTypeof:
case HValue::kUnaryMathOperation: case HValue::kUnaryMathOperation:
case HValue::kUseConst:
case HValue::kWrapReceiver: case HValue::kWrapReceiver:
return false;
case HValue::kForceRepresentation:
case HValue::kAdd:
case HValue::kBitwise:
case HValue::kChange:
case HValue::kCompareGeneric:
// These instructions might deoptimize if they are not primitive.
if (!HasPrimitiveRepresentation(this)) return true;
for (int i = 0; i < OperandCount(); i++) {
HValue* input = OperandAt(i);
if (!HasPrimitiveRepresentation(input)) return true;
}
return false;
default:
return true; return true;
} }
UNREACHABLE();
return true;
} }
......
...@@ -129,7 +129,7 @@ void HStoreEliminationPhase::ProcessInstr(HInstruction* instr, ...@@ -129,7 +129,7 @@ void HStoreEliminationPhase::ProcessInstr(HInstruction* instr,
unobserved_.Rewind(0); unobserved_.Rewind(0);
return; return;
} }
if (instr->ChangesFlags().ContainsAnyOf(flags)) { if (instr->DependsOnFlags().ContainsAnyOf(flags)) {
TRACE(("-- Observed stores at I%d (GVN flags)\n", instr->id())); TRACE(("-- Observed stores at I%d (GVN flags)\n", instr->id()));
unobserved_.Rewind(0); unobserved_.Rewind(0);
return; return;
......
...@@ -124,18 +124,22 @@ bool LCodeGenBase::GenerateBody() { ...@@ -124,18 +124,22 @@ bool LCodeGenBase::GenerateBody() {
void LCodeGenBase::CheckEnvironmentUsage() { void LCodeGenBase::CheckEnvironmentUsage() {
#ifdef DEBUG #ifdef DEBUG
bool live_block = true; bool dead_block = false;
for (int i = 0; i < instructions_->length(); i++) { for (int i = 0; i < instructions_->length(); i++) {
LInstruction* instr = instructions_->at(i); LInstruction* instr = instructions_->at(i);
if (instr->IsLabel()) live_block = !LLabel::cast(instr)->HasReplacement(); HValue* hval = instr->hydrogen_value();
if (live_block && if (instr->IsLabel()) dead_block = LLabel::cast(instr)->HasReplacement();
instr->hydrogen_value()->block()->IsReachable() && if (dead_block || !hval->block()->IsReachable()) continue;
instr->HasEnvironment() &&
!instr->environment()->has_been_used()) { HInstruction* hinstr = HInstruction::cast(hval);
FunctionLiteral* lit = info_->function(); if (!hinstr->CanDeoptimize() && instr->HasEnvironment()) {
V8_Fatal(__FILE__, __LINE__, "unused environment in %s <@%d,#%d> %s\n", V8_Fatal(__FILE__, __LINE__, "CanDeoptimize is wrong for %s (%s)\n",
lit == NULL ? "<UNKNOWN>" : lit->name()->ToCString().get(), hinstr->Mnemonic(), instr->Mnemonic());
i, instr->hydrogen_value()->id(), instr->Mnemonic()); }
if (instr->HasEnvironment() && !instr->environment()->has_been_used()) {
V8_Fatal(__FILE__, __LINE__, "unused environment for %s (%s)\n",
hinstr->Mnemonic(), instr->Mnemonic());
} }
} }
#endif #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment