Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(115)

Unified Diff: src/compiler/effect-control-linearizer.cc

Issue 2571903004: [turbofan] Introduce graph assembler to build effect-control-linearizer sub-graphs. (Closed)
Patch Set: Address reviewer comments Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/effect-control-linearizer.h ('k') | src/compiler/graph-assembler.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « src/compiler/effect-control-linearizer.h ('k') | src/compiler/graph-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698