Reviewers: Michael Starzinger,

Description:
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.

[email protected]
BUG=

Please review this at https://codereview.chromium.org/651843004/

Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+27, -9 lines):
  M src/compiler/common-operator.h
  M src/compiler/common-operator.cc
  M src/compiler/instruction-selector.cc
  M src/compiler/opcodes.h
  M src/compiler/operator-properties-inl.h
  M src/compiler/verifier.cc


Index: src/compiler/common-operator.cc
diff --git a/src/compiler/common-operator.cc b/src/compiler/common-operator.cc index e7d712a99016a55dee5fad4efba8ba9cdaed368d..ef9e2342071d3e2c2725aa53b8c6176ce339faf6 100644
--- a/src/compiler/common-operator.cc
+++ b/src/compiler/common-operator.cc
@@ -155,6 +155,13 @@ const Operator* CommonOperatorBuilder::Loop(int controls) {
 }


+const Operator* CommonOperatorBuilder::Terminate(int effects) {
+  return new (zone())
+ ControlOperator(IrOpcode::kTerminate, Operator::kNoProperties, 0, effects,
+                      1, "Terminate");
+}
+
+
 const Operator* CommonOperatorBuilder::Parameter(int index) {
return new (zone()) Operator1<int>(IrOpcode::kParameter, Operator::kPure, 1,
                                      1, "Parameter", index);
Index: src/compiler/common-operator.h
diff --git a/src/compiler/common-operator.h b/src/compiler/common-operator.h
index c65e1a7db5abbe8cc0078bc8bba3a416729e95fa..c59ca49f5c9d67368b38b7df16bc9d0b70564d53 100644
--- a/src/compiler/common-operator.h
+++ b/src/compiler/common-operator.h
@@ -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);
Index: src/compiler/instruction-selector.cc
diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc index e1b859f4f8e67a3856eaab8fa6fbe6763cc49daf..17c227acc70d4636d409b94487ae48b96a6a33fc 100644
--- a/src/compiler/instruction-selector.cc
+++ b/src/compiler/instruction-selector.cc
@@ -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:
Index: src/compiler/opcodes.h
diff --git a/src/compiler/opcodes.h b/src/compiler/opcodes.h
index 8b68e603fb882ec6f2f8a89a3f783470e057e414..cbc0d0760cb2202e2ad42650a13f17e49ddd5bc6 100644
--- a/src/compiler/opcodes.h
+++ b/src/compiler/opcodes.h
@@ -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) \
Index: src/compiler/operator-properties-inl.h
diff --git a/src/compiler/operator-properties-inl.h b/src/compiler/operator-properties-inl.h index 70810c65497f6098686d0ba46a24a59a179a91a8..4d851716df43968ab64614515b5b7d8c5cf99539 100644
--- a/src/compiler/operator-properties-inl.h
+++ b/src/compiler/operator-properties-inl.h
@@ -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) {
Index: src/compiler/verifier.cc
diff --git a/src/compiler/verifier.cc b/src/compiler/verifier.cc
index ab70ade6e569d8d294ace43ea487692b4d5b9de7..d0b40e74fc4f3b88ae289ddbd5f8da63a07f8de7 100644
--- a/src/compiler/verifier.cc
+++ b/src/compiler/verifier.cc
@@ -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
     // ----------------


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to