Commit 5a177426 authored by titzer@chromium.org's avatar titzer@chromium.org

Add Terminate operator.

Terminate is need for non-terminating loops (NTLs) that can appear after optimizing control flow. It gathers the control and effect(s) from a NTL and connects them to end so that they are not dead-code removed.

R=mstarzinger@chromium.org
BUG=

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24812 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 7a70d6a0
......@@ -155,6 +155,13 @@ const Operator* CommonOperatorBuilder::Loop(int controls) {
}
const Operator* CommonOperatorBuilder::Terminate(int effects) {
return new (zone()) Operator1<int>(IrOpcode::kTerminate,
Operator::kNoRead | Operator::kNoWrite, 0,
0, "Terminate", effects);
}
const Operator* CommonOperatorBuilder::Parameter(int index) {
return new (zone()) Operator1<int>(IrOpcode::kParameter, Operator::kPure, 1,
1, "Parameter", index);
......
......@@ -137,6 +137,7 @@ class CommonOperatorBuilder FINAL {
const Operator* IfTrue();
const Operator* IfFalse();
const Operator* Throw();
const Operator* Terminate(int effects);
const Operator* Return();
const Operator* Start(int num_formal_parameters);
......
......@@ -457,6 +457,7 @@ MachineType InstructionSelector::GetMachineType(Node* node) {
case IrOpcode::kIfFalse:
case IrOpcode::kEffectPhi:
case IrOpcode::kMerge:
case IrOpcode::kTerminate:
// No code needed for these graph artifacts.
return kMachNone;
case IrOpcode::kFinish:
......
......@@ -7,13 +7,14 @@
// Opcodes for control operators.
#define INNER_CONTROL_OP_LIST(V) \
V(Dead) \
V(Loop) \
V(Branch) \
V(IfTrue) \
V(IfFalse) \
V(Merge) \
V(Return) \
V(Dead) \
V(Loop) \
V(Branch) \
V(IfTrue) \
V(IfFalse) \
V(Merge) \
V(Return) \
V(Terminate) \
V(Throw)
#define CONTROL_OP_LIST(V) \
......
......@@ -104,7 +104,8 @@ inline int OperatorProperties::GetFrameStateInputCount(const Operator* op) {
inline int OperatorProperties::GetEffectInputCount(const Operator* op) {
if (op->opcode() == IrOpcode::kEffectPhi ||
op->opcode() == IrOpcode::kFinish) {
op->opcode() == IrOpcode::kFinish ||
op->opcode() == IrOpcode::kTerminate) {
return OpParameter<int>(op);
}
if (op->HasProperty(Operator::kNoRead) && op->HasProperty(Operator::kNoWrite))
......@@ -154,7 +155,8 @@ inline bool OperatorProperties::HasValueOutput(const Operator* op) {
inline bool OperatorProperties::HasEffectOutput(const Operator* op) {
return op->opcode() == IrOpcode::kStart ||
op->opcode() == IrOpcode::kValueEffect ||
(op->opcode() != IrOpcode::kFinish && GetEffectInputCount(op) > 0);
(op->opcode() != IrOpcode::kFinish &&
op->opcode() != IrOpcode::kTerminate && GetEffectInputCount(op) > 0);
}
inline bool OperatorProperties::HasControlOutput(const Operator* op) {
......
......@@ -243,6 +243,12 @@ GenericGraphVisit::Control Verifier::Visitor::Pre(Node* node) {
// Type is empty.
CheckNotTyped(node);
break;
case IrOpcode::kTerminate:
// Type is empty.
CheckNotTyped(node);
CHECK_EQ(1, control_count);
CHECK_EQ(input_count, 1 + effect_count);
break;
// Common operators
// ----------------
......
......@@ -1888,4 +1888,31 @@ TEST(BranchHintFalse) {
CHECK(!schedule->block(f)->deferred());
}
TEST(ScheduleTerminate) {
HandleAndZoneScope scope;
Graph graph(scope.main_zone());
CommonOperatorBuilder common(scope.main_zone());
Node* start = graph.NewNode(common.Start(1));
graph.SetStart(start);
Node* loop = graph.NewNode(common.Loop(2), start, start);
loop->ReplaceInput(1, loop); // self loop, NTL.
Node* effect = graph.NewNode(common.EffectPhi(1), start, loop);
effect->ReplaceInput(0, effect);
Node* terminate = graph.NewNode(common.Terminate(1), effect, loop);
Node* end = graph.NewNode(common.End(), terminate);
graph.SetEnd(end);
Schedule* schedule = ComputeAndVerifySchedule(5, &graph);
BasicBlock* block = schedule->block(loop);
CHECK_NE(NULL, loop);
CHECK_EQ(block, schedule->block(effect));
CHECK_GE(block->rpo_number(), 0);
}
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment