Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
- // TODO(sigurds) Use simplified load here once it is ready.
Node* field_load = NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object,
jsgraph()->Int32Constant(offset - kHeapObjectTag));
return field_load;
Node* ChangeLowering::LoadHeapNumberValue(Node* value, Node* control) {
return graph()->NewNode(machine()->Load(kMachFloat64), value,
- HeapNumberValueIndexConstant(),
- graph()->NewNode(common()->ControlEffect(), control));
+ HeapNumberValueIndexConstant(), graph()->start(),
+ control);
}
Name##Operator k##Name##Operator;
SHARED_OP_LIST(SHARED)
#undef SHARED
-
- struct ControlEffectOperator FINAL : public SimpleOperator {
- ControlEffectOperator()
- : SimpleOperator(IrOpcode::kControlEffect, Operator::kPure, 0, 0,
- "ControlEffect") {}
- };
- ControlEffectOperator kControlEffectOperator;
};
}
-const Operator* CommonOperatorBuilder::ControlEffect() {
- return &impl_.kControlEffectOperator;
-}
-
-
const Operator* CommonOperatorBuilder::ValueEffect(int arguments) {
DCHECK(arguments > 0); // Disallow empty value effects.
return new (zone()) SimpleOperator(IrOpcode::kValueEffect, Operator::kPure,
const Operator* Phi(MachineType type, int arguments);
const Operator* EffectPhi(int arguments);
- const Operator* ControlEffect();
const Operator* ValueEffect(int arguments);
const Operator* Finish(int arguments);
const Operator* StateValues(int arguments);
void JSGenericLowering::LowerJSLoadContext(Node* node) {
const ContextAccess& access = ContextAccessOf(node->op());
- // TODO(mstarzinger): Use simplified operators instead of machine operators
- // here so that load/store optimization can be applied afterwards.
for (size_t i = 0; i < access.depth(); ++i) {
node->ReplaceInput(
0, graph()->NewNode(
machine()->Load(kMachAnyTagged),
NodeProperties::GetValueInput(node, 0),
Int32Constant(Context::SlotOffset(Context::PREVIOUS_INDEX)),
- NodeProperties::GetEffectInput(node)));
+ NodeProperties::GetEffectInput(node), graph()->start()));
}
node->ReplaceInput(
1, Int32Constant(Context::SlotOffset(static_cast<int>(access.index()))));
+ node->AppendInput(zone(), graph()->start());
PatchOperator(node, machine()->Load(kMachAnyTagged));
}
void JSGenericLowering::LowerJSStoreContext(Node* node) {
const ContextAccess& access = ContextAccessOf(node->op());
- // TODO(mstarzinger): Use simplified operators instead of machine operators
- // here so that load/store optimization can be applied afterwards.
for (size_t i = 0; i < access.depth(); ++i) {
node->ReplaceInput(
0, graph()->NewNode(
machine()->Load(kMachAnyTagged),
NodeProperties::GetValueInput(node, 0),
Int32Constant(Context::SlotOffset(Context::PREVIOUS_INDEX)),
- NodeProperties::GetEffectInput(node)));
+ NodeProperties::GetEffectInput(node), graph()->start()));
}
node->ReplaceInput(2, NodeProperties::GetValueInput(node, 1));
node->ReplaceInput(
DCHECK(IsFixedTypedArrayElementsKind(elements_kind));
element_access = AccessBuilder::ForTypedArrayElement(type, false);
}
- Node* value =
- graph()->NewNode(simplified()->LoadElement(element_access), elements,
- key, jsgraph()->Uint32Constant(length),
- NodeProperties::GetEffectInput(node));
+ Node* value = graph()->NewNode(
+ simplified()->LoadElement(element_access), elements, key,
+ jsgraph()->Uint32Constant(length), NodeProperties::GetEffectInput(node),
+ NodeProperties::GetControlInput(node));
return ReplaceEagerly(node, value);
}
return NoChange();
#define INNER_OP_LIST(V) \
V(Phi) \
V(EffectPhi) \
- V(ControlEffect) \
V(ValueEffect) \
V(Finish) \
V(FrameState) \
switch (op->opcode()) {
case IrOpcode::kPhi:
case IrOpcode::kEffectPhi:
- case IrOpcode::kControlEffect:
+ case IrOpcode::kLoad:
+ case IrOpcode::kLoadElement:
return 1;
#define OPCODE_CASE(x) case IrOpcode::k##x:
CONTROL_OP_LIST(OPCODE_CASE)
inline bool OperatorProperties::HasEffectOutput(const Operator* op) {
return op->opcode() == IrOpcode::kStart ||
- op->opcode() == IrOpcode::kControlEffect ||
op->opcode() == IrOpcode::kValueEffect ||
(op->opcode() != IrOpcode::kFinish && GetEffectInputCount(op) > 0);
}
node->set_op(machine()->Load(access.machine_type));
Node* offset = jsgraph()->Int32Constant(access.offset - access.tag());
node->InsertInput(zone(), 1, offset);
+ node->AppendInput(zone(), graph()->start());
}
}
-Bounds Typer::Visitor::TypeControlEffect(Node* node) {
- UNREACHABLE();
- return Bounds();
-}
-
-
Bounds Typer::Visitor::TypeValueEffect(Node* node) {
UNREACHABLE();
return Bounds();
void* location) {
// We build a graph by hand here, because the raw machine assembler
// does not add the correct control and effect nodes.
- Node* load =
- this->graph()->NewNode(load_op, this->PointerConstant(location),
- this->Int32Constant(0), this->start());
+ Node* load = this->graph()->NewNode(
+ load_op, this->PointerConstant(location), this->Int32Constant(0),
+ this->start(), this->start());
Node* change = this->graph()->NewNode(op, load);
Node* ret = this->graph()->NewNode(this->common()->Return(), change,
this->start(), this->start());
Node* load =
t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, t.p1,
- t.jsgraph.Int32Constant(1024), t.start);
+ t.jsgraph.Int32Constant(1024), t.start, t.start);
Node* use = t.Use(load, machine_reps[i]);
t.Return(use);
t.Lower();
kMachAnyTagged};
Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0,
- t.p1, t.p2, t.start);
+ t.p1, t.p2, t.start, t.start);
t.Return(load);
t.Lower();
CHECK_EQ(IrOpcode::kLoad, load->opcode());
kMachFloat64};
Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0,
- t.p1, t.p1, t.start);
+ t.p1, t.p1, t.start, t.start);
t.Return(load);
t.Lower();
CHECK_EQ(IrOpcode::kLoad, load->opcode());
IsInt32Constant(0), IsNumberConstant(0.0), effect_matcher,
control_matcher);
}
+ Matcher<Node*> IsLoadHeapNumber(const Matcher<Node*>& value_matcher,
+ const Matcher<Node*>& control_matcher) {
+ return IsLoad(kMachFloat64, value_matcher,
+ IsInt32Constant(HeapNumberValueOffset()), graph()->start(),
+ control_matcher);
+ }
Matcher<Node*> IsWordEqual(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) {
return Is32() ? IsWord32Equal(lhs_matcher, rhs_matcher)
EXPECT_THAT(
phi,
IsPhi(
- kMachFloat64,
- IsLoad(kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
- IsControlEffect(CaptureEq(&if_true))),
+ kMachFloat64, IsLoadHeapNumber(val, CaptureEq(&if_true)),
IsChangeInt32ToFloat64(
IsWord32Sar(val, IsInt32Constant(SmiShiftAmount()))),
IsMerge(
EXPECT_THAT(
phi,
IsPhi(kMachInt32,
- IsChangeFloat64ToInt32(IsLoad(
- kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
- IsControlEffect(CaptureEq(&if_true)))),
+ IsChangeFloat64ToInt32(IsLoadHeapNumber(val, CaptureEq(&if_true))),
IsWord32Sar(val, IsInt32Constant(SmiShiftAmount())),
IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
IsIfFalse(AllOf(
EXPECT_THAT(
phi,
IsPhi(kMachUint32,
- IsChangeFloat64ToUint32(IsLoad(
- kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
- IsControlEffect(CaptureEq(&if_true)))),
+ IsChangeFloat64ToUint32(IsLoadHeapNumber(val, CaptureEq(&if_true))),
IsWord32Sar(val, IsInt32Constant(SmiShiftAmount())),
IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
IsIfFalse(AllOf(
EXPECT_THAT(
phi,
IsPhi(
- kMachFloat64,
- IsLoad(kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
- IsControlEffect(CaptureEq(&if_true))),
+ kMachFloat64, IsLoadHeapNumber(val, CaptureEq(&if_true)),
IsChangeInt32ToFloat64(IsTruncateInt64ToInt32(
IsWord64Sar(val, IsInt32Constant(SmiShiftAmount())))),
IsMerge(
EXPECT_THAT(
phi,
IsPhi(kMachInt32,
- IsChangeFloat64ToInt32(IsLoad(
- kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
- IsControlEffect(CaptureEq(&if_true)))),
+ IsChangeFloat64ToInt32(IsLoadHeapNumber(val, CaptureEq(&if_true))),
IsTruncateInt64ToInt32(
IsWord64Sar(val, IsInt32Constant(SmiShiftAmount()))),
IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
EXPECT_THAT(
phi,
IsPhi(kMachUint32,
- IsChangeFloat64ToUint32(IsLoad(
- kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
- IsControlEffect(CaptureEq(&if_true)))),
+ IsChangeFloat64ToUint32(IsLoadHeapNumber(val, CaptureEq(&if_true))),
IsTruncateInt64ToInt32(
IsWord64Sar(val, IsInt32Constant(SmiShiftAmount()))),
IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
SHARED(IfTrue, Operator::kFoldable, 0, 0, 1, 0, 1),
SHARED(IfFalse, Operator::kFoldable, 0, 0, 1, 0, 1),
SHARED(Throw, Operator::kFoldable, 1, 0, 1, 0, 1),
- SHARED(Return, Operator::kNoProperties, 1, 1, 1, 1, 1),
- SHARED(ControlEffect, Operator::kPure, 0, 0, 1, 1, 0)
+ SHARED(Return, Operator::kNoProperties, 1, 1, 1, 1, 1)
#undef SHARED
};
IsLoadMatcher(const Matcher<LoadRepresentation>& rep_matcher,
const Matcher<Node*>& base_matcher,
const Matcher<Node*>& index_matcher,
- const Matcher<Node*>& effect_matcher)
+ const Matcher<Node*>& effect_matcher,
+ const Matcher<Node*>& control_matcher)
: NodeMatcher(IrOpcode::kLoad),
rep_matcher_(rep_matcher),
base_matcher_(base_matcher),
index_matcher_(index_matcher),
- effect_matcher_(effect_matcher) {}
+ effect_matcher_(effect_matcher),
+ control_matcher_(control_matcher) {}
virtual void DescribeTo(std::ostream* os) const OVERRIDE {
NodeMatcher::DescribeTo(os);
base_matcher_.DescribeTo(os);
*os << "), index (";
index_matcher_.DescribeTo(os);
- *os << ") and effect (";
+ *os << "), effect (";
effect_matcher_.DescribeTo(os);
+ *os << ") and control (";
+ control_matcher_.DescribeTo(os);
*os << ")";
}
PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
"index", index_matcher_, listener) &&
PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
- effect_matcher_, listener));
+ effect_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+ "control", control_matcher_, listener));
}
private:
const Matcher<Node*> base_matcher_;
const Matcher<Node*> index_matcher_;
const Matcher<Node*> effect_matcher_;
+ const Matcher<Node*> control_matcher_;
};
}
-Matcher<Node*> IsControlEffect(const Matcher<Node*>& control_matcher) {
- return MakeMatcher(
- new IsControl1Matcher(IrOpcode::kControlEffect, control_matcher));
-}
-
-
Matcher<Node*> IsValueEffect(const Matcher<Node*>& value_matcher) {
return MakeMatcher(new IsUnopMatcher(IrOpcode::kValueEffect, value_matcher));
}
Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher,
const Matcher<Node*>& base_matcher,
const Matcher<Node*>& index_matcher,
- const Matcher<Node*>& effect_matcher) {
+ const Matcher<Node*>& effect_matcher,
+ const Matcher<Node*>& control_matcher) {
return MakeMatcher(new IsLoadMatcher(rep_matcher, base_matcher, index_matcher,
- effect_matcher));
+ effect_matcher, control_matcher));
}
const Matcher<Node*>& control1_matcher);
Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher);
Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher);
-Matcher<Node*> IsControlEffect(const Matcher<Node*>& control_matcher);
Matcher<Node*> IsValueEffect(const Matcher<Node*>& value_matcher);
Matcher<Node*> IsFinish(const Matcher<Node*>& value_matcher,
const Matcher<Node*>& effect_matcher);
Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher,
const Matcher<Node*>& base_matcher,
const Matcher<Node*>& index_matcher,
- const Matcher<Node*>& effect_matcher);
+ const Matcher<Node*>& effect_matcher,
+ const Matcher<Node*>& control_matcher);
Matcher<Node*> IsStore(const Matcher<MachineType>& type_matcher,
const Matcher<WriteBarrierKind>& write_barrier_matcher,
const Matcher<Node*>& base_matcher,
EXPECT_EQ(2, OperatorProperties::GetValueInputCount(op));
EXPECT_EQ(1, OperatorProperties::GetEffectInputCount(op));
- EXPECT_EQ(0, OperatorProperties::GetControlInputCount(op));
- EXPECT_EQ(3, OperatorProperties::GetTotalInputCount(op));
+ EXPECT_EQ(1, OperatorProperties::GetControlInputCount(op));
+ EXPECT_EQ(4, OperatorProperties::GetTotalInputCount(op));
EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));
EXPECT_EQ(3, OperatorProperties::GetValueInputCount(op));
EXPECT_EQ(1, OperatorProperties::GetEffectInputCount(op));
- EXPECT_EQ(0, OperatorProperties::GetControlInputCount(op));
- EXPECT_EQ(4, OperatorProperties::GetTotalInputCount(op));
+ EXPECT_EQ(1, OperatorProperties::GetControlInputCount(op));
+ EXPECT_EQ(5, OperatorProperties::GetTotalInputCount(op));
EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));