17d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Copyright 2013 the V8 project authors. All rights reserved.
27d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
37d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// found in the LICENSE file.
47d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
57d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifndef V8_COMPILER_OPERATOR_PROPERTIES_INL_H_
67d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#define V8_COMPILER_OPERATOR_PROPERTIES_INL_H_
77d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
85e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org#include "src/compiler/common-operator.h"
931c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org#include "src/compiler/js-operator.h"
107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/opcodes.h"
117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/operator-properties.h"
127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace v8 {
147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace internal {
157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace compiler {
167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
171af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orginline bool OperatorProperties::HasValueInput(const Operator* op) {
188640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  return OperatorProperties::GetValueInputCount(op) > 0;
198640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org}
208640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
211af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orginline bool OperatorProperties::HasContextInput(const Operator* op) {
228640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  IrOpcode::Value opcode = static_cast<IrOpcode::Value>(op->opcode());
238640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  return IrOpcode::IsJsOpcode(opcode);
248640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org}
258640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
261af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orginline bool OperatorProperties::HasEffectInput(const Operator* op) {
278640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  return OperatorProperties::GetEffectInputCount(op) > 0;
287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
301af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orginline bool OperatorProperties::HasControlInput(const Operator* op) {
318640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  return OperatorProperties::GetControlInputCount(op) > 0;
328640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org}
338640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
341af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orginline bool OperatorProperties::HasFrameStateInput(const Operator* op) {
35a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  if (!FLAG_turbo_deoptimization) {
36a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    return false;
37a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  }
38a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
39a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  switch (op->opcode()) {
409aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org    case IrOpcode::kFrameState:
419aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      return true;
42a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    case IrOpcode::kJSCallRuntime: {
431af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org      Runtime::FunctionId function = OpParameter<Runtime::FunctionId>(op);
4421d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org      return Linkage::NeedsFrameState(function);
45a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    }
46a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
4721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    // Strict equality cannot lazily deoptimize.
4821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    case IrOpcode::kJSStrictEqual:
4921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    case IrOpcode::kJSStrictNotEqual:
5021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org      return false;
5121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org
5221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    // Calls
5321d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    case IrOpcode::kJSCallFunction:
5421d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    case IrOpcode::kJSCallConstruct:
5521d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org
5621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    // Compare operations
5721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    case IrOpcode::kJSEqual:
5821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    case IrOpcode::kJSNotEqual:
5921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    case IrOpcode::kJSLessThan:
6021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    case IrOpcode::kJSGreaterThan:
6121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    case IrOpcode::kJSLessThanOrEqual:
6221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    case IrOpcode::kJSGreaterThanOrEqual:
6321d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org
64ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    // Binary operations
65ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    case IrOpcode::kJSBitwiseOr:
66ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    case IrOpcode::kJSBitwiseXor:
67ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    case IrOpcode::kJSBitwiseAnd:
68ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    case IrOpcode::kJSShiftLeft:
69ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    case IrOpcode::kJSShiftRight:
70ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    case IrOpcode::kJSShiftRightLogical:
71ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    case IrOpcode::kJSAdd:
72ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    case IrOpcode::kJSSubtract:
73ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    case IrOpcode::kJSMultiply:
74ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    case IrOpcode::kJSDivide:
75ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    case IrOpcode::kJSModulus:
76ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    case IrOpcode::kJSLoadProperty:
77ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    case IrOpcode::kJSStoreProperty:
78ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    case IrOpcode::kJSLoadNamed:
79ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    case IrOpcode::kJSStoreNamed:
80ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      return true;
81ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org
82a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    default:
83a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      return false;
84a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  }
85a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org}
868640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
871af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orginline int OperatorProperties::GetValueInputCount(const Operator* op) {
887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  return op->InputCount();
897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
911af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orginline int OperatorProperties::GetContextInputCount(const Operator* op) {
928640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  return OperatorProperties::HasContextInput(op) ? 1 : 0;
938640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org}
948640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
951af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orginline int OperatorProperties::GetFrameStateInputCount(const Operator* op) {
96a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  return OperatorProperties::HasFrameStateInput(op) ? 1 : 0;
97a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org}
98a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
991af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orginline int OperatorProperties::GetEffectInputCount(const Operator* op) {
1005e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  if (op->opcode() == IrOpcode::kEffectPhi ||
1015e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      op->opcode() == IrOpcode::kFinish) {
1021af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org    return OpParameter<int>(op);
1038640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  }
1048640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  if (op->HasProperty(Operator::kNoRead) && op->HasProperty(Operator::kNoWrite))
1058640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org    return 0;  // no effects.
1068640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  return 1;
1078640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org}
1088640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
1091af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orginline int OperatorProperties::GetControlInputCount(const Operator* op) {
1107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  switch (op->opcode()) {
1117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kPhi:
1127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kEffectPhi:
1135e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case IrOpcode::kControlEffect:
1147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return 1;
1157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#define OPCODE_CASE(x) case IrOpcode::k##x:
1167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      CONTROL_OP_LIST(OPCODE_CASE)
1177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#undef OPCODE_CASE
118b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      // Control operators are Operator1<int>.
119b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      return OpParameter<int>(op);
1207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    default:
1217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // Operators that have write effects must have a control
1227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // dependency. Effect dependencies only ensure the correct order of
1237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // write/read operations without consideration of control flow. Without an
1247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // explicit control dependency writes can be float in the schedule too
1257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // early along a path that shouldn't generate a side-effect.
1267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return op->HasProperty(Operator::kNoWrite) ? 0 : 1;
1277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
1287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  return 0;
1297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
1307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1311af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orginline int OperatorProperties::GetTotalInputCount(const Operator* op) {
1328640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  return GetValueInputCount(op) + GetContextInputCount(op) +
133a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org         GetFrameStateInputCount(op) + GetEffectInputCount(op) +
134a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org         GetControlInputCount(op);
1357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
1367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1378640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org// -----------------------------------------------------------------------------
1388640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org// Output properties.
1398640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
1401af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orginline bool OperatorProperties::HasValueOutput(const Operator* op) {
1418640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  return GetValueOutputCount(op) > 0;
1428640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org}
1438640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
1441af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orginline bool OperatorProperties::HasEffectOutput(const Operator* op) {
1455e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  return op->opcode() == IrOpcode::kStart ||
1465e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org         op->opcode() == IrOpcode::kControlEffect ||
1475e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org         op->opcode() == IrOpcode::kValueEffect ||
1485e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org         (op->opcode() != IrOpcode::kFinish && GetEffectInputCount(op) > 0);
1498640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org}
1508640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
1511af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orginline bool OperatorProperties::HasControlOutput(const Operator* op) {
1527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  IrOpcode::Value opcode = static_cast<IrOpcode::Value>(op->opcode());
153ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  return (opcode != IrOpcode::kEnd && IrOpcode::IsControlOpcode(opcode));
1548640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org}
1558640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
1568640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
1571af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orginline int OperatorProperties::GetValueOutputCount(const Operator* op) {
1588640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  return op->OutputCount();
1597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
1607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1611af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orginline int OperatorProperties::GetEffectOutputCount(const Operator* op) {
1628640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  return HasEffectOutput(op) ? 1 : 0;
1638640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org}
1648640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
1651af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orginline int OperatorProperties::GetControlOutputCount(const Operator* node) {
1668640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  return node->opcode() == IrOpcode::kBranch ? 2 : HasControlOutput(node) ? 1
1678640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org                                                                          : 0;
1688640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org}
1698640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
1708640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org
1711af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orginline bool OperatorProperties::IsBasicBlockBegin(const Operator* op) {
1727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  uint8_t opcode = op->opcode();
1737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  return opcode == IrOpcode::kStart || opcode == IrOpcode::kEnd ||
1747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org         opcode == IrOpcode::kDead || opcode == IrOpcode::kLoop ||
1757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org         opcode == IrOpcode::kMerge || opcode == IrOpcode::kIfTrue ||
1767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org         opcode == IrOpcode::kIfFalse;
1777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
1787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1791af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org}  // namespace compiler
1801af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org}  // namespace internal
1811af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org}  // namespace v8
1827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif  // V8_COMPILER_OPERATOR_PROPERTIES_INL_H_
184