if (count >= 1) {
// Add the frame state for after the operation.
- DCHECK_EQ(IrOpcode::kDead,
+ DCHECK_EQ(IrOpcode::kDeadValue,
NodeProperties::GetFrameStateInput(node, 0)->opcode());
Node* frame_state_after =
if (count >= 2) {
// Add the frame state for before the operation.
- DCHECK_EQ(IrOpcode::kDead,
+ DCHECK_EQ(IrOpcode::kDeadValue,
NodeProperties::GetFrameStateInput(node, 1)->opcode());
NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_);
}
OutputFrameStateCombine combine) {
if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
-
- DCHECK_EQ(IrOpcode::kDead,
+ DCHECK_EQ(IrOpcode::kDeadValue,
NodeProperties::GetFrameStateInput(node, 0)->opcode());
NodeProperties::ReplaceFrameStateInput(
node, 0, environment()->Checkpoint(ast_id, combine));
}
for (int i = 0; i < frame_state_count; i++) {
// The frame state will be inserted later. Here we misuse
- // the {DeadControl} node as a sentinel to be later overwritten
+ // the {DeadValue} node as a sentinel to be later overwritten
// with the real frame state.
- *current_input++ = jsgraph()->DeadControl();
+ *current_input++ = jsgraph()->DeadValue();
}
if (has_effect) {
*current_input++ = environment_->GetEffectDependency();
liveness_block_ = nullptr;
}
bool IsMarkedAsUnreachable() {
- return GetControlDependency()->opcode() == IrOpcode::kDead;
+ return GetControlDependency()->opcode() == IrOpcode::kDeadControl;
}
// Merge another environment into this one.
#define CACHED_OP_LIST(V) \
- V(Dead, Operator::kFoldable, 0, 0, 0, 0, 0, 1) \
+ V(DeadValue, Operator::kPure, 0, 0, 0, 1, 0, 0) \
+ V(DeadEffect, Operator::kPure, 0, 0, 0, 0, 1, 0) \
+ V(DeadControl, Operator::kFoldable, 0, 0, 0, 0, 0, 1) \
V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
public:
explicit CommonOperatorBuilder(Zone* zone);
- const Operator* Dead();
const Operator* End(size_t control_input_count);
const Operator* Branch(BranchHint = BranchHint::kNone);
const Operator* IfTrue();
const Operator* Return();
const Operator* Terminate();
+ const Operator* DeadValue();
+ const Operator* DeadEffect();
+ const Operator* DeadControl();
+
const Operator* Start(int num_formal_parameters);
const Operator* Loop(int control_input_count);
const Operator* Merge(int control_input_count);
node->opcode() == IrOpcode::kLoop) {
// If a node has only one control input and it is dead, replace with dead.
Node* control = NodeProperties::GetControlInput(node);
- if (control->opcode() == IrOpcode::kDead) {
+ if (control->opcode() == IrOpcode::kDeadControl) {
TRACE("ControlDead: #%d:%s\n", node->id(), node->op()->mnemonic());
return Replace(control);
}
auto const inputs = node->inputs();
for (auto it = inputs.begin(); n > 1; --n, ++it) {
Node* input = *it;
- if (input->opcode() == IrOpcode::kDead) continue; // ignore dead inputs.
- if (input != node && input != replacement) { // non-redundant input.
+ // Ignore dead inputs.
+ if (input->opcode() == IrOpcode::kDeadControl) continue;
+ // Non-redundant input.
+ if (input != node && input != replacement) {
if (replacement != NULL) return node;
replacement = input;
}
int live = 0;
for (int index = 0; index < node->InputCount(); ++index) {
// Skip dead inputs.
- if (node->InputAt(index)->opcode() == IrOpcode::kDead) continue;
+ if (node->InputAt(index)->opcode() == IrOpcode::kDeadControl) continue;
// Compact live inputs.
if (index != live) node->ReplaceInput(live, node->InputAt(index));
++live;
int index = 0;
int live_index = 0;
for (Node* const input : node->inputs()) {
- if (input->opcode() != IrOpcode::kDead) {
+ if (input->opcode() != IrOpcode::kDeadControl) {
live++;
live_index = index;
}
int live = 0;
for (int i = 0; i < merge->InputCount(); i++) {
// skip dead inputs.
- if (merge->InputAt(i)->opcode() == IrOpcode::kDead) continue;
+ if (merge->InputAt(i)->opcode() == IrOpcode::kDeadControl) continue;
// compact live inputs.
if (live != i) node->ReplaceInput(live, node->InputAt(i));
live++;
os_ << " shape=\"record\"\n";
switch (node->opcode()) {
case IrOpcode::kEnd:
- case IrOpcode::kDead:
+ case IrOpcode::kDeadControl:
case IrOpcode::kStart:
os_ << " style=\"diagonals\"\n";
break;
}
+Node* JSGraph::DeadValue() {
+ return CACHED(kDeadValue, graph()->NewNode(common()->DeadValue()));
+}
+
+
Node* JSGraph::DeadControl() {
- return CACHED(kDeadControl, graph()->NewNode(common()->Dead()));
+ return CACHED(kDeadControl, graph()->NewNode(common()->DeadControl()));
}
// cannot deopt.
Node* EmptyFrameState();
- // Create a control node that serves as control dependency for dead nodes.
+ // Creates a value node that servers as value input for dead nodes.
+ Node* DeadValue();
+
+ // Creates a control node that serves as control dependency for dead nodes.
Node* DeadControl();
JSOperatorBuilder* javascript() const { return javascript_; }
kOneConstant,
kNaNConstant,
kEmptyFrameState,
+ kDeadValue,
kDeadControl,
kNumCachedNodes // Must remain last.
};
class CopyVisitor {
public:
CopyVisitor(Graph* source_graph, Graph* target_graph, Zone* temp_zone)
- : sentinel_op_(IrOpcode::kDead, Operator::kNoProperties, "Sentinel", 0, 0,
- 0, 0, 0, 0),
+ : sentinel_op_(IrOpcode::kDeadControl, Operator::kNoProperties,
+ "Sentinel", 0, 0, 0, 0, 0, 0),
sentinel_(target_graph->NewNode(&sentinel_op_)),
copies_(source_graph->NodeCount(), sentinel_, temp_zone),
source_graph_(source_graph),
5 + (loop->TotalSize() + exits.size() + rets.size()) * 2;
Peeling peeling(graph, tmp_zone, estimated_peeled_size, &iter->node_pairs_);
- Node* dead = graph->NewNode(common->Dead());
+ Node* dead = graph->NewNode(common->DeadControl());
// Map the loop header nodes to their entry values.
for (Node* node : loop_tree->HeaderNodes(loop)) {
// Opcodes for control operators.
#define CONTROL_OP_LIST(V) \
V(Start) \
- V(Dead) \
V(Loop) \
V(Branch) \
V(Switch) \
V(Terminate) \
V(OsrNormalEntry) \
V(OsrLoopEntry) \
+ V(DeadControl) \
V(Throw) \
V(End)
#define COMMON_OP_LIST(V) \
CONSTANT_OP_LIST(V) \
- INNER_OP_LIST(V)
+ INNER_OP_LIST(V) \
+ V(DeadEffect) \
+ V(DeadValue)
+
// Opcodes for JavaScript operators.
#define JS_COMPARE_BINOP_LIST(V) \
// Returns true if opcode for common operator.
static bool IsCommonOpcode(Value value) {
- return kStart <= value && value <= kProjection;
+ return kStart <= value && value <= kDeadValue;
}
// Returns true if opcode for control operator.
bool OperatorProperties::IsBasicBlockBegin(const Operator* op) {
Operator::Opcode const opcode = op->opcode();
return opcode == IrOpcode::kStart || opcode == IrOpcode::kEnd ||
- opcode == IrOpcode::kDead || opcode == IrOpcode::kLoop ||
+ opcode == IrOpcode::kDeadControl || opcode == IrOpcode::kLoop ||
opcode == IrOpcode::kMerge || opcode == IrOpcode::kIfTrue ||
opcode == IrOpcode::kIfFalse || opcode == IrOpcode::kIfSuccess ||
opcode == IrOpcode::kIfException || opcode == IrOpcode::kIfValue ||
class JSGraphReducer final : public GraphReducer {
public:
JSGraphReducer(JSGraph* jsgraph, Zone* zone)
- : GraphReducer(zone, jsgraph->graph(), jsgraph->TheHoleConstant(),
+ : GraphReducer(zone, jsgraph->graph(), jsgraph->DeadValue(),
jsgraph->DeadControl()) {}
~JSGraphReducer() final {}
};
// Common operators.
//------------------------------------------------------------------
case IrOpcode::kStart:
- case IrOpcode::kDead:
+ case IrOpcode::kDeadControl:
return VisitLeaf(node, 0);
case IrOpcode::kParameter: {
// TODO(titzer): use representation from linkage.
#undef DECLARE_CASE
#define DECLARE_CASE(x) case IrOpcode::k##x:
- DECLARE_CASE(Dead)
DECLARE_CASE(Loop)
DECLARE_CASE(Branch)
DECLARE_CASE(IfTrue)
DECLARE_CASE(Terminate)
DECLARE_CASE(OsrNormalEntry)
DECLARE_CASE(OsrLoopEntry)
+ DECLARE_CASE(DeadControl)
DECLARE_CASE(Throw)
DECLARE_CASE(End)
#undef DECLARE_CASE
#undef DECLARE_CASE
#define DECLARE_CASE(x) case IrOpcode::k##x:
- DECLARE_CASE(Dead)
DECLARE_CASE(Loop)
DECLARE_CASE(Branch)
DECLARE_CASE(IfTrue)
DECLARE_CASE(Terminate)
DECLARE_CASE(OsrNormalEntry)
DECLARE_CASE(OsrLoopEntry)
+ DECLARE_CASE(DeadControl)
DECLARE_CASE(Throw)
DECLARE_CASE(End)
#undef DECLARE_CASE
}
+Bounds Typer::Visitor::TypeDeadValue(Node* node) {
+ return Bounds(Type::None(zone()), Type::Any(zone()));
+}
+
+
+Bounds Typer::Visitor::TypeDeadEffect(Node* node) {
+ UNREACHABLE();
+ return Bounds();
+}
+
+
Bounds Typer::Visitor::TypeFrameState(Node* node) {
// TODO(rossberg): Ideally FrameState wouldn't have a value output.
return Bounds(Type::None(zone()), Type::Internal(zone()));
// Type is empty.
CheckNotTyped(node);
break;
- case IrOpcode::kDead:
+ case IrOpcode::kDeadValue:
+ case IrOpcode::kDeadEffect:
+ case IrOpcode::kDeadControl:
// Dead is never connected to the graph.
// TODO(mstarzinger): Make the GraphReducer immediately perform control
// reduction in case control is killed. This will prevent {Dead} from
one(jsgraph.OneConstant()),
half(jsgraph.Constant(0.5)),
self(graph.NewNode(common.Int32Constant(0xaabbccdd))),
- dead(graph.NewNode(common.Dead())) {
+ dead(graph.NewNode(common.DeadControl())) {
graph.SetEnd(end);
graph.SetStart(start);
leaf[0] = zero;
if (use->opcode() == IrOpcode::kIfTrue) {
Node* result = ControlReducer::ReduceIfNodeForTesting(&jsgraph, use);
if (expected == kTrue) CHECK_EQ(control, result);
- if (expected == kFalse) CHECK_EQ(IrOpcode::kDead, result->opcode());
+ if (expected == kFalse) {
+ CHECK_EQ(IrOpcode::kDeadControl, result->opcode());
+ }
if (expected == kUnknown) CHECK_EQ(use, result);
} else if (use->opcode() == IrOpcode::kIfFalse) {
Node* result = ControlReducer::ReduceIfNodeForTesting(&jsgraph, use);
if (expected == kFalse) CHECK_EQ(control, result);
- if (expected == kTrue) CHECK_EQ(IrOpcode::kDead, result->opcode());
+ if (expected == kTrue) {
+ CHECK_EQ(IrOpcode::kDeadControl, result->opcode());
+ }
if (expected == kUnknown) CHECK_EQ(use, result);
} else {
UNREACHABLE();
int count = selector.count;
if (count == 0) {
// result should be dead.
- CHECK_EQ(IrOpcode::kDead, result->opcode());
+ CHECK_EQ(IrOpcode::kDeadControl, result->opcode());
} else if (count == 1) {
// merge should be replaced with one of the controls.
CHECK_EQ(controls[selector.single_index()], result);
one(jsgraph.OneConstant()),
half(jsgraph.Constant(0.5)),
self(graph.NewNode(common.Int32Constant(0xaabbccdd))),
- dead(graph.NewNode(common.Dead())),
+ dead(graph.NewNode(common.DeadControl())),
loop_tree(NULL) {
graph.SetEnd(end);
graph.SetStart(start);
value_input_count, effect_input_count, control_input_count, \
value_output_count, effect_output_count, control_output_count \
}
- SHARED(Dead, Operator::kFoldable, 0, 0, 0, 0, 0, 1),
SHARED(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1),
SHARED(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1),
SHARED(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1),
SHARED(Throw, Operator::kKontrol, 1, 1, 1, 0, 0, 1),
SHARED(Return, Operator::kNoThrow, 1, 1, 1, 0, 0, 1),
- SHARED(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1)
+ SHARED(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1),
+ SHARED(DeadValue, Operator::kPure, 0, 0, 0, 1, 0, 0),
+ SHARED(DeadEffect, Operator::kPure, 0, 0, 0, 0, 1, 0),
+ SHARED(DeadControl, Operator::kFoldable, 0, 0, 0, 0, 0, 1)
#undef SHARED
};
using AdvancedReducer::ReplaceWithValue;
};
-const Operator kMockOperator(IrOpcode::kDead, Operator::kNoProperties,
+const Operator kMockOperator(IrOpcode::kDeadControl, Operator::kNoProperties,
"MockOperator", 0, 0, 0, 1, 0, 0);
-const Operator kMockOpEffect(IrOpcode::kDead, Operator::kNoProperties,
+const Operator kMockOpEffect(IrOpcode::kDeadControl, Operator::kNoProperties,
"MockOpEffect", 0, 1, 0, 1, 1, 0);
-const Operator kMockOpControl(IrOpcode::kDead, Operator::kNoProperties,
+const Operator kMockOpControl(IrOpcode::kDeadControl, Operator::kNoProperties,
"MockOpControl", 0, 0, 1, 1, 0, 1);
const IfExceptionHint kNoHint = IfExceptionHint::kLocallyCaught;
namespace {
-const Operator kDead0(IrOpcode::kDead, Operator::kNoProperties, "Dead0", 0, 0,
- 1, 0, 0, 0);
-const Operator kLive0(IrOpcode::kDead, Operator::kNoProperties, "Live0", 0, 0,
- 1, 0, 0, 1);
+const Operator kDead0(IrOpcode::kDeadControl, Operator::kNoProperties, "Dead0",
+ 0, 0, 1, 0, 0, 0);
+const Operator kLive0(IrOpcode::kDeadControl, Operator::kNoProperties, "Live0",
+ 0, 0, 1, 0, 0, 1);
} // namespace
namespace {
-const Operator kMockOperator(IrOpcode::kDead, Operator::kNoProperties,
+const Operator kMockOperator(IrOpcode::kDeadControl, Operator::kNoProperties,
"MockOperator", 0, 0, 0, 1, 1, 2);
const Operator kMockCallOperator(IrOpcode::kCall, Operator::kNoProperties,
"MockCallOperator", 0, 0, 0, 0, 0, 2);