Index: src/compiler/effect-control-linearizer.cc |
diff --git a/src/compiler/effect-control-linearizer.cc b/src/compiler/effect-control-linearizer.cc |
index 3bb5cb51aace7745d3ce72d498243d4d0fdd327f..022aa87415023a15a55404f012b90d79c79f433f 100644 |
--- a/src/compiler/effect-control-linearizer.cc |
+++ b/src/compiler/effect-control-linearizer.cc |
@@ -7,6 +7,7 @@ |
#include "src/code-factory.h" |
#include "src/compiler/access-builder.h" |
#include "src/compiler/compiler-source-position-table.h" |
+#include "src/compiler/graph-assembler.h" |
#include "src/compiler/js-graph.h" |
#include "src/compiler/linkage.h" |
#include "src/compiler/node-matchers.h" |
@@ -24,7 +25,8 @@ EffectControlLinearizer::EffectControlLinearizer( |
: js_graph_(js_graph), |
schedule_(schedule), |
temp_zone_(temp_zone), |
- source_positions_(source_positions) {} |
+ source_positions_(source_positions), |
+ graph_assembler_(js_graph, nullptr, nullptr, temp_zone) {} |
Graph* EffectControlLinearizer::graph() const { return js_graph_->graph(); } |
CommonOperatorBuilder* EffectControlLinearizer::common() const { |
@@ -596,875 +598,636 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, |
Node* frame_state, |
Node** effect, |
Node** control) { |
- ValueEffectControl state(nullptr, nullptr, nullptr); |
+ gasm()->Reset(*effect, *control); |
+ Node* result = nullptr; |
switch (node->opcode()) { |
case IrOpcode::kChangeBitToTagged: |
- state = LowerChangeBitToTagged(node, *effect, *control); |
+ result = LowerChangeBitToTagged(node); |
break; |
case IrOpcode::kChangeInt31ToTaggedSigned: |
- state = LowerChangeInt31ToTaggedSigned(node, *effect, *control); |
+ result = LowerChangeInt31ToTaggedSigned(node); |
break; |
case IrOpcode::kChangeInt32ToTagged: |
- state = LowerChangeInt32ToTagged(node, *effect, *control); |
+ result = LowerChangeInt32ToTagged(node); |
break; |
case IrOpcode::kChangeUint32ToTagged: |
- state = LowerChangeUint32ToTagged(node, *effect, *control); |
+ result = LowerChangeUint32ToTagged(node); |
break; |
case IrOpcode::kChangeFloat64ToTagged: |
- state = LowerChangeFloat64ToTagged(node, *effect, *control); |
+ result = LowerChangeFloat64ToTagged(node); |
break; |
case IrOpcode::kChangeFloat64ToTaggedPointer: |
- state = LowerChangeFloat64ToTaggedPointer(node, *effect, *control); |
+ result = LowerChangeFloat64ToTaggedPointer(node); |
break; |
case IrOpcode::kChangeTaggedSignedToInt32: |
- state = LowerChangeTaggedSignedToInt32(node, *effect, *control); |
+ result = LowerChangeTaggedSignedToInt32(node); |
break; |
case IrOpcode::kChangeTaggedToBit: |
- state = LowerChangeTaggedToBit(node, *effect, *control); |
+ result = LowerChangeTaggedToBit(node); |
break; |
case IrOpcode::kChangeTaggedToInt32: |
- state = LowerChangeTaggedToInt32(node, *effect, *control); |
+ result = LowerChangeTaggedToInt32(node); |
break; |
case IrOpcode::kChangeTaggedToUint32: |
- state = LowerChangeTaggedToUint32(node, *effect, *control); |
+ result = LowerChangeTaggedToUint32(node); |
break; |
case IrOpcode::kChangeTaggedToFloat64: |
- state = LowerChangeTaggedToFloat64(node, *effect, *control); |
+ result = LowerChangeTaggedToFloat64(node); |
break; |
case IrOpcode::kTruncateTaggedToBit: |
- state = LowerTruncateTaggedToBit(node, *effect, *control); |
+ result = LowerTruncateTaggedToBit(node); |
break; |
case IrOpcode::kTruncateTaggedToFloat64: |
- state = LowerTruncateTaggedToFloat64(node, *effect, *control); |
+ result = LowerTruncateTaggedToFloat64(node); |
break; |
case IrOpcode::kCheckBounds: |
- state = LowerCheckBounds(node, frame_state, *effect, *control); |
+ result = LowerCheckBounds(node, frame_state); |
break; |
case IrOpcode::kCheckMaps: |
- state = LowerCheckMaps(node, frame_state, *effect, *control); |
+ result = LowerCheckMaps(node, frame_state); |
break; |
case IrOpcode::kCheckNumber: |
- state = LowerCheckNumber(node, frame_state, *effect, *control); |
+ result = LowerCheckNumber(node, frame_state); |
break; |
case IrOpcode::kCheckString: |
- state = LowerCheckString(node, frame_state, *effect, *control); |
+ result = LowerCheckString(node, frame_state); |
break; |
case IrOpcode::kCheckInternalizedString: |
- state = |
- LowerCheckInternalizedString(node, frame_state, *effect, *control); |
+ result = LowerCheckInternalizedString(node, frame_state); |
break; |
case IrOpcode::kCheckIf: |
- state = LowerCheckIf(node, frame_state, *effect, *control); |
+ result = LowerCheckIf(node, frame_state); |
break; |
case IrOpcode::kCheckedInt32Add: |
- state = LowerCheckedInt32Add(node, frame_state, *effect, *control); |
+ result = LowerCheckedInt32Add(node, frame_state); |
break; |
case IrOpcode::kCheckedInt32Sub: |
- state = LowerCheckedInt32Sub(node, frame_state, *effect, *control); |
+ result = LowerCheckedInt32Sub(node, frame_state); |
break; |
case IrOpcode::kCheckedInt32Div: |
- state = LowerCheckedInt32Div(node, frame_state, *effect, *control); |
+ result = LowerCheckedInt32Div(node, frame_state); |
break; |
case IrOpcode::kCheckedInt32Mod: |
- state = LowerCheckedInt32Mod(node, frame_state, *effect, *control); |
+ result = LowerCheckedInt32Mod(node, frame_state); |
break; |
case IrOpcode::kCheckedUint32Div: |
- state = LowerCheckedUint32Div(node, frame_state, *effect, *control); |
+ result = LowerCheckedUint32Div(node, frame_state); |
break; |
case IrOpcode::kCheckedUint32Mod: |
- state = LowerCheckedUint32Mod(node, frame_state, *effect, *control); |
+ result = LowerCheckedUint32Mod(node, frame_state); |
break; |
case IrOpcode::kCheckedInt32Mul: |
- state = LowerCheckedInt32Mul(node, frame_state, *effect, *control); |
+ result = LowerCheckedInt32Mul(node, frame_state); |
break; |
case IrOpcode::kCheckedInt32ToTaggedSigned: |
- state = |
- LowerCheckedInt32ToTaggedSigned(node, frame_state, *effect, *control); |
+ result = LowerCheckedInt32ToTaggedSigned(node, frame_state); |
break; |
case IrOpcode::kCheckedUint32ToInt32: |
- state = LowerCheckedUint32ToInt32(node, frame_state, *effect, *control); |
+ result = LowerCheckedUint32ToInt32(node, frame_state); |
break; |
case IrOpcode::kCheckedUint32ToTaggedSigned: |
- state = LowerCheckedUint32ToTaggedSigned(node, frame_state, *effect, |
- *control); |
+ result = LowerCheckedUint32ToTaggedSigned(node, frame_state); |
break; |
case IrOpcode::kCheckedFloat64ToInt32: |
- state = LowerCheckedFloat64ToInt32(node, frame_state, *effect, *control); |
+ result = LowerCheckedFloat64ToInt32(node, frame_state); |
break; |
case IrOpcode::kCheckedTaggedSignedToInt32: |
- state = |
- LowerCheckedTaggedSignedToInt32(node, frame_state, *effect, *control); |
+ result = LowerCheckedTaggedSignedToInt32(node, frame_state); |
break; |
case IrOpcode::kCheckedTaggedToInt32: |
- state = LowerCheckedTaggedToInt32(node, frame_state, *effect, *control); |
+ result = LowerCheckedTaggedToInt32(node, frame_state); |
break; |
case IrOpcode::kCheckedTaggedToFloat64: |
- state = LowerCheckedTaggedToFloat64(node, frame_state, *effect, *control); |
+ result = LowerCheckedTaggedToFloat64(node, frame_state); |
break; |
case IrOpcode::kCheckedTaggedToTaggedSigned: |
- state = LowerCheckedTaggedToTaggedSigned(node, frame_state, *effect, |
- *control); |
+ result = LowerCheckedTaggedToTaggedSigned(node, frame_state); |
break; |
case IrOpcode::kCheckedTaggedToTaggedPointer: |
- state = LowerCheckedTaggedToTaggedPointer(node, frame_state, *effect, |
- *control); |
+ result = LowerCheckedTaggedToTaggedPointer(node, frame_state); |
break; |
case IrOpcode::kTruncateTaggedToWord32: |
- state = LowerTruncateTaggedToWord32(node, *effect, *control); |
+ result = LowerTruncateTaggedToWord32(node); |
break; |
case IrOpcode::kCheckedTruncateTaggedToWord32: |
- state = LowerCheckedTruncateTaggedToWord32(node, frame_state, *effect, |
- *control); |
+ result = LowerCheckedTruncateTaggedToWord32(node, frame_state); |
break; |
case IrOpcode::kObjectIsCallable: |
- state = LowerObjectIsCallable(node, *effect, *control); |
+ result = LowerObjectIsCallable(node); |
break; |
case IrOpcode::kObjectIsNumber: |
- state = LowerObjectIsNumber(node, *effect, *control); |
+ result = LowerObjectIsNumber(node); |
break; |
case IrOpcode::kObjectIsReceiver: |
- state = LowerObjectIsReceiver(node, *effect, *control); |
+ result = LowerObjectIsReceiver(node); |
break; |
case IrOpcode::kObjectIsSmi: |
- state = LowerObjectIsSmi(node, *effect, *control); |
+ result = LowerObjectIsSmi(node); |
break; |
case IrOpcode::kObjectIsString: |
- state = LowerObjectIsString(node, *effect, *control); |
+ result = LowerObjectIsString(node); |
break; |
case IrOpcode::kObjectIsUndetectable: |
- state = LowerObjectIsUndetectable(node, *effect, *control); |
+ result = LowerObjectIsUndetectable(node); |
break; |
case IrOpcode::kNewRestParameterElements: |
- state = LowerNewRestParameterElements(node, *effect, *control); |
+ result = LowerNewRestParameterElements(node); |
break; |
case IrOpcode::kNewUnmappedArgumentsElements: |
- state = LowerNewUnmappedArgumentsElements(node, *effect, *control); |
+ result = LowerNewUnmappedArgumentsElements(node); |
break; |
case IrOpcode::kArrayBufferWasNeutered: |
- state = LowerArrayBufferWasNeutered(node, *effect, *control); |
+ result = LowerArrayBufferWasNeutered(node); |
break; |
case IrOpcode::kStringFromCharCode: |
- state = LowerStringFromCharCode(node, *effect, *control); |
+ result = LowerStringFromCharCode(node); |
break; |
case IrOpcode::kStringFromCodePoint: |
- state = LowerStringFromCodePoint(node, *effect, *control); |
+ result = LowerStringFromCodePoint(node); |
break; |
case IrOpcode::kStringCharAt: |
- state = LowerStringCharAt(node, *effect, *control); |
+ result = LowerStringCharAt(node); |
break; |
case IrOpcode::kStringCharCodeAt: |
- state = LowerStringCharCodeAt(node, *effect, *control); |
+ result = LowerStringCharCodeAt(node); |
break; |
case IrOpcode::kStringEqual: |
- state = LowerStringEqual(node, *effect, *control); |
+ result = LowerStringEqual(node); |
break; |
case IrOpcode::kStringLessThan: |
- state = LowerStringLessThan(node, *effect, *control); |
+ result = LowerStringLessThan(node); |
break; |
case IrOpcode::kStringLessThanOrEqual: |
- state = LowerStringLessThanOrEqual(node, *effect, *control); |
+ result = LowerStringLessThanOrEqual(node); |
break; |
case IrOpcode::kCheckFloat64Hole: |
- state = LowerCheckFloat64Hole(node, frame_state, *effect, *control); |
+ result = LowerCheckFloat64Hole(node, frame_state); |
break; |
case IrOpcode::kCheckTaggedHole: |
- state = LowerCheckTaggedHole(node, frame_state, *effect, *control); |
+ result = LowerCheckTaggedHole(node, frame_state); |
break; |
case IrOpcode::kConvertTaggedHoleToUndefined: |
- state = LowerConvertTaggedHoleToUndefined(node, *effect, *control); |
+ result = LowerConvertTaggedHoleToUndefined(node); |
break; |
case IrOpcode::kPlainPrimitiveToNumber: |
- state = LowerPlainPrimitiveToNumber(node, *effect, *control); |
+ result = LowerPlainPrimitiveToNumber(node); |
break; |
case IrOpcode::kPlainPrimitiveToWord32: |
- state = LowerPlainPrimitiveToWord32(node, *effect, *control); |
+ result = LowerPlainPrimitiveToWord32(node); |
break; |
case IrOpcode::kPlainPrimitiveToFloat64: |
- state = LowerPlainPrimitiveToFloat64(node, *effect, *control); |
+ result = LowerPlainPrimitiveToFloat64(node); |
break; |
case IrOpcode::kEnsureWritableFastElements: |
- state = LowerEnsureWritableFastElements(node, *effect, *control); |
+ result = LowerEnsureWritableFastElements(node); |
break; |
case IrOpcode::kMaybeGrowFastElements: |
- state = LowerMaybeGrowFastElements(node, frame_state, *effect, *control); |
+ result = LowerMaybeGrowFastElements(node, frame_state); |
break; |
case IrOpcode::kTransitionElementsKind: |
- state = LowerTransitionElementsKind(node, *effect, *control); |
+ LowerTransitionElementsKind(node); |
break; |
case IrOpcode::kLoadTypedElement: |
- state = LowerLoadTypedElement(node, *effect, *control); |
+ result = LowerLoadTypedElement(node); |
break; |
case IrOpcode::kStoreTypedElement: |
- state = LowerStoreTypedElement(node, *effect, *control); |
+ LowerStoreTypedElement(node); |
break; |
case IrOpcode::kFloat64RoundUp: |
- state = LowerFloat64RoundUp(node, *effect, *control); |
+ if (!LowerFloat64RoundUp(node).To(&result)) { |
+ return false; |
+ } |
break; |
case IrOpcode::kFloat64RoundDown: |
- state = LowerFloat64RoundDown(node, *effect, *control); |
+ if (!LowerFloat64RoundDown(node).To(&result)) { |
+ return false; |
+ } |
break; |
case IrOpcode::kFloat64RoundTruncate: |
- state = LowerFloat64RoundTruncate(node, *effect, *control); |
+ if (!LowerFloat64RoundTruncate(node).To(&result)) { |
+ return false; |
+ } |
break; |
case IrOpcode::kFloat64RoundTiesEven: |
- state = LowerFloat64RoundTiesEven(node, *effect, *control); |
+ if (!LowerFloat64RoundTiesEven(node).To(&result)) { |
+ return false; |
+ } |
break; |
default: |
return false; |
} |
- NodeProperties::ReplaceUses(node, state.value, state.effect, state.control); |
- *effect = state.effect; |
- *control = state.control; |
+ *effect = gasm()->ExtractCurrentEffect(); |
+ *control = gasm()->ExtractCurrentControl(); |
+ NodeProperties::ReplaceUses(node, result, *effect, *control); |
return true; |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node, Node* effect, |
- Node* control) { |
+#define __ gasm()-> |
+ |
+Node* EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node) { |
Node* value = node->InputAt(0); |
- return AllocateHeapNumberWithValue(value, effect, control); |
+ return AllocateHeapNumberWithValue(value); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerChangeFloat64ToTaggedPointer(Node* node, |
- Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerChangeFloat64ToTaggedPointer(Node* node) { |
Node* value = node->InputAt(0); |
- return AllocateHeapNumberWithValue(value, effect, control); |
+ return AllocateHeapNumberWithValue(value); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerChangeBitToTagged(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerChangeBitToTagged(Node* node) { |
Node* value = node->InputAt(0); |
- Node* branch = graph()->NewNode(common()->Branch(), value, control); |
- |
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
- Node* vtrue = jsgraph()->TrueConstant(); |
+ auto if_true = __ MakeLabel<1>(); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kTagged); |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
- Node* vfalse = jsgraph()->FalseConstant(); |
+ __ GotoIf(value, &if_true); |
+ __ Goto(&done, __ FalseConstant()); |
- control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
- value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
- vtrue, vfalse, control); |
+ __ Bind(&if_true); |
+ __ Goto(&done, __ TrueConstant()); |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerChangeInt31ToTaggedSigned(Node* node, |
- Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerChangeInt31ToTaggedSigned(Node* node) { |
Node* value = node->InputAt(0); |
- value = ChangeInt32ToSmi(value); |
- return ValueEffectControl(value, effect, control); |
+ return ChangeInt32ToSmi(value); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerChangeInt32ToTagged(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerChangeInt32ToTagged(Node* node) { |
Node* value = node->InputAt(0); |
if (machine()->Is64()) { |
- return ValueEffectControl(ChangeInt32ToSmi(value), effect, control); |
+ return ChangeInt32ToSmi(value); |
} |
- Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value, |
- control); |
+ auto if_overflow = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kTagged); |
- Node* ovf = graph()->NewNode(common()->Projection(1), add, control); |
- Node* branch = |
- graph()->NewNode(common()->Branch(BranchHint::kFalse), ovf, control); |
+ Node* add = __ Int32AddWithOverflow(value, value); |
+ Node* ovf = __ Projection(1, add); |
+ __ GotoIf(ovf, &if_overflow); |
+ __ Goto(&done, __ Projection(0, add)); |
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
- ValueEffectControl alloc = |
- AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), effect, if_true); |
+ __ Bind(&if_overflow); |
+ Node* number = AllocateHeapNumberWithValue(__ ChangeInt32ToFloat64(value)); |
+ __ Goto(&done, number); |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
- Node* vfalse = graph()->NewNode(common()->Projection(0), add, if_false); |
- |
- Node* merge = graph()->NewNode(common()->Merge(2), alloc.control, if_false); |
- Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
- alloc.value, vfalse, merge); |
- Node* ephi = |
- graph()->NewNode(common()->EffectPhi(2), alloc.effect, effect, merge); |
- |
- return ValueEffectControl(phi, ephi, merge); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerChangeUint32ToTagged(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerChangeUint32ToTagged(Node* node) { |
Node* value = node->InputAt(0); |
- Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, |
- SmiMaxValueConstant()); |
- Node* branch = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
+ auto if_not_in_smi_range = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kTagged); |
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
- Node* vtrue = ChangeUint32ToSmi(value); |
+ Node* check = __ Uint32LessThanOrEqual(value, SmiMaxValueConstant()); |
+ __ GotoUnless(check, &if_not_in_smi_range); |
+ __ Goto(&done, ChangeUint32ToSmi(value)); |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
- ValueEffectControl alloc = AllocateHeapNumberWithValue( |
- ChangeUint32ToFloat64(value), effect, if_false); |
+ __ Bind(&if_not_in_smi_range); |
+ Node* number = AllocateHeapNumberWithValue(__ ChangeUint32ToFloat64(value)); |
- Node* merge = graph()->NewNode(common()->Merge(2), if_true, alloc.control); |
- Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
- vtrue, alloc.value, merge); |
- Node* ephi = |
- graph()->NewNode(common()->EffectPhi(2), effect, alloc.effect, merge); |
+ __ Goto(&done, number); |
+ __ Bind(&done); |
- return ValueEffectControl(phi, ephi, merge); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerChangeTaggedSignedToInt32(Node* node, |
- Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerChangeTaggedSignedToInt32(Node* node) { |
Node* value = node->InputAt(0); |
- value = ChangeSmiToInt32(value); |
- return ValueEffectControl(value, effect, control); |
+ return ChangeSmiToInt32(value); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerChangeTaggedToBit(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerChangeTaggedToBit(Node* node) { |
Node* value = node->InputAt(0); |
- value = graph()->NewNode(machine()->WordEqual(), value, |
- jsgraph()->TrueConstant()); |
- return ValueEffectControl(value, effect, control); |
+ return __ WordEqual(value, __ TrueConstant()); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node) { |
Node* value = node->InputAt(0); |
- Node* zero = jsgraph()->Int32Constant(0); |
- Node* fzero = jsgraph()->Float64Constant(0.0); |
- // Collect effect/control/value triples. |
- int count = 0; |
- Node* values[6]; |
- Node* effects[6]; |
- Node* controls[5]; |
+ auto if_smi = __ MakeDeferredLabel<1>(); |
+ auto if_not_oddball = __ MakeDeferredLabel<1>(); |
+ auto if_not_string = __ MakeDeferredLabel<1>(); |
+ auto if_not_heapnumber = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<5>(MachineRepresentation::kBit); |
+ |
+ Node* zero = __ Int32Constant(0); |
+ Node* fzero = __ Float64Constant(0.0); |
// Check if {value} is a Smi. |
Node* check_smi = ObjectIsSmi(value); |
- Node* branch_smi = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
- check_smi, control); |
- |
- // If {value} is a Smi, then we only need to check that it's not zero. |
- Node* if_smi = graph()->NewNode(common()->IfTrue(), branch_smi); |
- Node* esmi = effect; |
- { |
- controls[count] = if_smi; |
- effects[count] = esmi; |
- values[count] = |
- graph()->NewNode(machine()->Word32Equal(), |
- graph()->NewNode(machine()->WordEqual(), value, |
- jsgraph()->IntPtrConstant(0)), |
- zero); |
- count++; |
- } |
- control = graph()->NewNode(common()->IfFalse(), branch_smi); |
+ __ GotoIf(check_smi, &if_smi); |
// Load the map instance type of {value}. |
- Node* value_map = effect = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control); |
- Node* value_instance_type = effect = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map, |
- effect, control); |
+ Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); |
+ Node* value_instance_type = |
+ __ LoadField(AccessBuilder::ForMapInstanceType(), value_map); |
// Check if {value} is an Oddball. |
Node* check_oddball = |
- graph()->NewNode(machine()->Word32Equal(), value_instance_type, |
- jsgraph()->Int32Constant(ODDBALL_TYPE)); |
- Node* branch_oddball = graph()->NewNode(common()->Branch(BranchHint::kTrue), |
- check_oddball, control); |
+ __ Word32Equal(value_instance_type, __ Int32Constant(ODDBALL_TYPE)); |
+ __ GotoUnless(check_oddball, &if_not_oddball); |
// The only Oddball {value} that is trueish is true itself. |
- Node* if_oddball = graph()->NewNode(common()->IfTrue(), branch_oddball); |
- Node* eoddball = effect; |
- { |
- controls[count] = if_oddball; |
- effects[count] = eoddball; |
- values[count] = graph()->NewNode(machine()->WordEqual(), value, |
- jsgraph()->TrueConstant()); |
- count++; |
- } |
- control = graph()->NewNode(common()->IfFalse(), branch_oddball); |
+ __ Goto(&done, __ WordEqual(value, __ TrueConstant())); |
+ __ Bind(&if_not_oddball); |
// Check if {value} is a String. |
- Node* check_string = |
- graph()->NewNode(machine()->Int32LessThan(), value_instance_type, |
- jsgraph()->Int32Constant(FIRST_NONSTRING_TYPE)); |
- Node* branch_string = |
- graph()->NewNode(common()->Branch(), check_string, control); |
- |
+ Node* check_string = __ Int32LessThan(value_instance_type, |
+ __ Int32Constant(FIRST_NONSTRING_TYPE)); |
+ __ GotoUnless(check_string, &if_not_string); |
// For String {value}, we need to check that the length is not zero. |
- Node* if_string = graph()->NewNode(common()->IfTrue(), branch_string); |
- Node* estring = effect; |
- { |
- // Load the {value} length. |
- Node* value_length = estring = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForStringLength()), value, |
- estring, if_string); |
- |
- controls[count] = if_string; |
- effects[count] = estring; |
- values[count] = |
- graph()->NewNode(machine()->Word32Equal(), |
- graph()->NewNode(machine()->WordEqual(), value_length, |
- jsgraph()->IntPtrConstant(0)), |
- zero); |
- count++; |
- } |
- control = graph()->NewNode(common()->IfFalse(), branch_string); |
+ Node* value_length = __ LoadField(AccessBuilder::ForStringLength(), value); |
+ __ Goto(&done, __ Word32Equal( |
+ __ WordEqual(value_length, __ IntPtrConstant(0)), zero)); |
+ __ Bind(&if_not_string); |
// Check if {value} is a HeapNumber. |
Node* check_heapnumber = |
- graph()->NewNode(machine()->Word32Equal(), value_instance_type, |
- jsgraph()->Int32Constant(HEAP_NUMBER_TYPE)); |
- Node* branch_heapnumber = |
- graph()->NewNode(common()->Branch(), check_heapnumber, control); |
- |
- // For HeapNumber {value}, just check that its value is not 0.0, -0.0 or NaN. |
- Node* if_heapnumber = graph()->NewNode(common()->IfTrue(), branch_heapnumber); |
- Node* eheapnumber = effect; |
- { |
- // Load the raw value of {value}. |
- Node* value_value = eheapnumber = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value, |
- eheapnumber, if_heapnumber); |
- |
- // Check if {value} is not one of 0, -0, or NaN. |
- controls[count] = if_heapnumber; |
- effects[count] = eheapnumber; |
- values[count] = graph()->NewNode( |
- machine()->Float64LessThan(), fzero, |
- graph()->NewNode(machine()->Float64Abs(), value_value)); |
- count++; |
- } |
- control = graph()->NewNode(common()->IfFalse(), branch_heapnumber); |
+ __ Word32Equal(value_instance_type, __ Int32Constant(HEAP_NUMBER_TYPE)); |
+ __ GotoUnless(check_heapnumber, &if_not_heapnumber); |
+ |
+ // For HeapNumber {value}, just check that its value is not 0.0, -0.0 or |
+ // NaN. |
+ // Load the raw value of {value}. |
+ Node* value_value = __ LoadField(AccessBuilder::ForHeapNumberValue(), value); |
+ __ Goto(&done, __ Float64LessThan(fzero, __ Float64Abs(value_value))); |
// The {value} is either a JSReceiver, a Symbol or some Simd128Value. In |
// those cases we can just the undetectable bit on the map, which will only |
// be set for certain JSReceivers, i.e. document.all. |
- { |
- // Load the {value} map bit field. |
- Node* value_map_bitfield = effect = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map, |
- effect, control); |
- |
- controls[count] = control; |
- effects[count] = effect; |
- values[count] = graph()->NewNode( |
- machine()->Word32Equal(), |
- graph()->NewNode(machine()->Word32And(), value_map_bitfield, |
- jsgraph()->Int32Constant(1 << Map::kIsUndetectable)), |
- zero); |
- count++; |
- } |
+ __ Bind(&if_not_heapnumber); |
+ |
+ // Load the {value} map bit field. |
+ Node* value_map_bitfield = |
+ __ LoadField(AccessBuilder::ForMapBitField(), value_map); |
+ __ Goto(&done, __ Word32Equal( |
+ __ Word32And(value_map_bitfield, |
+ __ Int32Constant(1 << Map::kIsUndetectable)), |
+ zero)); |
- // Merge the different controls. |
- control = graph()->NewNode(common()->Merge(count), count, controls); |
- effects[count] = control; |
- effect = graph()->NewNode(common()->EffectPhi(count), count + 1, effects); |
- values[count] = control; |
- value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, count), |
- count + 1, values); |
+ __ Bind(&if_smi); |
+ // If {value} is a Smi, then we only need to check that it's not zero. |
+ __ Goto(&done, |
+ __ Word32Equal(__ WordEqual(value, __ IntPtrConstant(0)), zero)); |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node) { |
Node* value = node->InputAt(0); |
- Node* check = ObjectIsSmi(value); |
- Node* branch = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
- |
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
- Node* etrue = effect; |
- Node* vtrue = ChangeSmiToInt32(value); |
+ auto if_not_smi = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kWord32); |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
- Node* efalse = effect; |
- Node* vfalse; |
- { |
- STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset); |
- vfalse = efalse = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value, |
- efalse, if_false); |
- vfalse = graph()->NewNode(machine()->ChangeFloat64ToInt32(), vfalse); |
- } |
+ Node* check = ObjectIsSmi(value); |
+ __ GotoUnless(check, &if_not_smi); |
+ __ Goto(&done, ChangeSmiToInt32(value)); |
- control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
- value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), |
- vtrue, vfalse, control); |
+ __ Bind(&if_not_smi); |
+ STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset); |
+ Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value); |
+ vfalse = __ ChangeFloat64ToInt32(vfalse); |
+ __ Goto(&done, vfalse); |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerChangeTaggedToUint32(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerChangeTaggedToUint32(Node* node) { |
Node* value = node->InputAt(0); |
- Node* check = ObjectIsSmi(value); |
- Node* branch = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
- |
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
- Node* etrue = effect; |
- Node* vtrue = ChangeSmiToInt32(value); |
+ auto if_not_smi = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kWord32); |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
- Node* efalse = effect; |
- Node* vfalse; |
- { |
- STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset); |
- vfalse = efalse = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value, |
- efalse, if_false); |
- vfalse = graph()->NewNode(machine()->ChangeFloat64ToUint32(), vfalse); |
- } |
+ Node* check = ObjectIsSmi(value); |
+ __ GotoUnless(check, &if_not_smi); |
+ __ Goto(&done, ChangeSmiToInt32(value)); |
- control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
- value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), |
- vtrue, vfalse, control); |
+ __ Bind(&if_not_smi); |
+ STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset); |
+ Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value); |
+ vfalse = __ ChangeFloat64ToUint32(vfalse); |
+ __ Goto(&done, vfalse); |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerChangeTaggedToFloat64(Node* node, Node* effect, |
- Node* control) { |
- return LowerTruncateTaggedToFloat64(node, effect, control); |
+Node* EffectControlLinearizer::LowerChangeTaggedToFloat64(Node* node) { |
+ return LowerTruncateTaggedToFloat64(node); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerTruncateTaggedToFloat64(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerTruncateTaggedToFloat64(Node* node) { |
Node* value = node->InputAt(0); |
- Node* check = ObjectIsSmi(value); |
- Node* branch = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
+ auto if_not_smi = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kFloat64); |
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
- Node* etrue = effect; |
- Node* vtrue; |
- { |
- vtrue = ChangeSmiToInt32(value); |
- vtrue = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue); |
- } |
- |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
- Node* efalse = effect; |
- Node* vfalse; |
- { |
- STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset); |
- vfalse = efalse = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value, |
- efalse, if_false); |
- } |
+ Node* check = ObjectIsSmi(value); |
+ __ GotoUnless(check, &if_not_smi); |
+ Node* vtrue = ChangeSmiToInt32(value); |
+ vtrue = __ ChangeInt32ToFloat64(vtrue); |
+ __ Goto(&done, vtrue); |
- control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
- value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
- vtrue, vfalse, control); |
+ __ Bind(&if_not_smi); |
+ STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset); |
+ Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value); |
+ __ Goto(&done, vfalse); |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckBounds(Node* node, Node* frame_state, |
- Node* effect, Node* control) { |
+Node* EffectControlLinearizer::LowerCheckBounds(Node* node, Node* frame_state) { |
Node* index = node->InputAt(0); |
Node* limit = node->InputAt(1); |
- Node* check = graph()->NewNode(machine()->Uint32LessThan(), index, limit); |
- control = effect = graph()->NewNode( |
- common()->DeoptimizeUnless(DeoptimizeReason::kOutOfBounds), check, |
- frame_state, effect, control); |
- |
- return ValueEffectControl(index, effect, control); |
+ Node* check = __ Uint32LessThan(index, limit); |
+ __ DeoptimizeUnless(DeoptimizeReason::kOutOfBounds, check, frame_state); |
+ return index; |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state, |
- Node* effect, Node* control) { |
+Node* EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) { |
CheckMapsParameters const& p = CheckMapsParametersOf(node->op()); |
Node* value = node->InputAt(0); |
- // Load the current map of the {value}. |
- Node* value_map = effect = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control); |
- |
ZoneHandleSet<Map> const& maps = p.maps(); |
int const map_count = static_cast<int>(maps.size()); |
- Node** controls = temp_zone()->NewArray<Node*>(map_count); |
- Node** effects = temp_zone()->NewArray<Node*>(map_count + 1); |
- for (int i = 0; i < map_count; ++i) { |
- Node* map = jsgraph()->HeapConstant(maps[i]); |
+ auto done = __ MakeLabelFor(GraphAssemblerLabelType::kNonDeferred, |
+ static_cast<size_t>(map_count)); |
- Node* check = graph()->NewNode(machine()->WordEqual(), value_map, map); |
+ // Load the current map of the {value}. |
+ Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); |
+ |
+ for (int i = 0; i < map_count; ++i) { |
+ Node* map = __ HeapConstant(maps[i]); |
+ Node* check = __ WordEqual(value_map, map); |
if (i == map_count - 1) { |
- controls[i] = effects[i] = graph()->NewNode( |
- common()->DeoptimizeUnless(DeoptimizeReason::kWrongMap), check, |
- frame_state, effect, control); |
+ __ DeoptimizeUnless(DeoptimizeReason::kWrongMap, check, frame_state); |
} else { |
- control = graph()->NewNode(common()->Branch(), check, control); |
- controls[i] = graph()->NewNode(common()->IfTrue(), control); |
- control = graph()->NewNode(common()->IfFalse(), control); |
- effects[i] = effect; |
+ __ GotoIf(check, &done); |
} |
} |
- |
- control = graph()->NewNode(common()->Merge(map_count), map_count, controls); |
- effects[map_count] = control; |
- effect = |
- graph()->NewNode(common()->EffectPhi(map_count), map_count + 1, effects); |
- |
- return ValueEffectControl(value, effect, control); |
+ __ Goto(&done); |
+ __ Bind(&done); |
+ return value; |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckNumber(Node* node, Node* frame_state, |
- Node* effect, Node* control) { |
+Node* EffectControlLinearizer::LowerCheckNumber(Node* node, Node* frame_state) { |
Node* value = node->InputAt(0); |
- Node* check0 = ObjectIsSmi(value); |
- Node* branch0 = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); |
- |
- Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
- Node* etrue0 = effect; |
+ auto if_not_smi = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<2>(); |
- Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
- Node* efalse0 = effect; |
- { |
- Node* value_map = efalse0 = |
- graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
- value, efalse0, if_false0); |
- Node* check1 = graph()->NewNode(machine()->WordEqual(), value_map, |
- jsgraph()->HeapNumberMapConstant()); |
- if_false0 = efalse0 = graph()->NewNode( |
- common()->DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber), check1, |
- frame_state, efalse0, if_false0); |
- } |
+ Node* check0 = ObjectIsSmi(value); |
+ __ GotoUnless(check0, &if_not_smi); |
+ __ Goto(&done); |
- control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); |
+ __ Bind(&if_not_smi); |
+ Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); |
+ Node* check1 = __ WordEqual(value_map, __ HeapNumberMapConstant()); |
+ __ DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber, check1, frame_state); |
+ __ Goto(&done); |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return value; |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckString(Node* node, Node* frame_state, |
- Node* effect, Node* control) { |
+Node* EffectControlLinearizer::LowerCheckString(Node* node, Node* frame_state) { |
Node* value = node->InputAt(0); |
Node* check0 = ObjectIsSmi(value); |
- control = effect = |
- graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kSmi), check0, |
- frame_state, effect, control); |
- |
- Node* value_map = effect = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control); |
- Node* value_instance_type = effect = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map, |
- effect, control); |
- |
- Node* check1 = |
- graph()->NewNode(machine()->Uint32LessThan(), value_instance_type, |
- jsgraph()->Uint32Constant(FIRST_NONSTRING_TYPE)); |
- control = effect = graph()->NewNode( |
- common()->DeoptimizeUnless(DeoptimizeReason::kWrongInstanceType), check1, |
- frame_state, effect, control); |
- |
- return ValueEffectControl(value, effect, control); |
-} |
- |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckInternalizedString(Node* node, |
- Node* frame_state, |
- Node* effect, |
- Node* control) { |
- Node* value = node->InputAt(0); |
+ __ DeoptimizeIf(DeoptimizeReason::kSmi, check0, frame_state); |
- Node* check0 = ObjectIsSmi(value); |
- control = effect = |
- graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kSmi), check0, |
- frame_state, effect, control); |
- |
- Node* value_map = effect = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control); |
- Node* value_instance_type = effect = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map, |
- effect, control); |
- |
- Node* check1 = graph()->NewNode( |
- machine()->Word32Equal(), |
- graph()->NewNode( |
- machine()->Word32And(), value_instance_type, |
- jsgraph()->Int32Constant(kIsNotStringMask | kIsNotInternalizedMask)), |
- jsgraph()->Int32Constant(kInternalizedTag)); |
- control = effect = graph()->NewNode( |
- common()->DeoptimizeUnless(DeoptimizeReason::kWrongInstanceType), check1, |
- frame_state, effect, control); |
- |
- return ValueEffectControl(value, effect, control); |
-} |
- |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state, |
- Node* effect, Node* control) { |
- Node* value = node->InputAt(0); |
+ Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); |
+ Node* value_instance_type = |
+ __ LoadField(AccessBuilder::ForMapInstanceType(), value_map); |
- control = effect = |
- graph()->NewNode(common()->DeoptimizeUnless(DeoptimizeReason::kNoReason), |
- value, frame_state, effect, control); |
- |
- return ValueEffectControl(value, effect, control); |
+ Node* check1 = __ Uint32LessThan(value_instance_type, |
+ __ Uint32Constant(FIRST_NONSTRING_TYPE)); |
+ __ DeoptimizeUnless(DeoptimizeReason::kWrongInstanceType, check1, |
+ frame_state); |
+ return value; |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckedInt32Add(Node* node, Node* frame_state, |
- Node* effect, Node* control) { |
- Node* lhs = node->InputAt(0); |
- Node* rhs = node->InputAt(1); |
+Node* EffectControlLinearizer::LowerCheckInternalizedString(Node* node, |
+ Node* frame_state) { |
+ Node* value = node->InputAt(0); |
- Node* value = |
- graph()->NewNode(machine()->Int32AddWithOverflow(), lhs, rhs, control); |
+ Node* check0 = ObjectIsSmi(value); |
+ __ DeoptimizeIf(DeoptimizeReason::kSmi, check0, frame_state); |
- Node* check = graph()->NewNode(common()->Projection(1), value, control); |
- control = effect = |
- graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow), |
- check, frame_state, effect, control); |
+ Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); |
+ Node* value_instance_type = |
+ __ LoadField(AccessBuilder::ForMapInstanceType(), value_map); |
- value = graph()->NewNode(common()->Projection(0), value, control); |
+ Node* check1 = __ Word32Equal( |
+ __ Word32And(value_instance_type, |
+ __ Int32Constant(kIsNotStringMask | kIsNotInternalizedMask)), |
+ __ Int32Constant(kInternalizedTag)); |
+ __ DeoptimizeUnless(DeoptimizeReason::kWrongInstanceType, check1, |
+ frame_state); |
- return ValueEffectControl(value, effect, control); |
+ return value; |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckedInt32Sub(Node* node, Node* frame_state, |
- Node* effect, Node* control) { |
+Node* EffectControlLinearizer::LowerCheckIf(Node* node, Node* frame_state) { |
+ Node* value = node->InputAt(0); |
+ __ DeoptimizeUnless(DeoptimizeReason::kNoReason, value, frame_state); |
+ return value; |
+} |
+ |
+Node* EffectControlLinearizer::LowerCheckedInt32Add(Node* node, |
+ Node* frame_state) { |
Node* lhs = node->InputAt(0); |
Node* rhs = node->InputAt(1); |
- Node* value = |
- graph()->NewNode(machine()->Int32SubWithOverflow(), lhs, rhs, control); |
- |
- Node* check = graph()->NewNode(common()->Projection(1), value, control); |
- control = effect = |
- graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow), |
- check, frame_state, effect, control); |
+ Node* value = __ Int32AddWithOverflow(lhs, rhs); |
+ Node* check = __ Projection(1, value); |
+ __ DeoptimizeIf(DeoptimizeReason::kOverflow, check, frame_state); |
+ return __ Projection(0, value); |
+} |
- value = graph()->NewNode(common()->Projection(0), value, control); |
+Node* EffectControlLinearizer::LowerCheckedInt32Sub(Node* node, |
+ Node* frame_state) { |
+ Node* lhs = node->InputAt(0); |
+ Node* rhs = node->InputAt(1); |
- return ValueEffectControl(value, effect, control); |
+ Node* value = __ Int32SubWithOverflow(lhs, rhs); |
+ Node* check = __ Projection(1, value); |
+ __ DeoptimizeIf(DeoptimizeReason::kOverflow, check, frame_state); |
+ return __ Projection(0, value); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckedInt32Div(Node* node, Node* frame_state, |
- Node* effect, Node* control) { |
- Node* zero = jsgraph()->Int32Constant(0); |
- Node* minusone = jsgraph()->Int32Constant(-1); |
- Node* minint = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::min()); |
- |
+Node* EffectControlLinearizer::LowerCheckedInt32Div(Node* node, |
+ Node* frame_state) { |
Node* lhs = node->InputAt(0); |
Node* rhs = node->InputAt(1); |
+ auto if_not_positive = __ MakeDeferredLabel<1>(); |
+ auto if_is_minint = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kWord32); |
+ auto minint_check_done = __ MakeLabel<2>(); |
+ |
+ Node* zero = __ Int32Constant(0); |
+ |
// Check if {rhs} is positive (and not zero). |
- Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs); |
- Node* branch0 = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); |
+ Node* check0 = __ Int32LessThan(zero, rhs); |
+ __ GotoUnless(check0, &if_not_positive); |
- Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
- Node* etrue0 = effect; |
- Node* vtrue0; |
- { |
- // Fast case, no additional checking required. |
- vtrue0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true0); |
- } |
+ // Fast case, no additional checking required. |
+ __ Goto(&done, __ Int32Div(lhs, rhs)); |
- Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
- Node* efalse0 = effect; |
- Node* vfalse0; |
{ |
+ __ Bind(&if_not_positive); |
+ |
// Check if {rhs} is zero. |
- Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero); |
- if_false0 = efalse0 = graph()->NewNode( |
- common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check, |
- frame_state, efalse0, if_false0); |
+ Node* check = __ Word32Equal(rhs, zero); |
+ __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, check, frame_state); |
// Check if {lhs} is zero, as that would produce minus zero. |
- check = graph()->NewNode(machine()->Word32Equal(), lhs, zero); |
- if_false0 = efalse0 = |
- graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero), |
- check, frame_state, efalse0, if_false0); |
+ check = __ Word32Equal(lhs, zero); |
+ __ DeoptimizeIf(DeoptimizeReason::kMinusZero, check, frame_state); |
// Check if {lhs} is kMinInt and {rhs} is -1, in which case we'd have |
// to return -kMinInt, which is not representable. |
+ Node* minint = __ Int32Constant(std::numeric_limits<int32_t>::min()); |
Node* check1 = graph()->NewNode(machine()->Word32Equal(), lhs, minint); |
- Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
- check1, if_false0); |
+ __ GotoIf(check1, &if_is_minint); |
+ __ Goto(&minint_check_done); |
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
- Node* etrue1 = efalse0; |
- { |
- // Check if {rhs} is -1. |
- Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, minusone); |
- if_true1 = etrue1 = |
- graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow), |
- check, frame_state, etrue1, if_true1); |
- } |
- |
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
- Node* efalse1 = efalse0; |
- |
- if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
- efalse0 = |
- graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0); |
+ __ Bind(&if_is_minint); |
+ // Check if {rhs} is -1. |
+ Node* minusone = __ Int32Constant(-1); |
+ Node* is_minus_one = __ Word32Equal(rhs, minusone); |
+ __ DeoptimizeIf(DeoptimizeReason::kOverflow, is_minus_one, frame_state); |
+ __ Goto(&minint_check_done); |
+ __ Bind(&minint_check_done); |
// Perform the actual integer division. |
- vfalse0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_false0); |
+ __ Goto(&done, __ Int32Div(lhs, rhs)); |
} |
- control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); |
- Node* value = |
- graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue0, |
- vfalse0, control); |
+ __ Bind(&done); |
+ Node* value = done.PhiAt(0); |
// Check if the remainder is non-zero. |
- Node* check = |
- graph()->NewNode(machine()->Word32Equal(), lhs, |
- graph()->NewNode(machine()->Int32Mul(), rhs, value)); |
- control = effect = graph()->NewNode( |
- common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecision), check, |
- frame_state, effect, control); |
+ Node* check = __ Word32Equal(lhs, __ Int32Mul(rhs, value)); |
+ __ DeoptimizeUnless(DeoptimizeReason::kLostPrecision, check, frame_state); |
- return ValueEffectControl(value, effect, control); |
+ return value; |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckedInt32Mod(Node* node, Node* frame_state, |
- Node* effect, Node* control) { |
- Node* zero = jsgraph()->Int32Constant(0); |
- Node* one = jsgraph()->Int32Constant(1); |
- |
+Node* EffectControlLinearizer::LowerCheckedInt32Mod(Node* node, |
+ Node* frame_state) { |
// General case for signed integer modulus, with optimization for (unknown) |
// power of 2 right hand side. |
// |
@@ -1485,733 +1248,476 @@ EffectControlLinearizer::LowerCheckedInt32Mod(Node* node, Node* frame_state, |
Node* lhs = node->InputAt(0); |
Node* rhs = node->InputAt(1); |
+ auto if_rhs_not_positive = __ MakeDeferredLabel<1>(); |
+ auto if_lhs_negative = __ MakeDeferredLabel<1>(); |
+ auto if_power_of_two = __ MakeLabel<1>(); |
+ auto rhs_checked = __ MakeLabel<2>(MachineRepresentation::kWord32); |
+ auto done = __ MakeLabel<3>(MachineRepresentation::kWord32); |
+ |
+ Node* zero = __ Int32Constant(0); |
+ |
// Check if {rhs} is not strictly positive. |
- Node* check0 = graph()->NewNode(machine()->Int32LessThanOrEqual(), rhs, zero); |
- Node* branch0 = |
- graph()->NewNode(common()->Branch(BranchHint::kFalse), check0, control); |
+ Node* check0 = __ Int32LessThanOrEqual(rhs, zero); |
+ __ GotoIf(check0, &if_rhs_not_positive); |
+ __ Goto(&rhs_checked, rhs); |
- Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
- Node* etrue0 = effect; |
- Node* vtrue0; |
+ __ Bind(&if_rhs_not_positive); |
{ |
// Negate {rhs}, might still produce a negative result in case of |
// -2^31, but that is handled safely below. |
- vtrue0 = graph()->NewNode(machine()->Int32Sub(), zero, rhs); |
+ Node* vtrue0 = __ Int32Sub(zero, rhs); |
// Ensure that {rhs} is not zero, otherwise we'd have to return NaN. |
- Node* check = graph()->NewNode(machine()->Word32Equal(), vtrue0, zero); |
- if_true0 = etrue0 = graph()->NewNode( |
- common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check, |
- frame_state, etrue0, if_true0); |
+ Node* check = __ Word32Equal(vtrue0, zero); |
+ __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, check, frame_state); |
+ __ Goto(&rhs_checked, vtrue0); |
} |
- Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
- Node* efalse0 = effect; |
- Node* vfalse0 = rhs; |
- |
- // At this point {rhs} is either greater than zero or -2^31, both are |
- // fine for the code that follows. |
- control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); |
- rhs = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), |
- vtrue0, vfalse0, control); |
+ __ Bind(&rhs_checked); |
+ rhs = rhs_checked.PhiAt(0); |
// Check if {lhs} is negative. |
- Node* check1 = graph()->NewNode(machine()->Int32LessThan(), lhs, zero); |
- Node* branch1 = |
- graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, control); |
- |
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
- Node* etrue1 = effect; |
- Node* vtrue1; |
- { |
- // Compute the remainder using {lhs % msk}. |
- vtrue1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1); |
- |
- // Check if we would have to return -0. |
- Node* check = graph()->NewNode(machine()->Word32Equal(), vtrue1, zero); |
- if_true1 = etrue1 = |
- graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero), |
- check, frame_state, etrue1, if_true1); |
- } |
+ Node* check1 = __ Int32LessThan(lhs, zero); |
+ __ GotoIf(check1, &if_lhs_negative); |
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
- Node* efalse1 = effect; |
- Node* vfalse1; |
+ // {lhs} non-negative. |
{ |
- Node* msk = graph()->NewNode(machine()->Int32Sub(), rhs, one); |
+ Node* one = __ Int32Constant(1); |
+ Node* msk = __ Int32Sub(rhs, one); |
// Check if {rhs} minus one is a valid mask. |
- Node* check2 = graph()->NewNode( |
- machine()->Word32Equal(), |
- graph()->NewNode(machine()->Word32And(), rhs, msk), zero); |
- Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_false1); |
+ Node* check2 = __ Word32Equal(__ Word32And(rhs, msk), zero); |
+ __ GotoIf(check2, &if_power_of_two); |
+ // Compute the remainder using the generic {lhs % rhs}. |
+ __ Goto(&done, __ Int32Mod(lhs, rhs)); |
+ __ Bind(&if_power_of_two); |
// Compute the remainder using {lhs & msk}. |
- Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); |
- Node* vtrue2 = graph()->NewNode(machine()->Word32And(), lhs, msk); |
+ __ Goto(&done, __ Word32And(lhs, msk)); |
+ } |
- // Compute the remainder using the generic {lhs % rhs}. |
- Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); |
- Node* vfalse2 = |
- graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_false2); |
+ __ Bind(&if_lhs_negative); |
+ { |
+ // Compute the remainder using {lhs % msk}. |
+ Node* vtrue1 = __ Int32Mod(lhs, rhs); |
- if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); |
- vfalse1 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), |
- vtrue2, vfalse2, if_false1); |
+ // Check if we would have to return -0. |
+ Node* check = __ Word32Equal(vtrue1, zero); |
+ __ DeoptimizeIf(DeoptimizeReason::kMinusZero, check, frame_state); |
+ __ Goto(&done, vtrue1); |
} |
- control = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, control); |
- Node* value = |
- graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue1, |
- vfalse1, control); |
- |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckedUint32Div(Node* node, Node* frame_state, |
- Node* effect, Node* control) { |
- Node* zero = jsgraph()->Int32Constant(0); |
- |
+Node* EffectControlLinearizer::LowerCheckedUint32Div(Node* node, |
+ Node* frame_state) { |
Node* lhs = node->InputAt(0); |
Node* rhs = node->InputAt(1); |
+ Node* zero = __ Int32Constant(0); |
+ |
// Ensure that {rhs} is not zero, otherwise we'd have to return NaN. |
- Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero); |
- control = effect = graph()->NewNode( |
- common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check, |
- frame_state, effect, control); |
+ Node* check = __ Word32Equal(rhs, zero); |
+ __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, check, frame_state); |
// Perform the actual unsigned integer division. |
- Node* value = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, control); |
+ Node* value = __ Uint32Div(lhs, rhs); |
// Check if the remainder is non-zero. |
- check = graph()->NewNode(machine()->Word32Equal(), lhs, |
- graph()->NewNode(machine()->Int32Mul(), rhs, value)); |
- control = effect = graph()->NewNode( |
- common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecision), check, |
- frame_state, effect, control); |
- |
- return ValueEffectControl(value, effect, control); |
+ check = __ Word32Equal(lhs, __ Int32Mul(rhs, value)); |
+ __ DeoptimizeUnless(DeoptimizeReason::kLostPrecision, check, frame_state); |
+ return value; |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckedUint32Mod(Node* node, Node* frame_state, |
- Node* effect, Node* control) { |
- Node* zero = jsgraph()->Int32Constant(0); |
- |
+Node* EffectControlLinearizer::LowerCheckedUint32Mod(Node* node, |
+ Node* frame_state) { |
Node* lhs = node->InputAt(0); |
Node* rhs = node->InputAt(1); |
+ Node* zero = __ Int32Constant(0); |
+ |
// Ensure that {rhs} is not zero, otherwise we'd have to return NaN. |
- Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero); |
- control = effect = graph()->NewNode( |
- common()->DeoptimizeIf(DeoptimizeReason::kDivisionByZero), check, |
- frame_state, effect, control); |
+ Node* check = __ Word32Equal(rhs, zero); |
+ __ DeoptimizeIf(DeoptimizeReason::kDivisionByZero, check, frame_state); |
// Perform the actual unsigned integer modulus. |
- Node* value = graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, control); |
- |
- return ValueEffectControl(value, effect, control); |
+ return __ Uint32Mod(lhs, rhs); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckedInt32Mul(Node* node, Node* frame_state, |
- Node* effect, Node* control) { |
+Node* EffectControlLinearizer::LowerCheckedInt32Mul(Node* node, |
+ Node* frame_state) { |
CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op()); |
- Node* zero = jsgraph()->Int32Constant(0); |
Node* lhs = node->InputAt(0); |
Node* rhs = node->InputAt(1); |
- Node* projection = |
- graph()->NewNode(machine()->Int32MulWithOverflow(), lhs, rhs, control); |
- |
- Node* check = graph()->NewNode(common()->Projection(1), projection, control); |
- control = effect = |
- graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow), |
- check, frame_state, effect, control); |
+ Node* projection = __ Int32MulWithOverflow(lhs, rhs); |
+ Node* check = __ Projection(1, projection); |
+ __ DeoptimizeIf(DeoptimizeReason::kOverflow, check, frame_state); |
- Node* value = graph()->NewNode(common()->Projection(0), projection, control); |
+ Node* value = __ Projection(0, projection); |
if (mode == CheckForMinusZeroMode::kCheckForMinusZero) { |
- Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value, zero); |
- Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
- check_zero, control); |
+ auto if_zero = __ MakeDeferredLabel<1>(); |
+ auto check_done = __ MakeLabel<2>(); |
+ Node* zero = __ Int32Constant(0); |
+ Node* check_zero = __ Word32Equal(value, zero); |
+ __ GotoIf(check_zero, &if_zero); |
+ __ Goto(&check_done); |
- Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero); |
- Node* e_if_zero = effect; |
- { |
- // We may need to return negative zero. |
- Node* or_inputs = graph()->NewNode(machine()->Word32Or(), lhs, rhs); |
- Node* check_or = |
- graph()->NewNode(machine()->Int32LessThan(), or_inputs, zero); |
- if_zero = e_if_zero = |
- graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero), |
- check_or, frame_state, e_if_zero, if_zero); |
- } |
- |
- Node* if_not_zero = graph()->NewNode(common()->IfFalse(), branch_zero); |
- Node* e_if_not_zero = effect; |
+ __ Bind(&if_zero); |
+ // We may need to return negative zero. |
+ Node* check_or = __ Int32LessThan(__ Word32Or(lhs, rhs), zero); |
+ __ DeoptimizeIf(DeoptimizeReason::kMinusZero, check_or, frame_state); |
+ __ Goto(&check_done); |
- control = graph()->NewNode(common()->Merge(2), if_zero, if_not_zero); |
- effect = graph()->NewNode(common()->EffectPhi(2), e_if_zero, e_if_not_zero, |
- control); |
+ __ Bind(&check_done); |
} |
- return ValueEffectControl(value, effect, control); |
+ return value; |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckedInt32ToTaggedSigned(Node* node, |
- Node* frame_state, |
- Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerCheckedInt32ToTaggedSigned( |
+ Node* node, Node* frame_state) { |
DCHECK(SmiValuesAre31Bits()); |
Node* value = node->InputAt(0); |
- Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value, |
- control); |
- |
- Node* check = graph()->NewNode(common()->Projection(1), add, control); |
- control = effect = |
- graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kOverflow), |
- check, frame_state, effect, control); |
- |
- value = graph()->NewNode(common()->Projection(0), add, control); |
- |
- return ValueEffectControl(value, effect, control); |
+ Node* add = __ Int32AddWithOverflow(value, value); |
+ Node* check = __ Projection(1, add); |
+ __ DeoptimizeIf(DeoptimizeReason::kOverflow, check, frame_state); |
+ return __ Projection(0, add); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node, |
- Node* frame_state, |
- Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerCheckedUint32ToInt32(Node* node, |
+ Node* frame_state) { |
Node* value = node->InputAt(0); |
- Node* max_int = jsgraph()->Int32Constant(std::numeric_limits<int32_t>::max()); |
- Node* is_safe = |
- graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, max_int); |
- control = effect = graph()->NewNode( |
- common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecision), is_safe, |
- frame_state, effect, control); |
- |
- return ValueEffectControl(value, effect, control); |
+ Node* max_int = __ Int32Constant(std::numeric_limits<int32_t>::max()); |
+ Node* is_safe = __ Uint32LessThanOrEqual(value, max_int); |
+ __ DeoptimizeUnless(DeoptimizeReason::kLostPrecision, is_safe, frame_state); |
+ return value; |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckedUint32ToTaggedSigned(Node* node, |
- Node* frame_state, |
- Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerCheckedUint32ToTaggedSigned( |
+ Node* node, Node* frame_state) { |
Node* value = node->InputAt(0); |
- Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, |
- SmiMaxValueConstant()); |
- control = effect = graph()->NewNode( |
- common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecision), check, |
- frame_state, effect, control); |
- value = ChangeUint32ToSmi(value); |
- |
- return ValueEffectControl(value, effect, control); |
-} |
- |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::BuildCheckedFloat64ToInt32(CheckForMinusZeroMode mode, |
- Node* value, |
- Node* frame_state, |
- Node* effect, |
- Node* control) { |
- Node* value32 = graph()->NewNode(machine()->RoundFloat64ToInt32(), value); |
- Node* check_same = graph()->NewNode( |
- machine()->Float64Equal(), value, |
- graph()->NewNode(machine()->ChangeInt32ToFloat64(), value32)); |
- control = effect = graph()->NewNode( |
- common()->DeoptimizeUnless(DeoptimizeReason::kLostPrecisionOrNaN), |
- check_same, frame_state, effect, control); |
+ Node* check = __ Uint32LessThanOrEqual(value, SmiMaxValueConstant()); |
+ __ DeoptimizeUnless(DeoptimizeReason::kLostPrecision, check, frame_state); |
+ return ChangeUint32ToSmi(value); |
+} |
+ |
+Node* EffectControlLinearizer::BuildCheckedFloat64ToInt32( |
+ CheckForMinusZeroMode mode, Node* value, Node* frame_state) { |
+ Node* value32 = __ RoundFloat64ToInt32(value); |
+ Node* check_same = __ Float64Equal(value, __ ChangeInt32ToFloat64(value32)); |
+ __ DeoptimizeUnless(DeoptimizeReason::kLostPrecisionOrNaN, check_same, |
+ frame_state); |
if (mode == CheckForMinusZeroMode::kCheckForMinusZero) { |
// Check if {value} is -0. |
- Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value32, |
- jsgraph()->Int32Constant(0)); |
- Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
- check_zero, control); |
+ auto if_zero = __ MakeDeferredLabel<1>(); |
+ auto check_done = __ MakeLabel<2>(); |
- Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero); |
- Node* if_notzero = graph()->NewNode(common()->IfFalse(), branch_zero); |
+ Node* check_zero = __ Word32Equal(value32, __ Int32Constant(0)); |
+ __ GotoIf(check_zero, &if_zero); |
+ __ Goto(&check_done); |
+ __ Bind(&if_zero); |
// In case of 0, we need to check the high bits for the IEEE -0 pattern. |
- Node* check_negative = graph()->NewNode( |
- machine()->Int32LessThan(), |
- graph()->NewNode(machine()->Float64ExtractHighWord32(), value), |
- jsgraph()->Int32Constant(0)); |
- |
- Node* deopt_minus_zero = |
- graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kMinusZero), |
- check_negative, frame_state, effect, if_zero); |
- |
- control = |
- graph()->NewNode(common()->Merge(2), deopt_minus_zero, if_notzero); |
- effect = graph()->NewNode(common()->EffectPhi(2), deopt_minus_zero, effect, |
- control); |
- } |
+ Node* check_negative = __ Int32LessThan(__ Float64ExtractHighWord32(value), |
+ __ Int32Constant(0)); |
+ __ DeoptimizeIf(DeoptimizeReason::kMinusZero, check_negative, frame_state); |
+ __ Goto(&check_done); |
- return ValueEffectControl(value32, effect, control); |
+ __ Bind(&check_done); |
+ } |
+ return value32; |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node, |
- Node* frame_state, |
- Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerCheckedFloat64ToInt32(Node* node, |
+ Node* frame_state) { |
CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op()); |
Node* value = node->InputAt(0); |
- |
- return BuildCheckedFloat64ToInt32(mode, value, frame_state, effect, control); |
+ return BuildCheckedFloat64ToInt32(mode, value, frame_state); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckedTaggedSignedToInt32(Node* node, |
- Node* frame_state, |
- Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerCheckedTaggedSignedToInt32( |
+ Node* node, Node* frame_state) { |
Node* value = node->InputAt(0); |
- |
Node* check = ObjectIsSmi(value); |
- control = effect = |
- graph()->NewNode(common()->DeoptimizeUnless(DeoptimizeReason::kNotASmi), |
- check, frame_state, effect, control); |
- value = ChangeSmiToInt32(value); |
- |
- return ValueEffectControl(value, effect, control); |
+ __ DeoptimizeUnless(DeoptimizeReason::kNotASmi, check, frame_state); |
+ return ChangeSmiToInt32(value); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node, |
- Node* frame_state, |
- Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerCheckedTaggedToInt32(Node* node, |
+ Node* frame_state) { |
CheckForMinusZeroMode mode = CheckMinusZeroModeOf(node->op()); |
Node* value = node->InputAt(0); |
- Node* check = ObjectIsSmi(value); |
- Node* branch = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
+ auto if_not_smi = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kWord32); |
+ Node* check = ObjectIsSmi(value); |
+ __ GotoUnless(check, &if_not_smi); |
// In the Smi case, just convert to int32. |
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
- Node* etrue = effect; |
- Node* vtrue = ChangeSmiToInt32(value); |
+ __ Goto(&done, ChangeSmiToInt32(value)); |
// In the non-Smi case, check the heap numberness, load the number and convert |
// to int32. |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
- Node* efalse = effect; |
- Node* vfalse; |
- { |
- Node* value_map = efalse = |
- graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
- value, efalse, if_false); |
- Node* check = graph()->NewNode(machine()->WordEqual(), value_map, |
- jsgraph()->HeapNumberMapConstant()); |
- if_false = efalse = graph()->NewNode( |
- common()->DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber), check, |
- frame_state, efalse, if_false); |
- vfalse = efalse = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value, |
- efalse, if_false); |
- ValueEffectControl state = |
- BuildCheckedFloat64ToInt32(mode, vfalse, frame_state, efalse, if_false); |
- if_false = state.control; |
- efalse = state.effect; |
- vfalse = state.value; |
- } |
- |
- control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
- value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), |
- vtrue, vfalse, control); |
- |
- return ValueEffectControl(value, effect, control); |
-} |
- |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::BuildCheckedHeapNumberOrOddballToFloat64( |
- CheckTaggedInputMode mode, Node* value, Node* frame_state, Node* effect, |
- Node* control) { |
- Node* value_map = effect = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForMap()), value, effect, control); |
- |
- Node* check_number = graph()->NewNode(machine()->WordEqual(), value_map, |
- jsgraph()->HeapNumberMapConstant()); |
- |
+ __ Bind(&if_not_smi); |
+ Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); |
+ Node* check_map = __ WordEqual(value_map, __ HeapNumberMapConstant()); |
+ __ DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber, check_map, |
+ frame_state); |
+ Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value); |
+ vfalse = BuildCheckedFloat64ToInt32(mode, vfalse, frame_state); |
+ __ Goto(&done, vfalse); |
+ |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
+} |
+ |
+Node* EffectControlLinearizer::BuildCheckedHeapNumberOrOddballToFloat64( |
+ CheckTaggedInputMode mode, Node* value, Node* frame_state) { |
+ Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); |
+ Node* check_number = __ WordEqual(value_map, __ HeapNumberMapConstant()); |
switch (mode) { |
case CheckTaggedInputMode::kNumber: { |
- control = effect = graph()->NewNode( |
- common()->DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber), |
- check_number, frame_state, effect, control); |
+ __ DeoptimizeUnless(DeoptimizeReason::kNotAHeapNumber, check_number, |
+ frame_state); |
break; |
} |
case CheckTaggedInputMode::kNumberOrOddball: { |
- Node* branch = |
- graph()->NewNode(common()->Branch(), check_number, control); |
+ auto check_done = __ MakeLabel<2>(); |
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
- Node* etrue = effect; |
- |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
+ __ GotoIf(check_number, &check_done); |
// For oddballs also contain the numeric value, let us just check that |
// we have an oddball here. |
- Node* efalse = effect; |
- Node* instance_type = efalse = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForMapInstanceType()), |
- value_map, efalse, if_false); |
+ Node* instance_type = |
+ __ LoadField(AccessBuilder::ForMapInstanceType(), value_map); |
Node* check_oddball = |
- graph()->NewNode(machine()->Word32Equal(), instance_type, |
- jsgraph()->Int32Constant(ODDBALL_TYPE)); |
- if_false = efalse = graph()->NewNode( |
- common()->DeoptimizeUnless(DeoptimizeReason::kNotANumberOrOddball), |
- check_oddball, frame_state, efalse, if_false); |
+ __ Word32Equal(instance_type, __ Int32Constant(ODDBALL_TYPE)); |
+ __ DeoptimizeUnless(DeoptimizeReason::kNotANumberOrOddball, check_oddball, |
+ frame_state); |
STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset); |
+ __ Goto(&check_done); |
- control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
+ __ Bind(&check_done); |
break; |
} |
} |
- |
- value = effect = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value, |
- effect, control); |
- return ValueEffectControl(value, effect, control); |
+ return __ LoadField(AccessBuilder::ForHeapNumberValue(), value); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node, |
- Node* frame_state, |
- Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerCheckedTaggedToFloat64(Node* node, |
+ Node* frame_state) { |
CheckTaggedInputMode mode = CheckTaggedInputModeOf(node->op()); |
Node* value = node->InputAt(0); |
+ auto if_smi = __ MakeLabel<1>(); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kFloat64); |
+ |
Node* check = ObjectIsSmi(value); |
- Node* branch = graph()->NewNode(common()->Branch(), check, control); |
+ __ GotoIf(check, &if_smi); |
// In the Smi case, just convert to int32 and then float64. |
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
- Node* etrue = effect; |
- Node* vtrue = ChangeSmiToInt32(value); |
- vtrue = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue); |
- |
// Otherwise, check heap numberness and load the number. |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
- ValueEffectControl number_state = BuildCheckedHeapNumberOrOddballToFloat64( |
- mode, value, frame_state, effect, if_false); |
- |
- Node* merge = |
- graph()->NewNode(common()->Merge(2), if_true, number_state.control); |
- Node* effect_phi = graph()->NewNode(common()->EffectPhi(2), etrue, |
- number_state.effect, merge); |
- Node* result = |
- graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), vtrue, |
- number_state.value, merge); |
- |
- return ValueEffectControl(result, effect_phi, merge); |
-} |
- |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckedTaggedToTaggedSigned(Node* node, |
- Node* frame_state, |
- Node* effect, |
- Node* control) { |
- Node* value = node->InputAt(0); |
+ Node* number = |
+ BuildCheckedHeapNumberOrOddballToFloat64(mode, value, frame_state); |
+ __ Goto(&done, number); |
- Node* check = ObjectIsSmi(value); |
- control = effect = |
- graph()->NewNode(common()->DeoptimizeUnless(DeoptimizeReason::kNotASmi), |
- check, frame_state, effect, control); |
+ __ Bind(&if_smi); |
+ Node* from_smi = ChangeSmiToInt32(value); |
+ from_smi = __ ChangeInt32ToFloat64(from_smi); |
+ __ Goto(&done, from_smi); |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckedTaggedToTaggedPointer(Node* node, |
- Node* frame_state, |
- Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerCheckedTaggedToTaggedSigned( |
+ Node* node, Node* frame_state) { |
Node* value = node->InputAt(0); |
Node* check = ObjectIsSmi(value); |
- control = effect = |
- graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kSmi), check, |
- frame_state, effect, control); |
+ __ DeoptimizeUnless(DeoptimizeReason::kNotASmi, check, frame_state); |
- return ValueEffectControl(value, effect, control); |
+ return value; |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerTruncateTaggedToWord32(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerCheckedTaggedToTaggedPointer( |
+ Node* node, Node* frame_state) { |
Node* value = node->InputAt(0); |
Node* check = ObjectIsSmi(value); |
- Node* branch = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
+ __ DeoptimizeIf(DeoptimizeReason::kSmi, check, frame_state); |
+ return value; |
+} |
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
- Node* etrue = effect; |
- Node* vtrue = ChangeSmiToInt32(value); |
+Node* EffectControlLinearizer::LowerTruncateTaggedToWord32(Node* node) { |
+ Node* value = node->InputAt(0); |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
- Node* efalse = effect; |
- Node* vfalse; |
- { |
- STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset); |
- vfalse = efalse = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value, |
- efalse, if_false); |
- vfalse = graph()->NewNode(machine()->TruncateFloat64ToWord32(), vfalse); |
- } |
+ auto if_not_smi = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kWord32); |
- control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
- value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), |
- vtrue, vfalse, control); |
+ Node* check = ObjectIsSmi(value); |
+ __ GotoUnless(check, &if_not_smi); |
+ __ Goto(&done, ChangeSmiToInt32(value)); |
+ |
+ __ Bind(&if_not_smi); |
+ STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset); |
+ Node* vfalse = __ LoadField(AccessBuilder::ForHeapNumberValue(), value); |
+ vfalse = __ TruncateFloat64ToWord32(vfalse); |
+ __ Goto(&done, vfalse); |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckedTruncateTaggedToWord32(Node* node, |
- Node* frame_state, |
- Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerCheckedTruncateTaggedToWord32( |
+ Node* node, Node* frame_state) { |
Node* value = node->InputAt(0); |
- Node* check = ObjectIsSmi(value); |
- Node* branch = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
+ auto if_not_smi = __ MakeLabel<1>(); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kWord32); |
+ Node* check = ObjectIsSmi(value); |
+ __ GotoUnless(check, &if_not_smi); |
// In the Smi case, just convert to int32. |
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
- Node* etrue = effect; |
- Node* vtrue = ChangeSmiToInt32(value); |
+ __ Goto(&done, ChangeSmiToInt32(value)); |
// Otherwise, check that it's a heap number or oddball and truncate the value |
// to int32. |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
- ValueEffectControl false_state = BuildCheckedHeapNumberOrOddballToFloat64( |
- CheckTaggedInputMode::kNumberOrOddball, value, frame_state, effect, |
- if_false); |
- false_state.value = |
- graph()->NewNode(machine()->TruncateFloat64ToWord32(), false_state.value); |
- |
- Node* merge = |
- graph()->NewNode(common()->Merge(2), if_true, false_state.control); |
- Node* effect_phi = graph()->NewNode(common()->EffectPhi(2), etrue, |
- false_state.effect, merge); |
- Node* result = |
- graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), vtrue, |
- false_state.value, merge); |
- |
- return ValueEffectControl(result, effect_phi, merge); |
-} |
- |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerObjectIsCallable(Node* node, Node* effect, |
- Node* control) { |
+ __ Bind(&if_not_smi); |
+ Node* number = BuildCheckedHeapNumberOrOddballToFloat64( |
+ CheckTaggedInputMode::kNumberOrOddball, value, frame_state); |
+ number = __ TruncateFloat64ToWord32(number); |
+ __ Goto(&done, number); |
+ |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
+} |
+ |
+Node* EffectControlLinearizer::LowerObjectIsCallable(Node* node) { |
Node* value = node->InputAt(0); |
- Node* check = ObjectIsSmi(value); |
- Node* branch = |
- graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); |
+ auto if_smi = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kBit); |
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
- Node* etrue = effect; |
- Node* vtrue = jsgraph()->Int32Constant(0); |
+ Node* check = ObjectIsSmi(value); |
+ __ GotoIf(check, &if_smi); |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
- Node* efalse = effect; |
- Node* vfalse; |
- { |
- Node* value_map = efalse = |
- graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
- value, efalse, if_false); |
- Node* value_bit_field = efalse = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map, |
- efalse, if_false); |
- vfalse = graph()->NewNode( |
- machine()->Word32Equal(), |
- jsgraph()->Int32Constant(1 << Map::kIsCallable), |
- graph()->NewNode( |
- machine()->Word32And(), value_bit_field, |
- jsgraph()->Int32Constant((1 << Map::kIsCallable) | |
- (1 << Map::kIsUndetectable)))); |
- } |
+ Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); |
+ Node* value_bit_field = |
+ __ LoadField(AccessBuilder::ForMapBitField(), value_map); |
+ Node* vfalse = __ Word32Equal( |
+ __ Int32Constant(1 << Map::kIsCallable), |
+ __ Word32And(value_bit_field, |
+ __ Int32Constant((1 << Map::kIsCallable) | |
+ (1 << Map::kIsUndetectable)))); |
+ __ Goto(&done, vfalse); |
- control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
- value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue, |
- vfalse, control); |
+ __ Bind(&if_smi); |
+ __ Goto(&done, __ Int32Constant(0)); |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerObjectIsNumber(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerObjectIsNumber(Node* node) { |
Node* value = node->InputAt(0); |
- Node* check = ObjectIsSmi(value); |
- Node* branch = graph()->NewNode(common()->Branch(), check, control); |
+ auto if_smi = __ MakeLabel<1>(); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kBit); |
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
- Node* etrue = effect; |
- Node* vtrue = jsgraph()->Int32Constant(1); |
+ __ GotoIf(ObjectIsSmi(value), &if_smi); |
+ Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); |
+ __ Goto(&done, __ WordEqual(value_map, __ HeapNumberMapConstant())); |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
- Node* efalse = effect; |
- Node* vfalse; |
- { |
- Node* value_map = efalse = |
- graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
- value, efalse, if_false); |
- vfalse = graph()->NewNode(machine()->WordEqual(), value_map, |
- jsgraph()->HeapNumberMapConstant()); |
- } |
+ __ Bind(&if_smi); |
+ __ Goto(&done, __ Int32Constant(1)); |
- control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
- value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue, |
- vfalse, control); |
- |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerObjectIsReceiver(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerObjectIsReceiver(Node* node) { |
Node* value = node->InputAt(0); |
- Node* check = ObjectIsSmi(value); |
- Node* branch = |
- graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); |
+ auto if_smi = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kBit); |
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
- Node* etrue = effect; |
- Node* vtrue = jsgraph()->Int32Constant(0); |
+ __ GotoIf(ObjectIsSmi(value), &if_smi); |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
- Node* efalse = effect; |
- Node* vfalse; |
- { |
- STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); |
- Node* value_map = efalse = |
- graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
- value, efalse, if_false); |
- Node* value_instance_type = efalse = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map, |
- efalse, if_false); |
- vfalse = graph()->NewNode(machine()->Uint32LessThanOrEqual(), |
- jsgraph()->Uint32Constant(FIRST_JS_RECEIVER_TYPE), |
- value_instance_type); |
- } |
+ STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); |
+ Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); |
+ Node* value_instance_type = |
+ __ LoadField(AccessBuilder::ForMapInstanceType(), value_map); |
+ Node* result = __ Uint32LessThanOrEqual( |
+ __ Uint32Constant(FIRST_JS_RECEIVER_TYPE), value_instance_type); |
+ __ Goto(&done, result); |
- control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
- value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue, |
- vfalse, control); |
+ __ Bind(&if_smi); |
+ __ Goto(&done, __ Int32Constant(0)); |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerObjectIsSmi(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerObjectIsSmi(Node* node) { |
Node* value = node->InputAt(0); |
- value = ObjectIsSmi(value); |
- return ValueEffectControl(value, effect, control); |
+ return ObjectIsSmi(value); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerObjectIsString(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerObjectIsString(Node* node) { |
Node* value = node->InputAt(0); |
- Node* check = ObjectIsSmi(value); |
- Node* branch = |
- graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); |
- |
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
- Node* etrue = effect; |
- Node* vtrue = jsgraph()->Int32Constant(0); |
+ auto if_smi = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kBit); |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
- Node* efalse = effect; |
- Node* vfalse; |
- { |
- Node* value_map = efalse = |
- graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
- value, efalse, if_false); |
- Node* value_instance_type = efalse = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map, |
- efalse, if_false); |
- vfalse = graph()->NewNode(machine()->Uint32LessThan(), value_instance_type, |
- jsgraph()->Uint32Constant(FIRST_NONSTRING_TYPE)); |
- } |
+ Node* check = ObjectIsSmi(value); |
+ __ GotoIf(check, &if_smi); |
+ Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); |
+ Node* value_instance_type = |
+ __ LoadField(AccessBuilder::ForMapInstanceType(), value_map); |
+ Node* vfalse = __ Uint32LessThan(value_instance_type, |
+ __ Uint32Constant(FIRST_NONSTRING_TYPE)); |
+ __ Goto(&done, vfalse); |
- control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
- value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue, |
- vfalse, control); |
+ __ Bind(&if_smi); |
+ __ Goto(&done, __ Int32Constant(0)); |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerObjectIsUndetectable(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerObjectIsUndetectable(Node* node) { |
Node* value = node->InputAt(0); |
- Node* check = ObjectIsSmi(value); |
- Node* branch = |
- graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); |
+ auto if_smi = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kBit); |
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
- Node* etrue = effect; |
- Node* vtrue = jsgraph()->Int32Constant(0); |
+ Node* check = ObjectIsSmi(value); |
+ __ GotoIf(check, &if_smi); |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
- Node* efalse = effect; |
- Node* vfalse; |
- { |
- Node* value_map = efalse = |
- graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
- value, efalse, if_false); |
- Node* value_bit_field = efalse = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map, |
- efalse, if_false); |
- vfalse = graph()->NewNode( |
- machine()->Word32Equal(), |
- graph()->NewNode( |
- machine()->Word32Equal(), jsgraph()->Int32Constant(0), |
- graph()->NewNode( |
- machine()->Word32And(), value_bit_field, |
- jsgraph()->Int32Constant(1 << Map::kIsUndetectable))), |
- jsgraph()->Int32Constant(0)); |
- } |
+ Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); |
+ Node* value_bit_field = |
+ __ LoadField(AccessBuilder::ForMapBitField(), value_map); |
+ Node* vfalse = __ Word32Equal( |
+ __ Word32Equal(__ Int32Constant(0), |
+ __ Word32And(value_bit_field, |
+ __ Int32Constant(1 << Map::kIsUndetectable))), |
+ __ Int32Constant(0)); |
+ __ Goto(&done, vfalse); |
- control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
- value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue, |
- vfalse, control); |
+ __ Bind(&if_smi); |
+ __ Goto(&done, __ Int32Constant(0)); |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerNewRestParameterElements(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerNewRestParameterElements(Node* node) { |
int const formal_parameter_count = ParameterCountOf(node->op()); |
Callable const callable = CodeFactory::NewRestParameterElements(isolate()); |
@@ -2219,17 +1725,12 @@ EffectControlLinearizer::LowerNewRestParameterElements(Node* node, Node* effect, |
CallDescriptor::Flags const flags = CallDescriptor::kNoFlags; |
CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties); |
- Node* value = effect = graph()->NewNode( |
- common()->Call(desc), jsgraph()->HeapConstant(callable.code()), |
- jsgraph()->IntPtrConstant(formal_parameter_count), |
- jsgraph()->NoContextConstant(), effect); |
- return ValueEffectControl(value, effect, control); |
+ return __ Call(desc, __ HeapConstant(callable.code()), |
+ __ IntPtrConstant(formal_parameter_count), |
+ __ NoContextConstant()); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerNewUnmappedArgumentsElements(Node* node, |
- Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerNewUnmappedArgumentsElements(Node* node) { |
int const formal_parameter_count = ParameterCountOf(node->op()); |
Callable const callable = |
@@ -2238,275 +1739,182 @@ EffectControlLinearizer::LowerNewUnmappedArgumentsElements(Node* node, |
CallDescriptor::Flags const flags = CallDescriptor::kNoFlags; |
CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties); |
- Node* value = effect = graph()->NewNode( |
- common()->Call(desc), jsgraph()->HeapConstant(callable.code()), |
- jsgraph()->IntPtrConstant(formal_parameter_count), |
- jsgraph()->NoContextConstant(), effect); |
- return ValueEffectControl(value, effect, control); |
+ return __ Call(desc, __ HeapConstant(callable.code()), |
+ __ IntPtrConstant(formal_parameter_count), |
+ __ NoContextConstant()); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerArrayBufferWasNeutered(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerArrayBufferWasNeutered(Node* node) { |
Node* value = node->InputAt(0); |
- Node* value_bit_field = effect = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForJSArrayBufferBitField()), value, |
- effect, control); |
- value = graph()->NewNode( |
- machine()->Word32Equal(), |
- graph()->NewNode(machine()->Word32Equal(), |
- graph()->NewNode(machine()->Word32And(), value_bit_field, |
- jsgraph()->Int32Constant( |
- JSArrayBuffer::WasNeutered::kMask)), |
- jsgraph()->Int32Constant(0)), |
- jsgraph()->Int32Constant(0)); |
- |
- return ValueEffectControl(value, effect, control); |
+ Node* value_bit_field = |
+ __ LoadField(AccessBuilder::ForJSArrayBufferBitField(), value); |
+ return __ Word32Equal( |
+ __ Word32Equal( |
+ __ Word32And(value_bit_field, |
+ __ Int32Constant(JSArrayBuffer::WasNeutered::kMask)), |
+ __ Int32Constant(0)), |
+ __ Int32Constant(0)); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerStringCharAt(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerStringCharAt(Node* node) { |
+ Node* receiver = node->InputAt(0); |
+ Node* position = node->InputAt(1); |
+ |
Callable const callable = CodeFactory::StringCharAt(isolate()); |
Operator::Properties properties = Operator::kNoThrow | Operator::kNoWrite; |
CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties); |
- node->InsertInput(graph()->zone(), 0, |
- jsgraph()->HeapConstant(callable.code())); |
- node->InsertInput(graph()->zone(), 3, jsgraph()->NoContextConstant()); |
- node->InsertInput(graph()->zone(), 4, effect); |
- NodeProperties::ChangeOp(node, common()->Call(desc)); |
- return ValueEffectControl(node, node, control); |
+ return __ Call(desc, __ HeapConstant(callable.code()), receiver, position, |
+ __ NoContextConstant()); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerStringCharCodeAt(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerStringCharCodeAt(Node* node) { |
+ Node* receiver = node->InputAt(0); |
+ Node* position = node->InputAt(1); |
+ |
Callable const callable = CodeFactory::StringCharCodeAt(isolate()); |
Operator::Properties properties = Operator::kNoThrow | Operator::kNoWrite; |
CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties, |
MachineType::TaggedSigned()); |
- node->InsertInput(graph()->zone(), 0, |
- jsgraph()->HeapConstant(callable.code())); |
- node->InsertInput(graph()->zone(), 3, jsgraph()->NoContextConstant()); |
- node->InsertInput(graph()->zone(), 4, effect); |
- NodeProperties::ChangeOp(node, common()->Call(desc)); |
- return ValueEffectControl(node, node, control); |
+ return __ Call(desc, __ HeapConstant(callable.code()), receiver, position, |
+ __ NoContextConstant()); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerStringFromCharCode(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerStringFromCharCode(Node* node) { |
Node* value = node->InputAt(0); |
+ auto runtime_call = __ MakeDeferredLabel<2>(); |
+ auto if_undefined = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kTagged); |
+ |
// Compute the character code. |
- Node* code = |
- graph()->NewNode(machine()->Word32And(), value, |
- jsgraph()->Int32Constant(String::kMaxUtf16CodeUnit)); |
+ Node* code = __ Word32And(value, __ Int32Constant(String::kMaxUtf16CodeUnit)); |
// Check if the {code} is a one-byte char code. |
- Node* check0 = |
- graph()->NewNode(machine()->Int32LessThanOrEqual(), code, |
- jsgraph()->Int32Constant(String::kMaxOneByteCharCode)); |
- Node* branch0 = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); |
- |
- Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
- Node* efalse0 = effect; |
- |
- Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
- Node* etrue0 = effect; |
+ Node* check0 = __ Int32LessThanOrEqual( |
+ code, __ Int32Constant(String::kMaxOneByteCharCode)); |
+ __ GotoUnless(check0, &runtime_call); |
// Load the isolate wide single character string cache. |
- Node* cache = |
- jsgraph()->HeapConstant(factory()->single_character_string_cache()); |
+ Node* cache = __ HeapConstant(factory()->single_character_string_cache()); |
// Compute the {cache} index for {code}. |
- Node* index = machine()->Is32() |
- ? code |
- : graph()->NewNode(machine()->ChangeUint32ToUint64(), code); |
+ Node* index = machine()->Is32() ? code : __ ChangeUint32ToUint64(code); |
// Check if we have an entry for the {code} in the single character string |
// cache already. |
- Node* entry = etrue0 = graph()->NewNode( |
- simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), cache, |
- index, etrue0, if_true0); |
- |
- Node* check1 = graph()->NewNode(machine()->WordEqual(), entry, |
- jsgraph()->UndefinedConstant()); |
- Node* branch1 = |
- graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, if_true0); |
+ Node* entry = |
+ __ LoadElement(AccessBuilder::ForFixedArrayElement(), cache, index); |
- // Use the {entry} from the {cache}. |
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
- Node* efalse1 = etrue0; |
- Node* vfalse1 = entry; |
+ Node* check1 = __ WordEqual(entry, __ UndefinedConstant()); |
+ __ GotoIf(check1, &runtime_call); |
+ __ Goto(&done, entry); |
// Let %StringFromCharCode handle this case. |
// TODO(turbofan): At some point we may consider adding a stub for this |
// deferred case, so that we don't need to call to C++ here. |
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
- Node* etrue1 = etrue0; |
- Node* vtrue1; |
+ __ Bind(&runtime_call); |
{ |
- if_true1 = graph()->NewNode(common()->Merge(2), if_true1, if_false0); |
- etrue1 = |
- graph()->NewNode(common()->EffectPhi(2), etrue1, efalse0, if_true1); |
Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow; |
Runtime::FunctionId id = Runtime::kStringCharFromCode; |
CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor( |
graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags); |
- vtrue1 = etrue1 = graph()->NewNode( |
- common()->Call(desc), jsgraph()->CEntryStubConstant(1), |
- ChangeInt32ToSmi(code), |
- jsgraph()->ExternalConstant(ExternalReference(id, isolate())), |
- jsgraph()->Int32Constant(1), jsgraph()->NoContextConstant(), etrue1, |
- if_true1); |
+ Node* vtrue1 = |
+ __ Call(desc, __ CEntryStubConstant(1), ChangeInt32ToSmi(code), |
+ __ ExternalConstant(ExternalReference(id, isolate())), |
+ __ Int32Constant(1), __ NoContextConstant()); |
+ __ Goto(&done, vtrue1); |
} |
- |
- control = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, control); |
- value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
- vtrue1, vfalse1, control); |
- |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerStringFromCodePoint(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerStringFromCodePoint(Node* node) { |
Node* value = node->InputAt(0); |
Node* code = value; |
- Node* etrue0 = effect; |
- Node* vtrue0; |
+ auto if_not_single_code = __ MakeDeferredLabel<1>(); |
+ auto if_not_one_byte = __ MakeDeferredLabel<1>(); |
+ auto cache_miss = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<4>(MachineRepresentation::kTagged); |
// Check if the {code} is a single code unit |
- Node* check0 = graph()->NewNode(machine()->Uint32LessThanOrEqual(), code, |
- jsgraph()->Uint32Constant(0xFFFF)); |
- Node* branch0 = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); |
+ Node* check0 = __ Uint32LessThanOrEqual(code, __ Uint32Constant(0xFFFF)); |
+ __ GotoUnless(check0, &if_not_single_code); |
- Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
{ |
// Check if the {code} is a one byte character |
- Node* check1 = graph()->NewNode( |
- machine()->Uint32LessThanOrEqual(), code, |
- jsgraph()->Uint32Constant(String::kMaxOneByteCharCode)); |
- Node* branch1 = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check1, if_true0); |
- |
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
- Node* etrue1 = etrue0; |
- Node* vtrue1; |
+ Node* check1 = __ Uint32LessThanOrEqual( |
+ code, __ Uint32Constant(String::kMaxOneByteCharCode)); |
+ __ GotoUnless(check1, &if_not_one_byte); |
{ |
// Load the isolate wide single character string cache. |
- Node* cache = |
- jsgraph()->HeapConstant(factory()->single_character_string_cache()); |
+ Node* cache = __ HeapConstant(factory()->single_character_string_cache()); |
// Compute the {cache} index for {code}. |
- Node* index = |
- machine()->Is32() |
- ? code |
- : graph()->NewNode(machine()->ChangeUint32ToUint64(), code); |
+ Node* index = machine()->Is32() ? code : __ ChangeUint32ToUint64(code); |
// Check if we have an entry for the {code} in the single character string |
// cache already. |
- Node* entry = etrue1 = graph()->NewNode( |
- simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), |
- cache, index, etrue1, if_true1); |
- |
- Node* check2 = graph()->NewNode(machine()->WordEqual(), entry, |
- jsgraph()->UndefinedConstant()); |
- Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
- check2, if_true1); |
- |
- Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); |
- Node* etrue2 = etrue1; |
- Node* vtrue2; |
+ Node* entry = |
+ __ LoadElement(AccessBuilder::ForFixedArrayElement(), cache, index); |
+ |
+ Node* check2 = __ WordEqual(entry, __ UndefinedConstant()); |
+ __ GotoIf(check2, &cache_miss); |
+ |
+ // Use the {entry} from the {cache}. |
+ __ Goto(&done, entry); |
+ |
+ __ Bind(&cache_miss); |
{ |
// Allocate a new SeqOneByteString for {code}. |
- vtrue2 = etrue2 = graph()->NewNode( |
- simplified()->Allocate(NOT_TENURED), |
- jsgraph()->Int32Constant(SeqOneByteString::SizeFor(1)), etrue2, |
- if_true2); |
- etrue2 = graph()->NewNode( |
- simplified()->StoreField(AccessBuilder::ForMap()), vtrue2, |
- jsgraph()->HeapConstant(factory()->one_byte_string_map()), etrue2, |
- if_true2); |
- etrue2 = graph()->NewNode( |
- simplified()->StoreField(AccessBuilder::ForNameHashField()), vtrue2, |
- jsgraph()->IntPtrConstant(Name::kEmptyHashField), etrue2, if_true2); |
- etrue2 = graph()->NewNode( |
- simplified()->StoreField(AccessBuilder::ForStringLength()), vtrue2, |
- jsgraph()->SmiConstant(1), etrue2, if_true2); |
- etrue2 = graph()->NewNode( |
- machine()->Store(StoreRepresentation(MachineRepresentation::kWord8, |
- kNoWriteBarrier)), |
- vtrue2, jsgraph()->IntPtrConstant(SeqOneByteString::kHeaderSize - |
- kHeapObjectTag), |
- code, etrue2, if_true2); |
+ Node* vtrue2 = __ Allocate( |
+ NOT_TENURED, __ Int32Constant(SeqOneByteString::SizeFor(1))); |
+ __ StoreField(AccessBuilder::ForMap(), vtrue2, |
+ __ HeapConstant(factory()->one_byte_string_map())); |
+ __ StoreField(AccessBuilder::ForNameHashField(), vtrue2, |
+ __ IntPtrConstant(Name::kEmptyHashField)); |
+ __ StoreField(AccessBuilder::ForStringLength(), vtrue2, |
+ __ SmiConstant(1)); |
+ __ Store( |
+ StoreRepresentation(MachineRepresentation::kWord8, kNoWriteBarrier), |
+ vtrue2, |
+ __ IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag), |
+ code); |
// Remember it in the {cache}. |
- etrue2 = graph()->NewNode( |
- simplified()->StoreElement(AccessBuilder::ForFixedArrayElement()), |
- cache, index, vtrue2, etrue2, if_true2); |
+ __ StoreElement(AccessBuilder::ForFixedArrayElement(), cache, index, |
+ vtrue2); |
+ __ Goto(&done, vtrue2); |
} |
- |
- // Use the {entry} from the {cache}. |
- Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); |
- Node* efalse2 = etrue0; |
- Node* vfalse2 = entry; |
- |
- if_true1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); |
- etrue1 = |
- graph()->NewNode(common()->EffectPhi(2), etrue2, efalse2, if_true1); |
- vtrue1 = |
- graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
- vtrue2, vfalse2, if_true1); |
} |
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
- Node* efalse1 = effect; |
- Node* vfalse1; |
+ __ Bind(&if_not_one_byte); |
{ |
// Allocate a new SeqTwoByteString for {code}. |
- vfalse1 = efalse1 = graph()->NewNode( |
- simplified()->Allocate(NOT_TENURED), |
- jsgraph()->Int32Constant(SeqTwoByteString::SizeFor(1)), efalse1, |
- if_false1); |
- efalse1 = graph()->NewNode( |
- simplified()->StoreField(AccessBuilder::ForMap()), vfalse1, |
- jsgraph()->HeapConstant(factory()->string_map()), efalse1, if_false1); |
- efalse1 = graph()->NewNode( |
- simplified()->StoreField(AccessBuilder::ForNameHashField()), vfalse1, |
- jsgraph()->IntPtrConstant(Name::kEmptyHashField), efalse1, if_false1); |
- efalse1 = graph()->NewNode( |
- simplified()->StoreField(AccessBuilder::ForStringLength()), vfalse1, |
- jsgraph()->SmiConstant(1), efalse1, if_false1); |
- efalse1 = graph()->NewNode( |
- machine()->Store(StoreRepresentation(MachineRepresentation::kWord16, |
- kNoWriteBarrier)), |
- vfalse1, jsgraph()->IntPtrConstant(SeqTwoByteString::kHeaderSize - |
- kHeapObjectTag), |
- code, efalse1, if_false1); |
+ Node* vfalse1 = __ Allocate( |
+ NOT_TENURED, __ Int32Constant(SeqTwoByteString::SizeFor(1))); |
+ __ StoreField(AccessBuilder::ForMap(), vfalse1, |
+ __ HeapConstant(factory()->string_map())); |
+ __ StoreField(AccessBuilder::ForNameHashField(), vfalse1, |
+ __ IntPtrConstant(Name::kEmptyHashField)); |
+ __ StoreField(AccessBuilder::ForStringLength(), vfalse1, |
+ __ SmiConstant(1)); |
+ __ Store( |
+ StoreRepresentation(MachineRepresentation::kWord16, kNoWriteBarrier), |
+ vfalse1, |
+ __ IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag), |
+ code); |
+ __ Goto(&done, vfalse1); |
} |
- |
- if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
- etrue0 = |
- graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0); |
- vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
- vtrue1, vfalse1, if_true0); |
} |
+ __ Bind(&if_not_single_code); |
// Generate surrogate pair string |
- Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
- Node* efalse0 = effect; |
- Node* vfalse0; |
{ |
switch (UnicodeEncodingOf(node->op())) { |
case UnicodeEncoding::UTF16: |
@@ -2514,553 +1922,359 @@ EffectControlLinearizer::LowerStringFromCodePoint(Node* node, Node* effect, |
case UnicodeEncoding::UTF32: { |
// Convert UTF32 to UTF16 code units, and store as a 32 bit word. |
- Node* lead_offset = jsgraph()->Int32Constant(0xD800 - (0x10000 >> 10)); |
+ Node* lead_offset = __ Int32Constant(0xD800 - (0x10000 >> 10)); |
// lead = (codepoint >> 10) + LEAD_OFFSET |
Node* lead = |
- graph()->NewNode(machine()->Int32Add(), |
- graph()->NewNode(machine()->Word32Shr(), code, |
- jsgraph()->Int32Constant(10)), |
- lead_offset); |
+ __ Int32Add(__ Word32Shr(code, __ Int32Constant(10)), lead_offset); |
// trail = (codepoint & 0x3FF) + 0xDC00; |
- Node* trail = |
- graph()->NewNode(machine()->Int32Add(), |
- graph()->NewNode(machine()->Word32And(), code, |
- jsgraph()->Int32Constant(0x3FF)), |
- jsgraph()->Int32Constant(0xDC00)); |
+ Node* trail = __ Int32Add(__ Word32And(code, __ Int32Constant(0x3FF)), |
+ __ Int32Constant(0xDC00)); |
// codpoint = (trail << 16) | lead; |
- code = graph()->NewNode(machine()->Word32Or(), |
- graph()->NewNode(machine()->Word32Shl(), trail, |
- jsgraph()->Int32Constant(16)), |
- lead); |
+ code = __ Word32Or(__ Word32Shl(trail, __ Int32Constant(16)), lead); |
break; |
} |
} |
// Allocate a new SeqTwoByteString for {code}. |
- vfalse0 = efalse0 = |
- graph()->NewNode(simplified()->Allocate(NOT_TENURED), |
- jsgraph()->Int32Constant(SeqTwoByteString::SizeFor(2)), |
- efalse0, if_false0); |
- efalse0 = graph()->NewNode( |
- simplified()->StoreField(AccessBuilder::ForMap()), vfalse0, |
- jsgraph()->HeapConstant(factory()->string_map()), efalse0, if_false0); |
- efalse0 = graph()->NewNode( |
- simplified()->StoreField(AccessBuilder::ForNameHashField()), vfalse0, |
- jsgraph()->IntPtrConstant(Name::kEmptyHashField), efalse0, if_false0); |
- efalse0 = graph()->NewNode( |
- simplified()->StoreField(AccessBuilder::ForStringLength()), vfalse0, |
- jsgraph()->SmiConstant(2), efalse0, if_false0); |
- efalse0 = graph()->NewNode( |
- machine()->Store(StoreRepresentation(MachineRepresentation::kWord32, |
- kNoWriteBarrier)), |
- vfalse0, jsgraph()->IntPtrConstant(SeqTwoByteString::kHeaderSize - |
- kHeapObjectTag), |
- code, efalse0, if_false0); |
- } |
- |
- control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); |
- value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
- vtrue0, vfalse0, control); |
- |
- return ValueEffectControl(value, effect, control); |
-} |
+ Node* vfalse0 = __ Allocate(NOT_TENURED, |
+ __ Int32Constant(SeqTwoByteString::SizeFor(2))); |
+ __ StoreField(AccessBuilder::ForMap(), vfalse0, |
+ __ HeapConstant(factory()->string_map())); |
+ __ StoreField(AccessBuilder::ForNameHashField(), vfalse0, |
+ __ IntPtrConstant(Name::kEmptyHashField)); |
+ __ StoreField(AccessBuilder::ForStringLength(), vfalse0, __ SmiConstant(2)); |
+ __ Store( |
+ StoreRepresentation(MachineRepresentation::kWord32, kNoWriteBarrier), |
+ vfalse0, |
+ __ IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag), |
+ code); |
+ __ Goto(&done, vfalse0); |
+ } |
+ |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
+} |
+ |
+Node* EffectControlLinearizer::LowerStringComparison(Callable const& callable, |
+ Node* node) { |
+ Node* lhs = node->InputAt(0); |
+ Node* rhs = node->InputAt(1); |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerStringComparison(Callable const& callable, |
- Node* node, Node* effect, |
- Node* control) { |
Operator::Properties properties = Operator::kEliminatable; |
CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties); |
- node->InsertInput(graph()->zone(), 0, |
- jsgraph()->HeapConstant(callable.code())); |
- node->AppendInput(graph()->zone(), jsgraph()->NoContextConstant()); |
- node->AppendInput(graph()->zone(), effect); |
- NodeProperties::ChangeOp(node, common()->Call(desc)); |
- return ValueEffectControl(node, node, control); |
+ return __ Call(desc, __ HeapConstant(callable.code()), lhs, rhs, |
+ __ NoContextConstant()); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerStringEqual(Node* node, Node* effect, |
- Node* control) { |
- return LowerStringComparison(CodeFactory::StringEqual(isolate()), node, |
- effect, control); |
+Node* EffectControlLinearizer::LowerStringEqual(Node* node) { |
+ return LowerStringComparison(CodeFactory::StringEqual(isolate()), node); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerStringLessThan(Node* node, Node* effect, |
- Node* control) { |
- return LowerStringComparison(CodeFactory::StringLessThan(isolate()), node, |
- effect, control); |
+Node* EffectControlLinearizer::LowerStringLessThan(Node* node) { |
+ return LowerStringComparison(CodeFactory::StringLessThan(isolate()), node); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerStringLessThanOrEqual(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerStringLessThanOrEqual(Node* node) { |
return LowerStringComparison(CodeFactory::StringLessThanOrEqual(isolate()), |
- node, effect, control); |
+ node); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckFloat64Hole(Node* node, Node* frame_state, |
- Node* effect, Node* control) { |
+Node* EffectControlLinearizer::LowerCheckFloat64Hole(Node* node, |
+ Node* frame_state) { |
// If we reach this point w/o eliminating the {node} that's marked |
// with allow-return-hole, we cannot do anything, so just deoptimize |
// in case of the hole NaN (similar to Crankshaft). |
Node* value = node->InputAt(0); |
- Node* check = graph()->NewNode( |
- machine()->Word32Equal(), |
- graph()->NewNode(machine()->Float64ExtractHighWord32(), value), |
- jsgraph()->Int32Constant(kHoleNanUpper32)); |
- control = effect = |
- graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kHole), check, |
- frame_state, effect, control); |
- |
- return ValueEffectControl(value, effect, control); |
+ Node* check = __ Word32Equal(__ Float64ExtractHighWord32(value), |
+ __ Int32Constant(kHoleNanUpper32)); |
+ __ DeoptimizeIf(DeoptimizeReason::kHole, check, frame_state); |
+ return value; |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerCheckTaggedHole(Node* node, Node* frame_state, |
- Node* effect, Node* control) { |
+Node* EffectControlLinearizer::LowerCheckTaggedHole(Node* node, |
+ Node* frame_state) { |
Node* value = node->InputAt(0); |
- Node* check = graph()->NewNode(machine()->WordEqual(), value, |
- jsgraph()->TheHoleConstant()); |
- control = effect = |
- graph()->NewNode(common()->DeoptimizeIf(DeoptimizeReason::kHole), check, |
- frame_state, effect, control); |
- |
- return ValueEffectControl(value, effect, control); |
+ Node* check = __ WordEqual(value, __ TheHoleConstant()); |
+ __ DeoptimizeIf(DeoptimizeReason::kHole, check, frame_state); |
+ return value; |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerConvertTaggedHoleToUndefined(Node* node, |
- Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerConvertTaggedHoleToUndefined(Node* node) { |
Node* value = node->InputAt(0); |
- Node* check = graph()->NewNode(machine()->WordEqual(), value, |
- jsgraph()->TheHoleConstant()); |
- Node* branch = |
- graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); |
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
- Node* vtrue = jsgraph()->UndefinedConstant(); |
+ auto if_is_hole = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kTagged); |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
- Node* vfalse = value; |
+ Node* check = __ WordEqual(value, __ TheHoleConstant()); |
+ __ GotoIf(check, &if_is_hole); |
+ __ Goto(&done, value); |
- control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
- value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
- vtrue, vfalse, control); |
+ __ Bind(&if_is_hole); |
+ __ Goto(&done, __ UndefinedConstant()); |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::AllocateHeapNumberWithValue(Node* value, Node* effect, |
- Node* control) { |
- Node* result = effect = graph()->NewNode( |
- simplified()->Allocate(NOT_TENURED), |
- jsgraph()->Int32Constant(HeapNumber::kSize), effect, control); |
- effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()), |
- result, jsgraph()->HeapNumberMapConstant(), effect, |
- control); |
- effect = graph()->NewNode( |
- simplified()->StoreField(AccessBuilder::ForHeapNumberValue()), result, |
- value, effect, control); |
- return ValueEffectControl(result, effect, control); |
+Node* EffectControlLinearizer::AllocateHeapNumberWithValue(Node* value) { |
+ Node* result = __ Allocate(NOT_TENURED, __ Int32Constant(HeapNumber::kSize)); |
+ __ StoreField(AccessBuilder::ForMap(), result, __ HeapNumberMapConstant()); |
+ __ StoreField(AccessBuilder::ForHeapNumberValue(), result, value); |
+ return result; |
} |
Node* EffectControlLinearizer::ChangeInt32ToSmi(Node* value) { |
if (machine()->Is64()) { |
- value = graph()->NewNode(machine()->ChangeInt32ToInt64(), value); |
+ value = __ ChangeInt32ToInt64(value); |
} |
- return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant()); |
+ return __ WordShl(value, SmiShiftBitsConstant()); |
} |
Node* EffectControlLinearizer::ChangeUint32ToSmi(Node* value) { |
if (machine()->Is64()) { |
- value = graph()->NewNode(machine()->ChangeUint32ToUint64(), value); |
+ value = __ ChangeUint32ToUint64(value); |
} |
- return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant()); |
-} |
- |
-Node* EffectControlLinearizer::ChangeInt32ToFloat64(Node* value) { |
- return graph()->NewNode(machine()->ChangeInt32ToFloat64(), value); |
-} |
- |
-Node* EffectControlLinearizer::ChangeUint32ToFloat64(Node* value) { |
- return graph()->NewNode(machine()->ChangeUint32ToFloat64(), value); |
+ return __ WordShl(value, SmiShiftBitsConstant()); |
} |
Node* EffectControlLinearizer::ChangeSmiToInt32(Node* value) { |
- value = graph()->NewNode(machine()->WordSar(), value, SmiShiftBitsConstant()); |
+ value = __ WordSar(value, SmiShiftBitsConstant()); |
if (machine()->Is64()) { |
- value = graph()->NewNode(machine()->TruncateInt64ToInt32(), value); |
+ value = __ TruncateInt64ToInt32(value); |
} |
return value; |
} |
+ |
Node* EffectControlLinearizer::ObjectIsSmi(Node* value) { |
- return graph()->NewNode( |
- machine()->WordEqual(), |
- graph()->NewNode(machine()->WordAnd(), value, |
- jsgraph()->IntPtrConstant(kSmiTagMask)), |
- jsgraph()->IntPtrConstant(kSmiTag)); |
+ return __ WordEqual(__ WordAnd(value, __ IntPtrConstant(kSmiTagMask)), |
+ __ IntPtrConstant(kSmiTag)); |
} |
Node* EffectControlLinearizer::SmiMaxValueConstant() { |
- return jsgraph()->Int32Constant(Smi::kMaxValue); |
+ return __ Int32Constant(Smi::kMaxValue); |
} |
Node* EffectControlLinearizer::SmiShiftBitsConstant() { |
- return jsgraph()->IntPtrConstant(kSmiShiftSize + kSmiTagSize); |
+ return __ IntPtrConstant(kSmiShiftSize + kSmiTagSize); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerPlainPrimitiveToNumber(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerPlainPrimitiveToNumber(Node* node) { |
Node* value = node->InputAt(0); |
- Node* result = effect = |
- graph()->NewNode(ToNumberOperator(), jsgraph()->ToNumberBuiltinConstant(), |
- value, jsgraph()->NoContextConstant(), effect); |
- return ValueEffectControl(result, effect, control); |
+ return __ ToNumber(value); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerPlainPrimitiveToWord32(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerPlainPrimitiveToWord32(Node* node) { |
Node* value = node->InputAt(0); |
- Node* check0 = ObjectIsSmi(value); |
- Node* branch0 = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); |
+ auto if_not_smi = __ MakeDeferredLabel<1>(); |
+ auto if_to_number_smi = __ MakeLabel<1>(); |
+ auto done = __ MakeLabel<3>(MachineRepresentation::kWord32); |
- Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
- Node* etrue0 = effect; |
- Node* vtrue0 = ChangeSmiToInt32(value); |
+ Node* check0 = ObjectIsSmi(value); |
+ __ GotoUnless(check0, &if_not_smi); |
+ __ Goto(&done, ChangeSmiToInt32(value)); |
- Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
- Node* efalse0 = effect; |
- Node* vfalse0; |
- { |
- vfalse0 = efalse0 = graph()->NewNode( |
- ToNumberOperator(), jsgraph()->ToNumberBuiltinConstant(), value, |
- jsgraph()->NoContextConstant(), efalse0); |
+ __ Bind(&if_not_smi); |
+ Node* to_number = __ ToNumber(value); |
- Node* check1 = ObjectIsSmi(vfalse0); |
- Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0); |
+ Node* check1 = ObjectIsSmi(to_number); |
+ __ GotoIf(check1, &if_to_number_smi); |
+ Node* number = __ LoadField(AccessBuilder::ForHeapNumberValue(), to_number); |
+ __ Goto(&done, __ TruncateFloat64ToWord32(number)); |
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
- Node* etrue1 = efalse0; |
- Node* vtrue1 = ChangeSmiToInt32(vfalse0); |
+ __ Bind(&if_to_number_smi); |
+ __ Goto(&done, ChangeSmiToInt32(to_number)); |
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
- Node* efalse1 = efalse0; |
- Node* vfalse1; |
- { |
- vfalse1 = efalse1 = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0, |
- efalse1, if_false1); |
- vfalse1 = graph()->NewNode(machine()->TruncateFloat64ToWord32(), vfalse1); |
- } |
- |
- if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
- efalse0 = |
- graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0); |
- vfalse0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), |
- vtrue1, vfalse1, if_false0); |
- } |
- |
- control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); |
- value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2), |
- vtrue0, vfalse0, control); |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerPlainPrimitiveToFloat64(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerPlainPrimitiveToFloat64(Node* node) { |
Node* value = node->InputAt(0); |
- Node* check0 = ObjectIsSmi(value); |
- Node* branch0 = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); |
- |
- Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
- Node* etrue0 = effect; |
- Node* vtrue0; |
- { |
- vtrue0 = ChangeSmiToInt32(value); |
- vtrue0 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue0); |
- } |
+ auto if_not_smi = __ MakeDeferredLabel<1>(); |
+ auto if_to_number_smi = __ MakeLabel<1>(); |
+ auto done = __ MakeLabel<3>(MachineRepresentation::kFloat64); |
- Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
- Node* efalse0 = effect; |
- Node* vfalse0; |
- { |
- vfalse0 = efalse0 = graph()->NewNode( |
- ToNumberOperator(), jsgraph()->ToNumberBuiltinConstant(), value, |
- jsgraph()->NoContextConstant(), efalse0); |
+ Node* check0 = ObjectIsSmi(value); |
+ __ GotoUnless(check0, &if_not_smi); |
+ Node* from_smi = ChangeSmiToInt32(value); |
+ __ Goto(&done, __ ChangeInt32ToFloat64(from_smi)); |
- Node* check1 = ObjectIsSmi(vfalse0); |
- Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0); |
+ __ Bind(&if_not_smi); |
+ Node* to_number = __ ToNumber(value); |
+ Node* check1 = ObjectIsSmi(to_number); |
+ __ GotoIf(check1, &if_to_number_smi); |
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
- Node* etrue1 = efalse0; |
- Node* vtrue1; |
- { |
- vtrue1 = ChangeSmiToInt32(vfalse0); |
- vtrue1 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue1); |
- } |
+ Node* number = __ LoadField(AccessBuilder::ForHeapNumberValue(), to_number); |
+ __ Goto(&done, number); |
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
- Node* efalse1 = efalse0; |
- Node* vfalse1; |
- { |
- vfalse1 = efalse1 = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0, |
- efalse1, if_false1); |
- } |
+ __ Bind(&if_to_number_smi); |
+ Node* number_from_smi = ChangeSmiToInt32(to_number); |
+ number_from_smi = __ ChangeInt32ToFloat64(number_from_smi); |
+ __ Goto(&done, number_from_smi); |
- if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
- efalse0 = |
- graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0); |
- vfalse0 = |
- graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
- vtrue1, vfalse1, if_false0); |
- } |
- |
- control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); |
- value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
- vtrue0, vfalse0, control); |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerEnsureWritableFastElements(Node* node, |
- Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerEnsureWritableFastElements(Node* node) { |
Node* object = node->InputAt(0); |
Node* elements = node->InputAt(1); |
+ auto if_not_fixed_array = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kTagged); |
+ |
// Load the current map of {elements}. |
- Node* elements_map = effect = |
- graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), |
- elements, effect, control); |
+ Node* elements_map = __ LoadField(AccessBuilder::ForMap(), elements); |
// Check if {elements} is not a copy-on-write FixedArray. |
- Node* check = graph()->NewNode(machine()->WordEqual(), elements_map, |
- jsgraph()->FixedArrayMapConstant()); |
- Node* branch = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
- |
+ Node* check = __ WordEqual(elements_map, __ FixedArrayMapConstant()); |
+ __ GotoUnless(check, &if_not_fixed_array); |
// Nothing to do if the {elements} are not copy-on-write. |
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
- Node* etrue = effect; |
- Node* vtrue = elements; |
+ __ Goto(&done, elements); |
+ __ Bind(&if_not_fixed_array); |
// We need to take a copy of the {elements} and set them up for {object}. |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
- Node* efalse = effect; |
- Node* vfalse; |
- { |
- // We need to create a copy of the {elements} for {object}. |
- Operator::Properties properties = Operator::kEliminatable; |
- Callable callable = CodeFactory::CopyFastSmiOrObjectElements(isolate()); |
- CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
- CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( |
- isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
- properties); |
- vfalse = efalse = graph()->NewNode( |
- common()->Call(desc), jsgraph()->HeapConstant(callable.code()), object, |
- jsgraph()->NoContextConstant(), efalse); |
- } |
- |
- control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
- Node* value = graph()->NewNode( |
- common()->Phi(MachineRepresentation::kTagged, 2), vtrue, vfalse, control); |
+ Operator::Properties properties = Operator::kEliminatable; |
+ Callable callable = CodeFactory::CopyFastSmiOrObjectElements(isolate()); |
+ CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
+ CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( |
+ isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties); |
+ Node* result = __ Call(desc, __ HeapConstant(callable.code()), object, |
+ __ NoContextConstant()); |
+ __ Goto(&done, result); |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerMaybeGrowFastElements(Node* node, |
- Node* frame_state, |
- Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerMaybeGrowFastElements(Node* node, |
+ Node* frame_state) { |
GrowFastElementsFlags flags = GrowFastElementsFlagsOf(node->op()); |
Node* object = node->InputAt(0); |
Node* elements = node->InputAt(1); |
Node* index = node->InputAt(2); |
Node* length = node->InputAt(3); |
- Node* check0 = graph()->NewNode((flags & GrowFastElementsFlag::kHoleyElements) |
- ? machine()->Uint32LessThanOrEqual() |
- : machine()->Word32Equal(), |
- length, index); |
- Node* branch0 = graph()->NewNode(common()->Branch(), check0, control); |
+ auto done = __ MakeLabel<2>(MachineRepresentation::kTagged); |
+ auto done_grow = __ MakeLabel<2>(MachineRepresentation::kTagged); |
+ auto if_not_grow = __ MakeLabel<1>(); |
+ auto if_not_grow_backing_store = __ MakeLabel<1>(); |
- Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
- Node* etrue0 = effect; |
- Node* vtrue0 = elements; |
+ Node* check0 = (flags & GrowFastElementsFlag::kHoleyElements) |
+ ? __ Uint32LessThanOrEqual(length, index) |
+ : __ Word32Equal(length, index); |
+ __ GotoUnless(check0, &if_not_grow); |
{ |
// Load the length of the {elements} backing store. |
- Node* elements_length = etrue0 = graph()->NewNode( |
- simplified()->LoadField(AccessBuilder::ForFixedArrayLength()), elements, |
- etrue0, if_true0); |
+ Node* elements_length = |
+ __ LoadField(AccessBuilder::ForFixedArrayLength(), elements); |
elements_length = ChangeSmiToInt32(elements_length); |
// Check if we need to grow the {elements} backing store. |
- Node* check1 = |
- graph()->NewNode(machine()->Uint32LessThan(), index, elements_length); |
- Node* branch1 = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check1, if_true0); |
- |
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
- Node* etrue1 = etrue0; |
- Node* vtrue1 = vtrue0; |
- |
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
- Node* efalse1 = etrue0; |
- Node* vfalse1 = vtrue0; |
- { |
- // We need to grow the {elements} for {object}. |
- Operator::Properties properties = Operator::kEliminatable; |
- Callable callable = |
- (flags & GrowFastElementsFlag::kDoubleElements) |
- ? CodeFactory::GrowFastDoubleElements(isolate()) |
- : CodeFactory::GrowFastSmiOrObjectElements(isolate()); |
- CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
- CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( |
- isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
- properties); |
- vfalse1 = efalse1 = graph()->NewNode( |
- common()->Call(desc), jsgraph()->HeapConstant(callable.code()), |
- object, ChangeInt32ToSmi(index), jsgraph()->NoContextConstant(), |
- efalse1); |
- |
- // Ensure that we were able to grow the {elements}. |
- // TODO(turbofan): We use kSmi as reason here similar to Crankshaft, |
- // but maybe we should just introduce a reason that makes sense. |
- efalse1 = if_false1 = graph()->NewNode( |
- common()->DeoptimizeIf(DeoptimizeReason::kSmi), ObjectIsSmi(vfalse1), |
- frame_state, efalse1, if_false1); |
- } |
+ Node* check1 = __ Uint32LessThan(index, elements_length); |
+ __ GotoUnless(check1, &if_not_grow_backing_store); |
+ __ Goto(&done_grow, elements); |
+ |
+ __ Bind(&if_not_grow_backing_store); |
+ // We need to grow the {elements} for {object}. |
+ Operator::Properties properties = Operator::kEliminatable; |
+ Callable callable = |
+ (flags & GrowFastElementsFlag::kDoubleElements) |
+ ? CodeFactory::GrowFastDoubleElements(isolate()) |
+ : CodeFactory::GrowFastSmiOrObjectElements(isolate()); |
+ CallDescriptor::Flags call_flags = CallDescriptor::kNoFlags; |
+ CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( |
+ isolate(), graph()->zone(), callable.descriptor(), 0, call_flags, |
+ properties); |
+ Node* new_object = __ Call(desc, __ HeapConstant(callable.code()), object, |
+ ChangeInt32ToSmi(index), __ NoContextConstant()); |
- if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
- etrue0 = |
- graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0); |
- vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
- vtrue1, vfalse1, if_true0); |
+ // Ensure that we were able to grow the {elements}. |
+ // TODO(turbofan): We use kSmi as reason here similar to Crankshaft, |
+ // but maybe we should just introduce a reason that makes sense. |
+ __ DeoptimizeIf(DeoptimizeReason::kSmi, ObjectIsSmi(new_object), |
+ frame_state); |
+ __ Goto(&done_grow, new_object); |
+ |
+ __ Bind(&done_grow); |
// For JSArray {object}s we also need to update the "length". |
if (flags & GrowFastElementsFlag::kArrayObject) { |
// Compute the new {length}. |
- Node* object_length = ChangeInt32ToSmi(graph()->NewNode( |
- machine()->Int32Add(), index, jsgraph()->Int32Constant(1))); |
+ Node* object_length = |
+ ChangeInt32ToSmi(__ Int32Add(index, __ Int32Constant(1))); |
// Update the "length" property of the {object}. |
- etrue0 = |
- graph()->NewNode(simplified()->StoreField( |
- AccessBuilder::ForJSArrayLength(FAST_ELEMENTS)), |
- object, object_length, etrue0, if_true0); |
+ __ StoreField(AccessBuilder::ForJSArrayLength(FAST_ELEMENTS), object, |
+ object_length); |
} |
+ __ Goto(&done, done_grow.PhiAt(0)); |
} |
- Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
- Node* efalse0 = effect; |
- Node* vfalse0 = elements; |
+ __ Bind(&if_not_grow); |
{ |
// In case of non-holey {elements}, we need to verify that the {index} is |
// in-bounds, otherwise for holey {elements}, the check above already |
// guards the index (and the operator forces {index} to be unsigned). |
if (!(flags & GrowFastElementsFlag::kHoleyElements)) { |
- Node* check1 = |
- graph()->NewNode(machine()->Uint32LessThan(), index, length); |
- efalse0 = if_false0 = graph()->NewNode( |
- common()->DeoptimizeUnless(DeoptimizeReason::kOutOfBounds), check1, |
- frame_state, efalse0, if_false0); |
+ Node* check1 = __ Uint32LessThan(index, length); |
+ __ DeoptimizeUnless(DeoptimizeReason::kOutOfBounds, check1, frame_state); |
} |
+ __ Goto(&done, elements); |
} |
- |
- control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); |
- Node* value = |
- graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), vtrue0, |
- vfalse0, control); |
- |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerTransitionElementsKind(Node* node, Node* effect, |
- Node* control) { |
+void EffectControlLinearizer::LowerTransitionElementsKind(Node* node) { |
ElementsTransition const transition = ElementsTransitionOf(node->op()); |
Node* object = node->InputAt(0); |
- Node* source_map = jsgraph()->HeapConstant(transition.source()); |
- Node* target_map = jsgraph()->HeapConstant(transition.target()); |
+ |
+ auto if_map_same = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<2>(); |
+ |
+ Node* source_map = __ HeapConstant(transition.source()); |
+ Node* target_map = __ HeapConstant(transition.target()); |
// Load the current map of {object}. |
- Node* object_map = effect = |
- graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), object, |
- effect, control); |
+ Node* object_map = __ LoadField(AccessBuilder::ForMap(), object); |
// Check if {object_map} is the same as {source_map}. |
- Node* check = |
- graph()->NewNode(machine()->WordEqual(), object_map, source_map); |
- Node* branch = |
- graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); |
- |
- // Migrate the {object} from {source_map} to {target_map}. |
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
- Node* etrue = effect; |
- { |
- switch (transition.mode()) { |
- case ElementsTransition::kFastTransition: { |
- // In-place migration of {object}, just store the {target_map}. |
- etrue = |
- graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()), |
- object, target_map, etrue, if_true); |
- break; |
- } |
- case ElementsTransition::kSlowTransition: { |
- // Instance migration, call out to the runtime for {object}. |
- Operator::Properties properties = |
- Operator::kNoDeopt | Operator::kNoThrow; |
- Runtime::FunctionId id = Runtime::kTransitionElementsKind; |
- CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor( |
- graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags); |
- etrue = graph()->NewNode( |
- common()->Call(desc), jsgraph()->CEntryStubConstant(1), object, |
- target_map, |
- jsgraph()->ExternalConstant(ExternalReference(id, isolate())), |
- jsgraph()->Int32Constant(2), jsgraph()->NoContextConstant(), etrue, |
- if_true); |
- break; |
- } |
+ Node* check = __ WordEqual(object_map, source_map); |
+ __ GotoIf(check, &if_map_same); |
+ __ Goto(&done); |
+ |
+ __ Bind(&if_map_same); |
+ switch (transition.mode()) { |
+ case ElementsTransition::kFastTransition: |
+ // In-place migration of {object}, just store the {target_map}. |
+ __ StoreField(AccessBuilder::ForMap(), object, target_map); |
+ break; |
+ case ElementsTransition::kSlowTransition: { |
+ // Instance migration, call out to the runtime for {object}. |
+ Operator::Properties properties = Operator::kNoDeopt | Operator::kNoThrow; |
+ Runtime::FunctionId id = Runtime::kTransitionElementsKind; |
+ CallDescriptor const* desc = Linkage::GetRuntimeCallDescriptor( |
+ graph()->zone(), id, 2, properties, CallDescriptor::kNoFlags); |
+ __ Call(desc, __ CEntryStubConstant(1), object, target_map, |
+ __ ExternalConstant(ExternalReference(id, isolate())), |
+ __ Int32Constant(2), __ NoContextConstant()); |
+ break; |
} |
} |
+ __ Goto(&done); |
- // Nothing to do if the {object} doesn't have the {source_map}. |
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
- Node* efalse = effect; |
- |
- control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
- effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
- |
- return ValueEffectControl(nullptr, effect, control); |
+ __ Bind(&done); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerLoadTypedElement(Node* node, Node* effect, |
- Node* control) { |
+Node* EffectControlLinearizer::LowerLoadTypedElement(Node* node) { |
ExternalArrayType array_type = ExternalArrayTypeOf(node->op()); |
Node* buffer = node->InputAt(0); |
Node* base = node->InputAt(1); |
@@ -3069,29 +2283,20 @@ EffectControlLinearizer::LowerLoadTypedElement(Node* node, Node* effect, |
// We need to keep the {buffer} alive so that the GC will not release the |
// ArrayBuffer (if there's any) as long as we are still operating on it. |
- effect = graph()->NewNode(common()->Retain(), buffer, effect); |
+ __ Retain(buffer); |
// Compute the effective storage pointer, handling the case where the |
// {external} pointer is the effective storage pointer (i.e. the {base} |
// is Smi zero). |
- Node* storage = |
- NumberMatcher(base).Is(0) |
- ? external |
- : effect = graph()->NewNode(machine()->UnsafePointerAdd(), base, |
- external, effect, control); |
+ Node* storage = NumberMatcher(base).Is(0) ? external : __ UnsafePointerAdd( |
+ base, external); |
// Perform the actual typed element access. |
- Node* value = effect = graph()->NewNode( |
- simplified()->LoadElement( |
- AccessBuilder::ForTypedArrayElement(array_type, true)), |
- storage, index, effect, control); |
- |
- return ValueEffectControl(value, effect, control); |
+ return __ LoadElement(AccessBuilder::ForTypedArrayElement(array_type, true), |
+ storage, index); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerStoreTypedElement(Node* node, Node* effect, |
- Node* control) { |
+void EffectControlLinearizer::LowerStoreTypedElement(Node* node) { |
ExternalArrayType array_type = ExternalArrayTypeOf(node->op()); |
Node* buffer = node->InputAt(0); |
Node* base = node->InputAt(1); |
@@ -3101,39 +2306,25 @@ EffectControlLinearizer::LowerStoreTypedElement(Node* node, Node* effect, |
// We need to keep the {buffer} alive so that the GC will not release the |
// ArrayBuffer (if there's any) as long as we are still operating on it. |
- effect = graph()->NewNode(common()->Retain(), buffer, effect); |
+ __ Retain(buffer); |
// Compute the effective storage pointer, handling the case where the |
// {external} pointer is the effective storage pointer (i.e. the {base} |
// is Smi zero). |
- Node* storage = |
- NumberMatcher(base).Is(0) |
- ? external |
- : effect = graph()->NewNode(machine()->UnsafePointerAdd(), base, |
- external, effect, control); |
+ Node* storage = NumberMatcher(base).Is(0) ? external : __ UnsafePointerAdd( |
+ base, external); |
// Perform the actual typed element access. |
- effect = graph()->NewNode( |
- simplified()->StoreElement( |
- AccessBuilder::ForTypedArrayElement(array_type, true)), |
- storage, index, value, effect, control); |
- |
- return ValueEffectControl(nullptr, effect, control); |
+ __ StoreElement(AccessBuilder::ForTypedArrayElement(array_type, true), |
+ storage, index, value); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerFloat64RoundUp(Node* node, Node* effect, |
- Node* control) { |
+Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundUp(Node* node) { |
// Nothing to be done if a fast hardware instruction is available. |
if (machine()->Float64RoundUp().IsSupported()) { |
- return ValueEffectControl(node, effect, control); |
+ return Nothing<Node*>(); |
} |
- Node* const one = jsgraph()->Float64Constant(1.0); |
- Node* const zero = jsgraph()->Float64Constant(0.0); |
- Node* const minus_zero = jsgraph()->Float64Constant(-0.0); |
- Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0); |
- Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0); |
Node* const input = node->InputAt(0); |
// General case for ceil. |
@@ -3158,251 +2349,169 @@ EffectControlLinearizer::LowerFloat64RoundUp(Node* node, Node* effect, |
// let temp2 = (2^52 + temp1) - 2^52 in |
// let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in |
// -0 - temp3 |
- // |
- // Note: We do not use the Diamond helper class here, because it really hurts |
- // readability with nested diamonds. |
- |
- Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input); |
- Node* branch0 = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); |
- Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
- Node* vtrue0; |
- { |
- Node* check1 = |
- graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input); |
- Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0); |
+ auto if_not_positive = __ MakeDeferredLabel<1>(); |
+ auto if_greater_than_two_52 = __ MakeDeferredLabel<1>(); |
+ auto if_less_than_minus_two_52 = __ MakeDeferredLabel<1>(); |
+ auto if_zero = __ MakeDeferredLabel<1>(); |
+ auto done_temp3 = __ MakeLabel<2>(MachineRepresentation::kFloat64); |
+ auto done = __ MakeLabel<6>(MachineRepresentation::kFloat64); |
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
- Node* vtrue1 = input; |
+ Node* const zero = __ Float64Constant(0.0); |
+ Node* const two_52 = __ Float64Constant(4503599627370496.0E0); |
+ Node* const one = __ Float64Constant(1.0); |
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
- Node* vfalse1; |
+ Node* check0 = __ Float64LessThan(zero, input); |
+ __ GotoUnless(check0, &if_not_positive); |
+ { |
+ Node* check1 = __ Float64LessThanOrEqual(two_52, input); |
+ __ GotoIf(check1, &if_greater_than_two_52); |
{ |
- Node* temp1 = graph()->NewNode( |
- machine()->Float64Sub(), |
- graph()->NewNode(machine()->Float64Add(), two_52, input), two_52); |
- vfalse1 = graph()->NewNode( |
- common()->Select(MachineRepresentation::kFloat64), |
- graph()->NewNode(machine()->Float64LessThan(), temp1, input), |
- graph()->NewNode(machine()->Float64Add(), temp1, one), temp1); |
+ Node* temp1 = __ Float64Sub(__ Float64Add(two_52, input), two_52); |
+ __ GotoUnless(__ Float64LessThan(temp1, input), &done, temp1); |
+ __ Goto(&done, __ Float64Add(temp1, one)); |
} |
- if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
- vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
- vtrue1, vfalse1, if_true0); |
+ __ Bind(&if_greater_than_two_52); |
+ __ Goto(&done, input); |
} |
- Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
- Node* vfalse0; |
+ __ Bind(&if_not_positive); |
{ |
- Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero); |
- Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
- check1, if_false0); |
+ Node* check1 = __ Float64Equal(input, zero); |
+ __ GotoIf(check1, &if_zero); |
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
- Node* vtrue1 = input; |
+ Node* const minus_two_52 = __ Float64Constant(-4503599627370496.0E0); |
+ Node* check2 = __ Float64LessThanOrEqual(input, minus_two_52); |
+ __ GotoIf(check2, &if_less_than_minus_two_52); |
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
- Node* vfalse1; |
{ |
- Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(), |
- input, minus_two_52); |
- Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
- check2, if_false1); |
- |
- Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); |
- Node* vtrue2 = input; |
- |
- Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); |
- Node* vfalse2; |
- { |
- Node* temp1 = |
- graph()->NewNode(machine()->Float64Sub(), minus_zero, input); |
- Node* temp2 = graph()->NewNode( |
- machine()->Float64Sub(), |
- graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52); |
- Node* temp3 = graph()->NewNode( |
- common()->Select(MachineRepresentation::kFloat64), |
- graph()->NewNode(machine()->Float64LessThan(), temp1, temp2), |
- graph()->NewNode(machine()->Float64Sub(), temp2, one), temp2); |
- vfalse2 = graph()->NewNode(machine()->Float64Sub(), minus_zero, temp3); |
- } |
- |
- if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); |
- vfalse1 = |
- graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
- vtrue2, vfalse2, if_false1); |
+ Node* const minus_zero = __ Float64Constant(-0.0); |
+ Node* temp1 = __ Float64Sub(minus_zero, input); |
+ Node* temp2 = __ Float64Sub(__ Float64Add(two_52, temp1), two_52); |
+ Node* check3 = __ Float64LessThan(temp1, temp2); |
+ __ GotoUnless(check3, &done_temp3, temp2); |
+ __ Goto(&done_temp3, __ Float64Sub(temp2, one)); |
+ |
+ __ Bind(&done_temp3); |
+ Node* temp3 = done_temp3.PhiAt(0); |
+ __ Goto(&done, __ Float64Sub(minus_zero, temp3)); |
} |
+ __ Bind(&if_less_than_minus_two_52); |
+ __ Goto(&done, input); |
- if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
- vfalse0 = |
- graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
- vtrue1, vfalse1, if_false0); |
+ __ Bind(&if_zero); |
+ __ Goto(&done, input); |
} |
- |
- Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
- Node* value = |
- graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
- vtrue0, vfalse0, merge0); |
- return ValueEffectControl(value, effect, merge0); |
+ __ Bind(&done); |
+ return Just(done.PhiAt(0)); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::BuildFloat64RoundDown(Node* value, Node* effect, |
- Node* control) { |
- if (machine()->Float64RoundDown().IsSupported()) { |
- value = graph()->NewNode(machine()->Float64RoundDown().op(), value); |
- } else { |
- Node* const one = jsgraph()->Float64Constant(1.0); |
- Node* const zero = jsgraph()->Float64Constant(0.0); |
- Node* const minus_one = jsgraph()->Float64Constant(-1.0); |
- Node* const minus_zero = jsgraph()->Float64Constant(-0.0); |
- Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0); |
- Node* const minus_two_52 = |
- jsgraph()->Float64Constant(-4503599627370496.0E0); |
- Node* const input = value; |
- |
- // General case for floor. |
- // |
- // if 0.0 < input then |
- // if 2^52 <= input then |
- // input |
- // else |
- // let temp1 = (2^52 + input) - 2^52 in |
- // if input < temp1 then |
- // temp1 - 1 |
- // else |
- // temp1 |
- // else |
- // if input == 0 then |
- // input |
- // else |
- // if input <= -2^52 then |
- // input |
- // else |
- // let temp1 = -0 - input in |
- // let temp2 = (2^52 + temp1) - 2^52 in |
- // if temp2 < temp1 then |
- // -1 - temp2 |
- // else |
- // -0 - temp2 |
- // |
- // Note: We do not use the Diamond helper class here, because it really |
- // hurts |
- // readability with nested diamonds. |
- |
- Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input); |
- Node* branch0 = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); |
- |
- Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
- Node* vtrue0; |
- { |
- Node* check1 = |
- graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input); |
- Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0); |
- |
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
- Node* vtrue1 = input; |
- |
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
- Node* vfalse1; |
- { |
- Node* temp1 = graph()->NewNode( |
- machine()->Float64Sub(), |
- graph()->NewNode(machine()->Float64Add(), two_52, input), two_52); |
- vfalse1 = graph()->NewNode( |
- common()->Select(MachineRepresentation::kFloat64), |
- graph()->NewNode(machine()->Float64LessThan(), input, temp1), |
- graph()->NewNode(machine()->Float64Sub(), temp1, one), temp1); |
- } |
+Node* EffectControlLinearizer::BuildFloat64RoundDown(Node* value) { |
+ Node* round_down = __ Float64RoundDown(value); |
+ if (round_down != nullptr) { |
+ return round_down; |
+ } |
- if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
- vtrue0 = |
- graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
- vtrue1, vfalse1, if_true0); |
- } |
+ Node* const input = value; |
- Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
- Node* vfalse0; |
+ // General case for floor. |
+ // |
+ // if 0.0 < input then |
+ // if 2^52 <= input then |
+ // input |
+ // else |
+ // let temp1 = (2^52 + input) - 2^52 in |
+ // if input < temp1 then |
+ // temp1 - 1 |
+ // else |
+ // temp1 |
+ // else |
+ // if input == 0 then |
+ // input |
+ // else |
+ // if input <= -2^52 then |
+ // input |
+ // else |
+ // let temp1 = -0 - input in |
+ // let temp2 = (2^52 + temp1) - 2^52 in |
+ // if temp2 < temp1 then |
+ // -1 - temp2 |
+ // else |
+ // -0 - temp2 |
+ |
+ auto if_not_positive = __ MakeDeferredLabel<1>(); |
+ auto if_greater_than_two_52 = __ MakeDeferredLabel<1>(); |
+ auto if_less_than_minus_two_52 = __ MakeDeferredLabel<1>(); |
+ auto if_temp2_lt_temp1 = __ MakeLabel<1>(); |
+ auto if_zero = __ MakeDeferredLabel<1>(); |
+ auto done = __ MakeLabel<7>(MachineRepresentation::kFloat64); |
+ |
+ Node* const zero = __ Float64Constant(0.0); |
+ Node* const two_52 = __ Float64Constant(4503599627370496.0E0); |
+ |
+ Node* check0 = __ Float64LessThan(zero, input); |
+ __ GotoUnless(check0, &if_not_positive); |
+ { |
+ Node* check1 = __ Float64LessThanOrEqual(two_52, input); |
+ __ GotoIf(check1, &if_greater_than_two_52); |
{ |
- Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero); |
- Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
- check1, if_false0); |
+ Node* const one = __ Float64Constant(1.0); |
+ Node* temp1 = __ Float64Sub(__ Float64Add(two_52, input), two_52); |
+ __ GotoUnless(__ Float64LessThan(input, temp1), &done, temp1); |
+ __ Goto(&done, __ Float64Sub(temp1, one)); |
+ } |
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
- Node* vtrue1 = input; |
+ __ Bind(&if_greater_than_two_52); |
+ __ Goto(&done, input); |
+ } |
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
- Node* vfalse1; |
- { |
- Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(), |
- input, minus_two_52); |
- Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
- check2, if_false1); |
- |
- Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); |
- Node* vtrue2 = input; |
- |
- Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); |
- Node* vfalse2; |
- { |
- Node* temp1 = |
- graph()->NewNode(machine()->Float64Sub(), minus_zero, input); |
- Node* temp2 = graph()->NewNode( |
- machine()->Float64Sub(), |
- graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52); |
- vfalse2 = graph()->NewNode( |
- common()->Select(MachineRepresentation::kFloat64), |
- graph()->NewNode(machine()->Float64LessThan(), temp2, temp1), |
- graph()->NewNode(machine()->Float64Sub(), minus_one, temp2), |
- graph()->NewNode(machine()->Float64Sub(), minus_zero, temp2)); |
- } |
+ __ Bind(&if_not_positive); |
+ { |
+ Node* check1 = __ Float64Equal(input, zero); |
+ __ GotoIf(check1, &if_zero); |
- if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); |
- vfalse1 = |
- graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
- vtrue2, vfalse2, if_false1); |
- } |
+ Node* const minus_two_52 = __ Float64Constant(-4503599627370496.0E0); |
+ Node* check2 = __ Float64LessThanOrEqual(input, minus_two_52); |
+ __ GotoIf(check2, &if_less_than_minus_two_52); |
- if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
- vfalse0 = |
- graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
- vtrue1, vfalse1, if_false0); |
+ { |
+ Node* const minus_zero = __ Float64Constant(-0.0); |
+ Node* temp1 = __ Float64Sub(minus_zero, input); |
+ Node* temp2 = __ Float64Sub(__ Float64Add(two_52, temp1), two_52); |
+ Node* check3 = __ Float64LessThan(temp2, temp1); |
+ __ GotoIf(check3, &if_temp2_lt_temp1); |
+ __ Goto(&done, __ Float64Sub(minus_zero, temp2)); |
+ |
+ __ Bind(&if_temp2_lt_temp1); |
+ __ Goto(&done, __ Float64Sub(__ Float64Constant(-1.0), temp2)); |
} |
+ __ Bind(&if_less_than_minus_two_52); |
+ __ Goto(&done, input); |
- control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
- value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
- vtrue0, vfalse0, control); |
+ __ Bind(&if_zero); |
+ __ Goto(&done, input); |
} |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return done.PhiAt(0); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerFloat64RoundDown(Node* node, Node* effect, |
- Node* control) { |
+Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundDown(Node* node) { |
// Nothing to be done if a fast hardware instruction is available. |
if (machine()->Float64RoundDown().IsSupported()) { |
- return ValueEffectControl(node, effect, control); |
+ return Nothing<Node*>(); |
} |
Node* const input = node->InputAt(0); |
- return BuildFloat64RoundDown(input, effect, control); |
+ return Just(BuildFloat64RoundDown(input)); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerFloat64RoundTiesEven(Node* node, Node* effect, |
- Node* control) { |
+Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundTiesEven(Node* node) { |
// Nothing to be done if a fast hardware instruction is available. |
if (machine()->Float64RoundTiesEven().IsSupported()) { |
- return ValueEffectControl(node, effect, control); |
+ return Nothing<Node*>(); |
} |
- Node* const one = jsgraph()->Float64Constant(1.0); |
- Node* const two = jsgraph()->Float64Constant(2.0); |
- Node* const half = jsgraph()->Float64Constant(0.5); |
- Node* const zero = jsgraph()->Float64Constant(0.0); |
Node* const input = node->InputAt(0); |
// Generate case for round ties to even: |
@@ -3419,79 +2528,38 @@ EffectControlLinearizer::LowerFloat64RoundTiesEven(Node* node, Node* effect, |
// value |
// else |
// value + 1.0 |
- // |
- // Note: We do not use the Diamond helper class here, because it really hurts |
- // readability with nested diamonds. |
- |
- ValueEffectControl continuation = |
- BuildFloat64RoundDown(input, effect, control); |
- Node* value = continuation.value; |
- effect = continuation.effect; |
- control = continuation.control; |
- Node* temp1 = graph()->NewNode(machine()->Float64Sub(), input, value); |
+ auto if_is_half = __ MakeLabel<1>(); |
+ auto done = __ MakeLabel<4>(MachineRepresentation::kFloat64); |
- Node* check0 = graph()->NewNode(machine()->Float64LessThan(), temp1, half); |
- Node* branch0 = graph()->NewNode(common()->Branch(), check0, control); |
+ Node* value = BuildFloat64RoundDown(input); |
+ Node* temp1 = __ Float64Sub(input, value); |
- Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
- Node* vtrue0 = value; |
+ Node* const half = __ Float64Constant(0.5); |
+ Node* check0 = __ Float64LessThan(temp1, half); |
+ __ GotoIf(check0, &done, value); |
- Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
- Node* vfalse0; |
- { |
- Node* check1 = graph()->NewNode(machine()->Float64LessThan(), half, temp1); |
- Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0); |
+ Node* const one = __ Float64Constant(1.0); |
+ Node* check1 = __ Float64LessThan(half, temp1); |
+ __ GotoUnless(check1, &if_is_half); |
+ __ Goto(&done, __ Float64Add(value, one)); |
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
- Node* vtrue1 = graph()->NewNode(machine()->Float64Add(), value, one); |
- |
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
- Node* vfalse1; |
- { |
- Node* temp2 = graph()->NewNode(machine()->Float64Mod(), value, two); |
+ __ Bind(&if_is_half); |
+ Node* temp2 = __ Float64Mod(value, __ Float64Constant(2.0)); |
+ Node* check2 = __ Float64Equal(temp2, __ Float64Constant(0.0)); |
+ __ GotoIf(check2, &done, value); |
+ __ Goto(&done, __ Float64Add(value, one)); |
- Node* check2 = graph()->NewNode(machine()->Float64Equal(), temp2, zero); |
- Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_false1); |
- |
- Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); |
- Node* vtrue2 = value; |
- |
- Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); |
- Node* vfalse2 = graph()->NewNode(machine()->Float64Add(), value, one); |
- |
- if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); |
- vfalse1 = |
- graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
- vtrue2, vfalse2, if_false1); |
- } |
- |
- if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
- vfalse0 = |
- graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
- vtrue1, vfalse1, if_false0); |
- } |
- |
- control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
- value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
- vtrue0, vfalse0, control); |
- |
- return ValueEffectControl(value, effect, control); |
+ __ Bind(&done); |
+ return Just(done.PhiAt(0)); |
} |
-EffectControlLinearizer::ValueEffectControl |
-EffectControlLinearizer::LowerFloat64RoundTruncate(Node* node, Node* effect, |
- Node* control) { |
+Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundTruncate(Node* node) { |
// Nothing to be done if a fast hardware instruction is available. |
if (machine()->Float64RoundTruncate().IsSupported()) { |
- return ValueEffectControl(node, effect, control); |
+ return Nothing<Node*>(); |
} |
- Node* const one = jsgraph()->Float64Constant(1.0); |
- Node* const zero = jsgraph()->Float64Constant(0.0); |
- Node* const minus_zero = jsgraph()->Float64Constant(-0.0); |
- Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0); |
- Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0); |
Node* const input = node->InputAt(0); |
// General case for trunc. |
@@ -3520,92 +2588,65 @@ EffectControlLinearizer::LowerFloat64RoundTruncate(Node* node, Node* effect, |
// Note: We do not use the Diamond helper class here, because it really hurts |
// readability with nested diamonds. |
- Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input); |
- Node* branch0 = |
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); |
+ auto if_not_positive = __ MakeDeferredLabel<1>(); |
+ auto if_greater_than_two_52 = __ MakeDeferredLabel<1>(); |
+ auto if_less_than_minus_two_52 = __ MakeDeferredLabel<1>(); |
+ auto if_zero = __ MakeDeferredLabel<1>(); |
+ auto done_temp3 = __ MakeLabel<2>(MachineRepresentation::kFloat64); |
+ auto done = __ MakeLabel<6>(MachineRepresentation::kFloat64); |
- Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
- Node* vtrue0; |
- { |
- Node* check1 = |
- graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input); |
- Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0); |
+ Node* const zero = __ Float64Constant(0.0); |
+ Node* const two_52 = __ Float64Constant(4503599627370496.0E0); |
+ Node* const one = __ Float64Constant(1.0); |
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
- Node* vtrue1 = input; |
- |
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
- Node* vfalse1; |
+ Node* check0 = __ Float64LessThan(zero, input); |
+ __ GotoUnless(check0, &if_not_positive); |
+ { |
+ Node* check1 = __ Float64LessThanOrEqual(two_52, input); |
+ __ GotoIf(check1, &if_greater_than_two_52); |
{ |
- Node* temp1 = graph()->NewNode( |
- machine()->Float64Sub(), |
- graph()->NewNode(machine()->Float64Add(), two_52, input), two_52); |
- vfalse1 = graph()->NewNode( |
- common()->Select(MachineRepresentation::kFloat64), |
- graph()->NewNode(machine()->Float64LessThan(), input, temp1), |
- graph()->NewNode(machine()->Float64Sub(), temp1, one), temp1); |
+ Node* temp1 = __ Float64Sub(__ Float64Add(two_52, input), two_52); |
+ __ GotoUnless(__ Float64LessThan(input, temp1), &done, temp1); |
+ __ Goto(&done, __ Float64Sub(temp1, one)); |
} |
- if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
- vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
- vtrue1, vfalse1, if_true0); |
+ __ Bind(&if_greater_than_two_52); |
+ __ Goto(&done, input); |
} |
- Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
- Node* vfalse0; |
+ __ Bind(&if_not_positive); |
{ |
- Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero); |
- Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
- check1, if_false0); |
+ Node* check1 = __ Float64Equal(input, zero); |
+ __ GotoIf(check1, &if_zero); |
- Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
- Node* vtrue1 = input; |
+ Node* const minus_two_52 = __ Float64Constant(-4503599627370496.0E0); |
+ Node* check2 = __ Float64LessThanOrEqual(input, minus_two_52); |
+ __ GotoIf(check2, &if_less_than_minus_two_52); |
- Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
- Node* vfalse1; |
{ |
- Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(), |
- input, minus_two_52); |
- Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
- check2, if_false1); |
- |
- Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); |
- Node* vtrue2 = input; |
- |
- Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); |
- Node* vfalse2; |
- { |
- Node* temp1 = |
- graph()->NewNode(machine()->Float64Sub(), minus_zero, input); |
- Node* temp2 = graph()->NewNode( |
- machine()->Float64Sub(), |
- graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52); |
- Node* temp3 = graph()->NewNode( |
- common()->Select(MachineRepresentation::kFloat64), |
- graph()->NewNode(machine()->Float64LessThan(), temp1, temp2), |
- graph()->NewNode(machine()->Float64Sub(), temp2, one), temp2); |
- vfalse2 = graph()->NewNode(machine()->Float64Sub(), minus_zero, temp3); |
- } |
- |
- if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); |
- vfalse1 = |
- graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
- vtrue2, vfalse2, if_false1); |
+ Node* const minus_zero = __ Float64Constant(-0.0); |
+ Node* temp1 = __ Float64Sub(minus_zero, input); |
+ Node* temp2 = __ Float64Sub(__ Float64Add(two_52, temp1), two_52); |
+ Node* check3 = __ Float64LessThan(temp1, temp2); |
+ __ GotoUnless(check3, &done_temp3, temp2); |
+ __ Goto(&done_temp3, __ Float64Sub(temp2, one)); |
+ |
+ __ Bind(&done_temp3); |
+ Node* temp3 = done_temp3.PhiAt(0); |
+ __ Goto(&done, __ Float64Sub(minus_zero, temp3)); |
} |
+ __ Bind(&if_less_than_minus_two_52); |
+ __ Goto(&done, input); |
- if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
- vfalse0 = |
- graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
- vtrue1, vfalse1, if_false0); |
+ __ Bind(&if_zero); |
+ __ Goto(&done, input); |
} |
- |
- Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
- Node* value = |
- graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), |
- vtrue0, vfalse0, merge0); |
- return ValueEffectControl(value, effect, merge0); |
+ __ Bind(&done); |
+ return Just(done.PhiAt(0)); |
} |
+#undef __ |
+ |
Factory* EffectControlLinearizer::factory() const { |
return isolate()->factory(); |
} |
@@ -3614,18 +2655,6 @@ Isolate* EffectControlLinearizer::isolate() const { |
return jsgraph()->isolate(); |
} |
-Operator const* EffectControlLinearizer::ToNumberOperator() { |
- if (!to_number_operator_.is_set()) { |
- Callable callable = CodeFactory::ToNumber(isolate()); |
- CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
- CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
- isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
- Operator::kEliminatable); |
- to_number_operator_.set(common()->Call(desc)); |
- } |
- return to_number_operator_.get(); |
-} |
- |
} // namespace compiler |
} // namespace internal |
} // namespace v8 |