1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/common-operator.h"
6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/graph.h"
7958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/instruction.h"
8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/schedule.h"
9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/state-values-utils.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler {
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
15c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochconst RegisterConfiguration* (*GetRegConfig)() =
16c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    RegisterConfiguration::Turbofan;
17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochFlagsCondition CommuteFlagsCondition(FlagsCondition condition) {
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (condition) {
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSignedLessThan:
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kSignedGreaterThan;
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSignedGreaterThanOrEqual:
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kSignedLessThanOrEqual;
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSignedLessThanOrEqual:
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kSignedGreaterThanOrEqual;
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSignedGreaterThan:
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kSignedLessThan;
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedLessThan:
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kUnsignedGreaterThan;
30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedGreaterThanOrEqual:
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kUnsignedLessThanOrEqual;
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedLessThanOrEqual:
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kUnsignedGreaterThanOrEqual;
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnsignedGreaterThan:
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kUnsignedLessThan;
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFloatLessThanOrUnordered:
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kFloatGreaterThanOrUnordered;
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFloatGreaterThanOrEqual:
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kFloatLessThanOrEqual;
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFloatLessThanOrEqual:
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kFloatGreaterThanOrEqual;
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFloatGreaterThanOrUnordered:
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kFloatLessThanOrUnordered;
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFloatLessThan:
45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kFloatGreaterThan;
46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFloatGreaterThanOrEqualOrUnordered:
47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kFloatLessThanOrEqualOrUnordered;
48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFloatLessThanOrEqualOrUnordered:
49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kFloatGreaterThanOrEqualOrUnordered;
50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFloatGreaterThan:
51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kFloatLessThan;
52f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kPositiveOrZero:
53f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kNegative:
54f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      UNREACHABLE();
55f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kEqual:
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kNotEqual:
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kOverflow:
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kNotOverflow:
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnorderedEqual:
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kUnorderedNotEqual:
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return condition;
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return condition;
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
68c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochbool InstructionOperand::InterferesWith(const InstructionOperand& other) const {
69c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (kSimpleFPAliasing || !this->IsFPLocationOperand() ||
70c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      !other.IsFPLocationOperand())
71c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return EqualsCanonicalized(other);
72c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // Aliasing is complex and both operands are fp locations.
73c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  const LocationOperand& loc = *LocationOperand::cast(this);
74c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  const LocationOperand& other_loc = LocationOperand::cast(other);
75c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  LocationOperand::LocationKind kind = loc.location_kind();
76c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  LocationOperand::LocationKind other_kind = other_loc.location_kind();
77c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (kind != other_kind) return false;
78c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  MachineRepresentation rep = loc.representation();
79c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  MachineRepresentation other_rep = other_loc.representation();
80c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (rep == other_rep) return EqualsCanonicalized(other);
81c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (kind == LocationOperand::REGISTER) {
82c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // FP register-register interference.
83c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return GetRegConfig()->AreAliases(rep, loc.register_code(), other_rep,
84c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                      other_loc.register_code());
85c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else {
86c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // FP slot-slot interference. Slots of different FP reps can alias because
87c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // the gap resolver may break a move into 2 or 4 equivalent smaller moves.
88c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    DCHECK_EQ(LocationOperand::STACK_SLOT, kind);
89c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    int index_hi = loc.index();
90c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    int index_lo = index_hi - (1 << ElementSizeLog2Of(rep)) / kPointerSize + 1;
91c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    int other_index_hi = other_loc.index();
92c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    int other_index_lo =
93c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        other_index_hi - (1 << ElementSizeLog2Of(other_rep)) / kPointerSize + 1;
94c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return other_index_hi >= index_lo && index_hi >= other_index_lo;
95c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
96c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return false;
9713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionOperand::Print(const RegisterConfiguration* config) const {
100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OFStream os(stdout);
101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PrintableInstructionOperand wrapper;
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  wrapper.register_configuration_ = config;
103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  wrapper.op_ = *this;
104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << wrapper << std::endl;
105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
10713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid InstructionOperand::Print() const { Print(GetRegConfig()); }
108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os,
110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                         const PrintableInstructionOperand& printable) {
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionOperand& op = printable.op_;
112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const RegisterConfiguration* conf = printable.register_configuration_;
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (op.kind()) {
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case InstructionOperand::UNALLOCATED: {
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      const UnallocatedOperand* unalloc = UnallocatedOperand::cast(&op);
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      os << "v" << unalloc->virtual_register();
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (unalloc->basic_policy() == UnallocatedOperand::FIXED_SLOT) {
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return os << "(=" << unalloc->fixed_slot_index() << "S)";
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      switch (unalloc->extended_policy()) {
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case UnallocatedOperand::NONE:
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return os;
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case UnallocatedOperand::FIXED_REGISTER:
124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return os << "(="
125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    << conf->GetGeneralRegisterName(
126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           unalloc->fixed_register_index())
127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    << ")";
12813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        case UnallocatedOperand::FIXED_FP_REGISTER:
129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return os << "(="
130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    << conf->GetDoubleRegisterName(
131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           unalloc->fixed_register_index())
132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    << ")";
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case UnallocatedOperand::MUST_HAVE_REGISTER:
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return os << "(R)";
135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case UnallocatedOperand::MUST_HAVE_SLOT:
136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return os << "(S)";
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case UnallocatedOperand::SAME_AS_FIRST_INPUT:
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return os << "(1)";
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case UnallocatedOperand::ANY:
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return os << "(-)";
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case InstructionOperand::CONSTANT:
144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return os << "[constant:" << ConstantOperand::cast(op).virtual_register()
145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                << "]";
146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::IMMEDIATE: {
1473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ImmediateOperand imm = ImmediateOperand::cast(op);
148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      switch (imm.type()) {
149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case ImmediateOperand::INLINE:
150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return os << "#" << imm.inline_value();
151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case ImmediateOperand::INDEXED:
152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return os << "[immediate:" << imm.indexed_value() << "]";
153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::EXPLICIT:
156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::ALLOCATED: {
1573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      LocationOperand allocated = LocationOperand::cast(op);
158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (op.IsStackSlot()) {
15913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        os << "[stack:" << allocated.index();
160bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      } else if (op.IsFPStackSlot()) {
16113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        os << "[fp_stack:" << allocated.index();
162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else if (op.IsRegister()) {
16313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        os << "["
16413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch           << GetRegConfig()->GetGeneralRegisterName(allocated.register_code())
16513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch           << "|R";
16613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      } else if (op.IsDoubleRegister()) {
16713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        os << "["
16813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch           << GetRegConfig()->GetDoubleRegisterName(allocated.register_code())
16913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch           << "|R";
170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else if (op.IsFloatRegister()) {
17113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        os << "["
17213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch           << GetRegConfig()->GetFloatRegisterName(allocated.register_code())
173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           << "|R";
174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        DCHECK(op.IsSimd128Register());
176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        os << "["
177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch           << GetRegConfig()->GetSimd128RegisterName(allocated.register_code())
178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch           << "|R";
179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (allocated.IsExplicit()) {
181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        os << "|E";
182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      switch (allocated.representation()) {
184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case MachineRepresentation::kNone:
185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          os << "|-";
186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case MachineRepresentation::kBit:
188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          os << "|b";
189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case MachineRepresentation::kWord8:
191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          os << "|w8";
192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case MachineRepresentation::kWord16:
194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          os << "|w16";
195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case MachineRepresentation::kWord32:
197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          os << "|w32";
198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case MachineRepresentation::kWord64:
200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          os << "|w64";
201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case MachineRepresentation::kFloat32:
203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          os << "|f32";
204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case MachineRepresentation::kFloat64:
206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          os << "|f64";
207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
208109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        case MachineRepresentation::kSimd128:
209109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          os << "|s128";
210109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          break;
211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        case MachineRepresentation::kTaggedSigned:
212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          os << "|ts";
213f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          break;
214f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        case MachineRepresentation::kTaggedPointer:
215f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          os << "|tp";
216f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          break;
217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case MachineRepresentation::kTagged:
218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          os << "|t";
219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return os << "]";
222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::INVALID:
224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return os << "(x)";
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return os;
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MoveOperands::Print(const RegisterConfiguration* config) const {
231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OFStream os(stdout);
232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PrintableInstructionOperand wrapper;
233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  wrapper.register_configuration_ = config;
234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  wrapper.op_ = destination();
235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << wrapper << " = ";
236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  wrapper.op_ = source();
237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << wrapper << std::endl;
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
24013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid MoveOperands::Print() const { Print(GetRegConfig()); }
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os,
243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                         const PrintableMoveOperands& printable) {
244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const MoveOperands& mo = *printable.move_operands_;
245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  PrintableInstructionOperand printable_op = {printable.register_configuration_,
246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                              mo.destination()};
247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  os << printable_op;
248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!mo.source().Equals(mo.destination())) {
249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    printable_op.op_ = mo.source();
250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    os << " = " << printable_op;
251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return os << ";";
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool ParallelMove::IsRedundant() const {
2573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (MoveOperands* move : *this) {
258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!move->IsRedundant()) return false;
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
263c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid ParallelMove::PrepareInsertAfter(
264c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    MoveOperands* move, ZoneVector<MoveOperands*>* to_eliminate) const {
265c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  bool no_aliasing =
266c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      kSimpleFPAliasing || !move->destination().IsFPLocationOperand();
267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MoveOperands* replacement = nullptr;
268c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  MoveOperands* eliminated = nullptr;
2693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (MoveOperands* curr : *this) {
270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (curr->IsEliminated()) continue;
271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (curr->destination().EqualsCanonicalized(move->source())) {
272c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // We must replace move's source with curr's destination in order to
273c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // insert it into this ParallelMove.
274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(!replacement);
275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      replacement = curr;
276c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (no_aliasing && eliminated != nullptr) break;
277c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    } else if (curr->destination().InterferesWith(move->destination())) {
278c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // We can eliminate curr, since move overwrites at least a part of its
279c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // destination, implying its value is no longer live.
280c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      eliminated = curr;
281c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      to_eliminate->push_back(curr);
282c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (no_aliasing && replacement != nullptr) break;
283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (replacement != nullptr) move->set_source(replacement->source());
286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochExplicitOperand::ExplicitOperand(LocationKind kind, MachineRepresentation rep,
289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 int index)
290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : LocationOperand(EXPLICIT, kind, rep, index) {
291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_IMPLIES(kind == REGISTER && !IsFloatingPoint(rep),
29213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                 GetRegConfig()->IsAllocatableGeneralCode(index));
29313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK_IMPLIES(kind == REGISTER && rep == MachineRepresentation::kFloat32,
29413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                 GetRegConfig()->IsAllocatableFloatCode(index));
29513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK_IMPLIES(kind == REGISTER && (rep == MachineRepresentation::kFloat64),
29613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                 GetRegConfig()->IsAllocatableDoubleCode(index));
297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochInstruction::Instruction(InstructionCode opcode)
300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : opcode_(opcode),
301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) |
302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 TempCountField::encode(0) | IsCallField::encode(false)),
303bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      reference_map_(nullptr),
304bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      block_(nullptr) {
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  parallel_moves_[0] = nullptr;
306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  parallel_moves_[1] = nullptr;
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochInstruction::Instruction(InstructionCode opcode, size_t output_count,
310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         InstructionOperand* outputs, size_t input_count,
311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         InstructionOperand* inputs, size_t temp_count,
312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         InstructionOperand* temps)
313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : opcode_(opcode),
314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bit_field_(OutputCountField::encode(output_count) |
315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 InputCountField::encode(input_count) |
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 TempCountField::encode(temp_count) |
317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 IsCallField::encode(false)),
318bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      reference_map_(nullptr),
319bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      block_(nullptr) {
320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  parallel_moves_[0] = nullptr;
321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  parallel_moves_[1] = nullptr;
322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t offset = 0;
323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < output_count; ++i) {
324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!outputs[i].IsInvalid());
325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    operands_[offset++] = outputs[i];
326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < input_count; ++i) {
328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!inputs[i].IsInvalid());
329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    operands_[offset++] = inputs[i];
330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < temp_count; ++i) {
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!temps[i].IsInvalid());
333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    operands_[offset++] = temps[i];
334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Instruction::AreMovesRedundant() const {
339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = Instruction::FIRST_GAP_POSITION;
340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       i <= Instruction::LAST_GAP_POSITION; i++) {
341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (parallel_moves_[i] != nullptr && !parallel_moves_[i]->IsRedundant()) {
342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return false;
343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return true;
346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Instruction::Print(const RegisterConfiguration* config) const {
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OFStream os(stdout);
350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PrintableInstruction wrapper;
351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  wrapper.instr_ = this;
352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  wrapper.register_configuration_ = config;
353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << wrapper << std::endl;
354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
35613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid Instruction::Print() const { Print(GetRegConfig()); }
357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os,
359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                         const PrintableParallelMove& printable) {
360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const ParallelMove& pm = *printable.parallel_move_;
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool first = true;
3623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (MoveOperands* move : pm) {
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (move->IsEliminated()) continue;
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!first) os << " ";
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    first = false;
366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PrintableMoveOperands pmo = {printable.register_configuration_, move};
367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    os << pmo;
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return os;
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ReferenceMap::RecordReference(const AllocatedOperand& op) {
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Do not record arguments as pointers.
375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (op.IsStackSlot() && LocationOperand::cast(op).index() < 0) return;
376bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(!op.IsFPRegister() && !op.IsFPStackSlot());
377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  reference_operands_.push_back(op);
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstd::ostream& operator<<(std::ostream& os, const ReferenceMap& pm) {
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  os << "{";
383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool first = true;
38413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  PrintableInstructionOperand poi = {GetRegConfig(), InstructionOperand()};
3853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (const InstructionOperand& op : pm.reference_operands_) {
386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!first) {
387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      os << ";";
388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first = false;
390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    poi.op_ = op;
392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << poi;
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return os << "}";
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os, const ArchOpcode& ao) {
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (ao) {
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define CASE(Name) \
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  case k##Name:    \
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return os << #Name;
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ARCH_OPCODE_LIST(CASE)
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef CASE
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return os;
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os, const AddressingMode& am) {
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (am) {
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kMode_None:
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os;
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define CASE(Name)   \
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  case kMode_##Name: \
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return os << #Name;
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TARGET_ADDRESSING_MODE_LIST(CASE)
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef CASE
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return os;
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os, const FlagsMode& fm) {
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (fm) {
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kFlags_none:
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os;
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kFlags_branch:
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << "branch";
4323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kFlags_deoptimize:
4333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      return os << "deoptimize";
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kFlags_set:
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << "set";
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return os;
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os, const FlagsCondition& fc) {
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (fc) {
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kEqual:
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << "equal";
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kNotEqual:
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << "not equal";
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kSignedLessThan:
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << "signed less than";
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kSignedGreaterThanOrEqual:
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << "signed greater than or equal";
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kSignedLessThanOrEqual:
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << "signed less than or equal";
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kSignedGreaterThan:
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << "signed greater than";
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kUnsignedLessThan:
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << "unsigned less than";
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kUnsignedGreaterThanOrEqual:
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << "unsigned greater than or equal";
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kUnsignedLessThanOrEqual:
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << "unsigned less than or equal";
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kUnsignedGreaterThan:
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << "unsigned greater than";
464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFloatLessThanOrUnordered:
465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return os << "less than or unordered (FP)";
466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFloatGreaterThanOrEqual:
467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return os << "greater than or equal (FP)";
468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFloatLessThanOrEqual:
469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return os << "less than or equal (FP)";
470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFloatGreaterThanOrUnordered:
471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return os << "greater than or unordered (FP)";
472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFloatLessThan:
473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return os << "less than (FP)";
474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFloatGreaterThanOrEqualOrUnordered:
475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return os << "greater than, equal or unordered (FP)";
476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFloatLessThanOrEqualOrUnordered:
477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return os << "less than, equal or unordered (FP)";
478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFloatGreaterThan:
479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return os << "greater than (FP)";
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kUnorderedEqual:
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << "unordered equal";
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kUnorderedNotEqual:
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << "unordered not equal";
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kOverflow:
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << "overflow";
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kNotOverflow:
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << "not overflow";
488f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kPositiveOrZero:
489f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return os << "positive or zero";
490f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kNegative:
491f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return os << "negative";
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return os;
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os,
499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                         const PrintableInstruction& printable) {
500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const Instruction& instr = *printable.instr_;
501958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  PrintableInstructionOperand printable_op = {printable.register_configuration_,
502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              InstructionOperand()};
503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << "gap ";
504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = Instruction::FIRST_GAP_POSITION;
505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       i <= Instruction::LAST_GAP_POSITION; i++) {
506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << "(";
507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (instr.parallel_moves()[i] != nullptr) {
508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintableParallelMove ppm = {printable.register_configuration_,
509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   instr.parallel_moves()[i]};
510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      os << ppm;
511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << ") ";
513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << "\n          ";
515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr.OutputCount() > 1) os << "(";
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (size_t i = 0; i < instr.OutputCount(); i++) {
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (i > 0) os << ", ";
519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    printable_op.op_ = *instr.OutputAt(i);
520958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    os << printable_op;
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr.OutputCount() > 1) os << ") = ";
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr.OutputCount() == 1) os << " = ";
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << ArchOpcodeField::decode(instr.opcode());
527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AddressingMode am = AddressingModeField::decode(instr.opcode());
528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (am != kMode_None) {
529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << " : " << AddressingModeField::decode(instr.opcode());
530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FlagsMode fm = FlagsModeField::decode(instr.opcode());
532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (fm != kFlags_none) {
533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << " && " << fm << " if " << FlagsConditionField::decode(instr.opcode());
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (instr.InputCount() > 0) {
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (size_t i = 0; i < instr.InputCount(); i++) {
537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      printable_op.op_ = *instr.InputAt(i);
538958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      os << " " << printable_op;
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
541958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return os;
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochConstant::Constant(int32_t v) : type_(kInt32), value_(v) {}
546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
547bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochConstant::Constant(RelocatablePtrConstantInfo info) {
548bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (info.type() == RelocatablePtrConstantInfo::kInt32) {
549bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    type_ = kInt32;
550bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (info.type() == RelocatablePtrConstantInfo::kInt64) {
551bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    type_ = kInt64;
552bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else {
553bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    UNREACHABLE();
554bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
555bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  value_ = info.value();
556bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  rmode_ = info.rmode();
557bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
558bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
559bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochHandle<HeapObject> Constant::ToHeapObject() const {
560bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK_EQ(kHeapObject, type());
561bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Handle<HeapObject> value(
562bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      bit_cast<HeapObject**>(static_cast<intptr_t>(value_)));
563bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return value;
564bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
566958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os, const Constant& constant) {
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (constant.type()) {
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Constant::kInt32:
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << constant.ToInt32();
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Constant::kInt64:
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << constant.ToInt64() << "l";
572958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case Constant::kFloat32:
573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return os << constant.ToFloat32() << "f";
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Constant::kFloat64:
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << constant.ToFloat64();
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Constant::kExternalReference:
577958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return os << static_cast<const void*>(
578958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                       constant.ToExternalReference().address());
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Constant::kHeapObject:
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return os << Brief(*constant.ToHeapObject());
581958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case Constant::kRpoNumber:
582958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return os << "RPO" << constant.ToRpoNumber().ToInt();
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UNREACHABLE();
585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return os;
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochPhiInstruction::PhiInstruction(Zone* zone, int virtual_register,
590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               size_t input_count)
591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : virtual_register_(virtual_register),
592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      output_(UnallocatedOperand(UnallocatedOperand::NONE, virtual_register)),
593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      operands_(input_count, InstructionOperand::kInvalidVirtualRegister,
594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                zone) {}
595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid PhiInstruction::SetInput(size_t offset, int virtual_register) {
598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(InstructionOperand::kInvalidVirtualRegister, operands_[offset]);
599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  operands_[offset] = virtual_register;
600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
602f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid PhiInstruction::RenameInput(size_t offset, int virtual_register) {
603f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK_NE(InstructionOperand::kInvalidVirtualRegister, operands_[offset]);
604f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  operands_[offset] = virtual_register;
605f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochInstructionBlock::InstructionBlock(Zone* zone, RpoNumber rpo_number,
608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   RpoNumber loop_header, RpoNumber loop_end,
609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   bool deferred, bool handler)
610958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    : successors_(zone),
611958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      predecessors_(zone),
612958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      phis_(zone),
613958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ao_number_(rpo_number),
614958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      rpo_number_(rpo_number),
615958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      loop_header_(loop_header),
616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      loop_end_(loop_end),
617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      code_start_(-1),
618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      code_end_(-1),
619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      deferred_(deferred),
620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      handler_(handler),
621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      needs_frame_(false),
622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      must_construct_frame_(false),
623c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      must_deconstruct_frame_(false) {}
624958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochsize_t InstructionBlock::PredecessorIndexOf(RpoNumber rpo_number) const {
626958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t j = 0;
627958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (InstructionBlock::Predecessors::const_iterator i = predecessors_.begin();
628958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       i != predecessors_.end(); ++i, ++j) {
629958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (*i == rpo_number) break;
630958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
631958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return j;
632958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
633958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
634958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic RpoNumber GetRpo(const BasicBlock* block) {
636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (block == nullptr) return RpoNumber::Invalid();
637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return RpoNumber::FromInt(block->rpo_number());
638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
639958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
640958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic RpoNumber GetLoopEndRpo(const BasicBlock* block) {
642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!block->IsLoopHeader()) return RpoNumber::Invalid();
643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return RpoNumber::FromInt(block->loop_end()->rpo_number());
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
647958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic InstructionBlock* InstructionBlockFor(Zone* zone,
648958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                             const BasicBlock* block) {
649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_handler =
650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      !block->empty() && block->front()->opcode() == IrOpcode::kIfException;
651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionBlock* instr_block = new (zone)
652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionBlock(zone, GetRpo(block), GetRpo(block->loop_header()),
653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       GetLoopEndRpo(block), block->deferred(), is_handler);
654958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Map successors and precessors
655958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  instr_block->successors().reserve(block->SuccessorCount());
656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (BasicBlock* successor : block->successors()) {
657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    instr_block->successors().push_back(GetRpo(successor));
658958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
659958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  instr_block->predecessors().reserve(block->PredecessorCount());
660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (BasicBlock* predecessor : block->predecessors()) {
661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    instr_block->predecessors().push_back(GetRpo(predecessor));
662958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
663958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return instr_block;
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
666f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstd::ostream& operator<<(std::ostream& os,
667f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                         PrintableInstructionBlock& printable_block) {
668f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  const InstructionBlock* block = printable_block.block_;
669f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  const RegisterConfiguration* config = printable_block.register_configuration_;
670f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  const InstructionSequence* code = printable_block.code_;
671f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
672f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  os << "B" << block->rpo_number();
673f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  os << ": AO#" << block->ao_number();
674f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (block->IsDeferred()) os << " (deferred)";
675f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!block->needs_frame()) os << " (no frame)";
676f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (block->must_construct_frame()) os << " (construct frame)";
677f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (block->must_deconstruct_frame()) os << " (deconstruct frame)";
678f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (block->IsLoopHeader()) {
679f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    os << " loop blocks: [" << block->rpo_number() << ", " << block->loop_end()
680f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch       << ")";
681f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
682f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  os << "  instructions: [" << block->code_start() << ", " << block->code_end()
683f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch     << ")" << std::endl
684f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch     << " predecessors:";
685f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
686f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  for (RpoNumber pred : block->predecessors()) {
687f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    os << " B" << pred.ToInt();
688f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
689f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  os << std::endl;
690f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
691f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  for (const PhiInstruction* phi : block->phis()) {
692f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    PrintableInstructionOperand printable_op = {config, phi->output()};
693f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    os << "     phi: " << printable_op << " =";
694f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    for (int input : phi->operands()) {
695f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      os << " v" << input;
696f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
697f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    os << std::endl;
698f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
699f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
700f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ScopedVector<char> buf(32);
701f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  PrintableInstruction printable_instr;
702f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  printable_instr.register_configuration_ = config;
703f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  for (int j = block->first_instruction_index();
704f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch       j <= block->last_instruction_index(); j++) {
705f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // TODO(svenpanne) Add some basic formatting to our streams.
706f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    SNPrintF(buf, "%5d", j);
707f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    printable_instr.instr_ = code->InstructionAt(j);
708f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    os << "   " << buf.start() << ": " << printable_instr << std::endl;
709f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
710f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
711f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  for (RpoNumber succ : block->successors()) {
712f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    os << " B" << succ.ToInt();
713f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
714f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  os << std::endl;
715f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return os;
716f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
717f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
718958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierInstructionBlocks* InstructionSequence::InstructionBlocksFor(
719958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Zone* zone, const Schedule* schedule) {
720958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  InstructionBlocks* blocks = zone->NewArray<InstructionBlocks>(1);
721958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  new (blocks) InstructionBlocks(
722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<int>(schedule->rpo_order()->size()), nullptr, zone);
723958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t rpo_number = 0;
724958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (BasicBlockVector::const_iterator it = schedule->rpo_order()->begin();
725958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       it != schedule->rpo_order()->end(); ++it, ++rpo_number) {
726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!(*blocks)[rpo_number]);
727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(GetRpo(*it).ToSize() == rpo_number);
728958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    (*blocks)[rpo_number] = InstructionBlockFor(zone, *it);
729958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
730958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ComputeAssemblyOrder(blocks);
731958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return blocks;
732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
734bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSequence::ValidateEdgeSplitForm() const {
735109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Validate blocks are in edge-split form: no block with multiple successors
736109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // has an edge to a block (== a successor) with more than one predecessors.
737109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (const InstructionBlock* block : instruction_blocks()) {
738109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (block->SuccessorCount() > 1) {
739109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      for (const RpoNumber& successor_id : block->successors()) {
740109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        const InstructionBlock* successor = InstructionBlockAt(successor_id);
741109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        // Expect precisely one predecessor: "block".
742109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        CHECK(successor->PredecessorCount() == 1 &&
743109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              successor->predecessors()[0] == block->rpo_number());
744109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
745109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
746109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
747109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
749bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSequence::ValidateDeferredBlockExitPaths() const {
7503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // A deferred block with more than one successor must have all its successors
7513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // deferred.
7523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (const InstructionBlock* block : instruction_blocks()) {
7533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (!block->IsDeferred() || block->SuccessorCount() <= 1) continue;
7543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    for (RpoNumber successor_id : block->successors()) {
7553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      CHECK(InstructionBlockAt(successor_id)->IsDeferred());
7563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
7573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
7583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
7593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
760bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSequence::ValidateDeferredBlockEntryPaths() const {
761bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // If a deferred block has multiple predecessors, they have to
762bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // all be deferred. Otherwise, we can run into a situation where a range
763bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // that spills only in deferred blocks inserts its spill in the block, but
764bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // other ranges need moves inserted by ResolveControlFlow in the predecessors,
765bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // which may clobber the register of this range.
766bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  for (const InstructionBlock* block : instruction_blocks()) {
767bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (!block->IsDeferred() || block->PredecessorCount() <= 1) continue;
768bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    for (RpoNumber predecessor_id : block->predecessors()) {
769bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      CHECK(InstructionBlockAt(predecessor_id)->IsDeferred());
770bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
771bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
772bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
773bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
774bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSequence::ValidateSSA() const {
7753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // TODO(mtrofin): We could use a local zone here instead.
7763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  BitVector definitions(VirtualRegisterCount(), zone());
7773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (const Instruction* instruction : *this) {
7783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    for (size_t i = 0; i < instruction->OutputCount(); ++i) {
7793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      const InstructionOperand* output = instruction->OutputAt(i);
7803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      int vreg = (output->IsConstant())
7813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                     ? ConstantOperand::cast(output)->virtual_register()
7823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                     : UnallocatedOperand::cast(output)->virtual_register();
7833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      CHECK(!definitions.Contains(vreg));
7843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      definitions.Add(vreg);
7853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
7863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
7873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
7883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
789958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSequence::ComputeAssemblyOrder(InstructionBlocks* blocks) {
790958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int ao = 0;
7913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (InstructionBlock* const block : *blocks) {
792958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (!block->IsDeferred()) {
793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      block->set_ao_number(RpoNumber::FromInt(ao++));
794958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
795958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
7963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (InstructionBlock* const block : *blocks) {
797958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (block->IsDeferred()) {
798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      block->set_ao_number(RpoNumber::FromInt(ao++));
799958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
800958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
801958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
802958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochInstructionSequence::InstructionSequence(Isolate* isolate,
804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         Zone* instruction_zone,
805958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                         InstructionBlocks* instruction_blocks)
806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : isolate_(isolate),
807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      zone_(instruction_zone),
808958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      instruction_blocks_(instruction_blocks),
809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      source_positions_(zone()),
810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      constants_(ConstantMap::key_compare(),
811958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                 ConstantMap::allocator_type(zone())),
812958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      immediates_(zone()),
813958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      instructions_(zone()),
814958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      next_virtual_register_(0),
815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      reference_maps_(zone()),
816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      representations_(zone()),
817c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      representation_mask_(0),
818bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      deoptimization_entries_(zone()),
819bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      current_block_(nullptr) {}
820958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint InstructionSequence::NextVirtualRegister() {
822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int virtual_register = next_virtual_register_++;
823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK_NE(virtual_register, InstructionOperand::kInvalidVirtualRegister);
824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return virtual_register;
825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochInstruction* InstructionSequence::GetBlockStart(RpoNumber rpo) const {
829958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const InstructionBlock* block = InstructionBlockAt(rpo);
830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return InstructionAt(block->code_start());
831958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
832958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
833958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSequence::StartBlock(RpoNumber rpo) {
835bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK_NULL(current_block_);
836bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  current_block_ = InstructionBlockAt(rpo);
837958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int code_start = static_cast<int>(instructions_.size());
838bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  current_block_->set_code_start(code_start);
839958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
840958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
841958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSequence::EndBlock(RpoNumber rpo) {
843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int end = static_cast<int>(instructions_.size());
844bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK_EQ(current_block_->rpo_number(), rpo);
845bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (current_block_->code_start() == end) {  // Empty block.  Insert a nop.
846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AddInstruction(Instruction::New(zone(), kArchNop));
847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    end = static_cast<int>(instructions_.size());
848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
849bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(current_block_->code_start() >= 0 &&
850bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         current_block_->code_start() < end);
851bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  current_block_->set_code_end(end);
852bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  current_block_ = nullptr;
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
856958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierint InstructionSequence::AddInstruction(Instruction* instr) {
857bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK_NOT_NULL(current_block_);
858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int index = static_cast<int>(instructions_.size());
859bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  instr->set_block(current_block_);
860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  instructions_.push_back(instr);
861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (instr->NeedsReferenceMap()) {
862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(instr->reference_map() == nullptr);
863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ReferenceMap* reference_map = new (zone()) ReferenceMap(zone());
864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    reference_map->set_instruction_position(index);
865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    instr->set_reference_map(reference_map);
866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    reference_maps_.push_back(reference_map);
867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return index;
869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochInstructionBlock* InstructionSequence::GetInstructionBlock(
873958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    int instruction_index) const {
874bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return instructions()[instruction_index]->block();
875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic MachineRepresentation FilterRepresentation(MachineRepresentation rep) {
879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (rep) {
880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kBit:
881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord8:
882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord16:
883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return InstructionSequence::DefaultRepresentation();
884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord32:
885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord64:
886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat32:
887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat64:
888109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case MachineRepresentation::kSimd128:
889f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTaggedSigned:
890f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTaggedPointer:
891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kTagged:
892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return rep;
893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kNone:
894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return MachineRepresentation::kNone;
898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochMachineRepresentation InstructionSequence::GetRepresentation(
902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int virtual_register) const {
903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_LE(0, virtual_register);
904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_LT(virtual_register, VirtualRegisterCount());
905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (virtual_register >= static_cast<int>(representations_.size())) {
906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return DefaultRepresentation();
907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return representations_[virtual_register];
909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSequence::MarkAsRepresentation(MachineRepresentation rep,
913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                               int virtual_register) {
914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_LE(0, virtual_register);
915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_LT(virtual_register, VirtualRegisterCount());
916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (virtual_register >= static_cast<int>(representations_.size())) {
917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    representations_.resize(VirtualRegisterCount(), DefaultRepresentation());
918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  rep = FilterRepresentation(rep);
920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_IMPLIES(representations_[virtual_register] != rep,
921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 representations_[virtual_register] == DefaultRepresentation());
922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  representations_[virtual_register] = rep;
923c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  representation_mask_ |= 1 << static_cast<int>(rep);
924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
926f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochint InstructionSequence::AddDeoptimizationEntry(
927f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    FrameStateDescriptor* descriptor, DeoptimizeReason reason) {
928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int deoptimization_id = static_cast<int>(deoptimization_entries_.size());
929f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  deoptimization_entries_.push_back(DeoptimizationEntry(descriptor, reason));
930f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return deoptimization_id;
931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
933f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochDeoptimizationEntry const& InstructionSequence::GetDeoptimizationEntry(
934f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int state_id) {
935f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return deoptimization_entries_[state_id];
936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRpoNumber InstructionSequence::InputRpo(Instruction* instr, size_t index) {
940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand* operand = instr->InputAt(index);
941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Constant constant =
942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      operand->IsImmediate()
943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          ? GetImmediate(ImmediateOperand::cast(operand))
944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          : GetConstant(ConstantOperand::cast(operand)->virtual_register());
945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return constant.ToRpoNumber();
946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool InstructionSequence::GetSourcePosition(const Instruction* instr,
950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            SourcePosition* result) const {
951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto it = source_positions_.find(instr);
952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (it == source_positions_.end()) return false;
953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  *result = it->second;
954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return true;
955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSequence::SetSourcePosition(const Instruction* instr,
959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            SourcePosition value) {
960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  source_positions_.insert(std::make_pair(instr, value));
961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSequence::Print(const RegisterConfiguration* config) const {
964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OFStream os(stdout);
965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PrintableInstructionSequence wrapper;
966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  wrapper.register_configuration_ = config;
967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  wrapper.sequence_ = this;
968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << wrapper << std::endl;
969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
97113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid InstructionSequence::Print() const { Print(GetRegConfig()); }
972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
973109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InstructionSequence::PrintBlock(const RegisterConfiguration* config,
974109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                     int block_id) const {
975109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  OFStream os(stdout);
976109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  RpoNumber rpo = RpoNumber::FromInt(block_id);
977109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const InstructionBlock* block = InstructionBlockAt(rpo);
978109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CHECK(block->rpo_number() == rpo);
979f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  PrintableInstructionBlock printable_block = {config, block, this};
980f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  os << printable_block << std::endl;
981109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
982109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
983109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InstructionSequence::PrintBlock(int block_id) const {
98413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  PrintBlock(GetRegConfig(), block_id);
985109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
987c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochconst RegisterConfiguration*
988c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochInstructionSequence::GetRegisterConfigurationForTesting() {
989c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return GetRegConfig();
990c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
991c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
992958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierFrameStateDescriptor::FrameStateDescriptor(
993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Zone* zone, FrameStateType type, BailoutId bailout_id,
994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    OutputFrameStateCombine state_combine, size_t parameters_count,
995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    size_t locals_count, size_t stack_count,
996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MaybeHandle<SharedFunctionInfo> shared_info,
997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FrameStateDescriptor* outer_state)
998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : type_(type),
999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bailout_id_(bailout_id),
1000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_state_combine_(state_combine),
1001958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      parameters_count_(parameters_count),
1002958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      locals_count_(locals_count),
1003958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      stack_count_(stack_count),
1004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      values_(zone),
1005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      shared_info_(shared_info),
1006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      outer_state_(outer_state) {}
1007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1008958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1009958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniersize_t FrameStateDescriptor::GetSize(OutputFrameStateCombine combine) const {
1010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t size = 1 + parameters_count() + locals_count() + stack_count() +
1011958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                (HasContext() ? 1 : 0);
1012958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  switch (combine.kind()) {
1013958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case OutputFrameStateCombine::kPushOutput:
1014958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      size += combine.GetPushCount();
1015958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1016958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case OutputFrameStateCombine::kPokeAt:
1017958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1019958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return size;
1020958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1021958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1022958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1023958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniersize_t FrameStateDescriptor::GetTotalSize() const {
1024958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t total_size = 0;
1025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (const FrameStateDescriptor* iter = this; iter != nullptr;
1026958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       iter = iter->outer_state_) {
1027958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    total_size += iter->GetSize();
1028958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1029958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return total_size;
1030958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1031958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1032958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1033958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniersize_t FrameStateDescriptor::GetFrameCount() const {
1034958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t count = 0;
1035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (const FrameStateDescriptor* iter = this; iter != nullptr;
1036958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       iter = iter->outer_state_) {
1037958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    ++count;
1038958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1039958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return count;
1040958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1041958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1042958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1043958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniersize_t FrameStateDescriptor::GetJSFrameCount() const {
1044958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t count = 0;
1045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (const FrameStateDescriptor* iter = this; iter != nullptr;
1046958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       iter = iter->outer_state_) {
1047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (FrameStateFunctionInfo::IsJSFunctionType(iter->type_)) {
1048958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ++count;
1049958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1050958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1051958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return count;
1052958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1053958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1054958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstd::ostream& operator<<(std::ostream& os, const RpoNumber& rpo) {
1056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return os << rpo.ToSize();
1057958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1058958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1059958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1060958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os,
1061958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                         const PrintableInstructionSequence& printable) {
1062958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const InstructionSequence& code = *printable.sequence_;
1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (size_t i = 0; i < code.immediates_.size(); ++i) {
1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Constant constant = code.immediates_[i];
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    os << "IMM#" << i << ": " << constant << "\n";
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int i = 0;
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (ConstantMap::const_iterator it = code.constants_.begin();
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       it != code.constants_.end(); ++i, ++it) {
1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    os << "CST#" << i << ": v" << it->first << " = " << it->second << "\n";
1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1072f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  PrintableInstructionBlock printable_block = {
1073f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      printable.register_configuration_, nullptr, printable.sequence_};
1074958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (int i = 0; i < code.InstructionBlockCount(); i++) {
1075f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    printable_block.block_ = code.InstructionBlockAt(RpoNumber::FromInt(i));
1076f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    os << printable_block;
1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return os;
1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace compiler
1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace internal
1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8
1084