17d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved. 27d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 37d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// found in the LICENSE file. 47d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 57d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifndef V8_COMPILER_INSTRUCTION_H_ 67d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#define V8_COMPILER_INSTRUCTION_H_ 77d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 87d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include <deque> 97d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include <map> 107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include <set> 117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/common-operator.h" 137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/frame.h" 147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/graph.h" 157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/instruction-codes.h" 167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/opcodes.h" 177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/schedule.h" 18b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org// TODO(titzer): don't include the macro-assembler? 19b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org#include "src/macro-assembler.h" 207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/zone-allocator.h" 217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace v8 { 237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace internal { 247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Forward declarations. 267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass OStream; 277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace compiler { 297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Forward declarations. 317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass Linkage; 327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// A couple of reserved opcodes are used for internal use. 347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgconst InstructionCode kGapInstruction = -1; 357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgconst InstructionCode kBlockStartInstruction = -2; 367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgconst InstructionCode kSourcePositionInstruction = -3; 377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#define INSTRUCTION_OPERAND_LIST(V) \ 407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(Constant, CONSTANT, 128) \ 417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(Immediate, IMMEDIATE, 128) \ 427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(StackSlot, STACK_SLOT, 128) \ 437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(DoubleStackSlot, DOUBLE_STACK_SLOT, 128) \ 447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(Register, REGISTER, Register::kNumRegisters) \ 457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org V(DoubleRegister, DOUBLE_REGISTER, DoubleRegister::kMaxNumRegisters) 467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass InstructionOperand : public ZoneObject { 487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org enum Kind { 507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org INVALID, 517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org UNALLOCATED, 527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org CONSTANT, 537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org IMMEDIATE, 547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org STACK_SLOT, 557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org DOUBLE_STACK_SLOT, 567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org REGISTER, 577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org DOUBLE_REGISTER 587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org }; 597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand() : value_(KindField::encode(INVALID)) {} 617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand(Kind kind, int index) { ConvertTo(kind, index); } 627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Kind kind() const { return KindField::decode(value_); } 647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int index() const { return static_cast<int>(value_) >> KindField::kSize; } 657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#define INSTRUCTION_OPERAND_PREDICATE(name, type, number) \ 667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool Is##name() const { return kind() == type; } 677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE) 687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0) 697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org INSTRUCTION_OPERAND_PREDICATE(Ignored, INVALID, 0) 707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#undef INSTRUCTION_OPERAND_PREDICATE 717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool Equals(InstructionOperand* other) const { 727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return value_ == other->value_; 737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void ConvertTo(Kind kind, int index) { 76e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org if (kind == REGISTER || kind == DOUBLE_REGISTER) DCHECK(index >= 0); 777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org value_ = KindField::encode(kind); 787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org value_ |= index << KindField::kSize; 79e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(this->index() == index); 807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Calls SetUpCache()/TearDownCache() for each subclass. 837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static void SetUpCaches(); 847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static void TearDownCaches(); 857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org protected: 877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org typedef BitField<Kind, 0, 3> KindField; 887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org unsigned value_; 907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 92fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgtypedef ZoneVector<InstructionOperand*> InstructionOperandVector; 93a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgOStream& operator<<(OStream& os, const InstructionOperand& op); 957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass UnallocatedOperand : public InstructionOperand { 977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org enum BasicPolicy { FIXED_SLOT, EXTENDED_POLICY }; 997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org enum ExtendedPolicy { 1017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org NONE, 1027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ANY, 1037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FIXED_REGISTER, 1047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FIXED_DOUBLE_REGISTER, 1057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org MUST_HAVE_REGISTER, 1067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org SAME_AS_FIRST_INPUT 1077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org }; 1087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Lifetime of operand inside the instruction. 1107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org enum Lifetime { 1117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // USED_AT_START operand is guaranteed to be live only at 1127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // instruction start. Register allocator is free to assign the same register 1137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // to some other operand used inside instruction (i.e. temporary or 1147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // output). 1157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org USED_AT_START, 1167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // USED_AT_END operand is treated as live until the end of 1187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // instruction. This means that register allocator will not reuse it's 1197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // register for any other operand inside instruction. 1207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org USED_AT_END 1217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org }; 1227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit UnallocatedOperand(ExtendedPolicy policy) 1247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : InstructionOperand(UNALLOCATED, 0) { 1257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org value_ |= BasicPolicyField::encode(EXTENDED_POLICY); 1267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org value_ |= ExtendedPolicyField::encode(policy); 1277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org value_ |= LifetimeField::encode(USED_AT_END); 1287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org UnallocatedOperand(BasicPolicy policy, int index) 1317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : InstructionOperand(UNALLOCATED, 0) { 132e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(policy == FIXED_SLOT); 1337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org value_ |= BasicPolicyField::encode(policy); 1347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org value_ |= index << FixedSlotIndexField::kShift; 135e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(this->fixed_slot_index() == index); 1367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org UnallocatedOperand(ExtendedPolicy policy, int index) 1397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : InstructionOperand(UNALLOCATED, 0) { 140e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(policy == FIXED_REGISTER || policy == FIXED_DOUBLE_REGISTER); 1417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org value_ |= BasicPolicyField::encode(EXTENDED_POLICY); 1427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org value_ |= ExtendedPolicyField::encode(policy); 1437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org value_ |= LifetimeField::encode(USED_AT_END); 1447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org value_ |= FixedRegisterField::encode(index); 1457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org UnallocatedOperand(ExtendedPolicy policy, Lifetime lifetime) 1487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : InstructionOperand(UNALLOCATED, 0) { 1497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org value_ |= BasicPolicyField::encode(EXTENDED_POLICY); 1507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org value_ |= ExtendedPolicyField::encode(policy); 1517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org value_ |= LifetimeField::encode(lifetime); 1527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org UnallocatedOperand* CopyUnconstrained(Zone* zone) { 1557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org UnallocatedOperand* result = new (zone) UnallocatedOperand(ANY); 1567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org result->set_virtual_register(virtual_register()); 1577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return result; 1587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static const UnallocatedOperand* cast(const InstructionOperand* op) { 161e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(op->IsUnallocated()); 1627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return static_cast<const UnallocatedOperand*>(op); 1637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static UnallocatedOperand* cast(InstructionOperand* op) { 166e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(op->IsUnallocated()); 1677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return static_cast<UnallocatedOperand*>(op); 1687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 1697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // The encoding used for UnallocatedOperand operands depends on the policy 1717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // that is 1727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // stored within the operand. The FIXED_SLOT policy uses a compact encoding 1737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // because it accommodates a larger pay-load. 1747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // 1757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // For FIXED_SLOT policy: 1767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // +------------------------------------------+ 1777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // | slot_index | vreg | 0 | 001 | 1787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // +------------------------------------------+ 1797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // 1807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // For all other (extended) policies: 1817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // +------------------------------------------+ 1827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // | reg_index | L | PPP | vreg | 1 | 001 | L ... Lifetime 1837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // +------------------------------------------+ P ... Policy 1847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // 1857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // The slot index is a signed value which requires us to decode it manually 1867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // instead of using the BitField utility class. 1877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // The superclass has a KindField. 1897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org STATIC_ASSERT(KindField::kSize == 3); 1907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // BitFields for all unallocated operands. 1927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org class BasicPolicyField : public BitField<BasicPolicy, 3, 1> {}; 1937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org class VirtualRegisterField : public BitField<unsigned, 4, 18> {}; 1947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // BitFields specific to BasicPolicy::FIXED_SLOT. 1967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org class FixedSlotIndexField : public BitField<int, 22, 10> {}; 1977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 1987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // BitFields specific to BasicPolicy::EXTENDED_POLICY. 1997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org class ExtendedPolicyField : public BitField<ExtendedPolicy, 22, 3> {}; 2007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org class LifetimeField : public BitField<Lifetime, 25, 1> {}; 2017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org class FixedRegisterField : public BitField<int, 26, 6> {}; 2027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static const int kMaxVirtualRegisters = VirtualRegisterField::kMax + 1; 2047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static const int kFixedSlotIndexWidth = FixedSlotIndexField::kSize; 2057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static const int kMaxFixedSlotIndex = (1 << (kFixedSlotIndexWidth - 1)) - 1; 2067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static const int kMinFixedSlotIndex = -(1 << (kFixedSlotIndexWidth - 1)); 2077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Predicates for the operand policy. 2097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool HasAnyPolicy() const { 2107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return basic_policy() == EXTENDED_POLICY && extended_policy() == ANY; 2117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool HasFixedPolicy() const { 2137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return basic_policy() == FIXED_SLOT || 2147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org extended_policy() == FIXED_REGISTER || 2157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org extended_policy() == FIXED_DOUBLE_REGISTER; 2167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool HasRegisterPolicy() const { 2187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return basic_policy() == EXTENDED_POLICY && 2197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org extended_policy() == MUST_HAVE_REGISTER; 2207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool HasSameAsInputPolicy() const { 2227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return basic_policy() == EXTENDED_POLICY && 2237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org extended_policy() == SAME_AS_FIRST_INPUT; 2247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool HasFixedSlotPolicy() const { return basic_policy() == FIXED_SLOT; } 2267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool HasFixedRegisterPolicy() const { 2277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return basic_policy() == EXTENDED_POLICY && 2287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org extended_policy() == FIXED_REGISTER; 2297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool HasFixedDoubleRegisterPolicy() const { 2317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return basic_policy() == EXTENDED_POLICY && 2327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org extended_policy() == FIXED_DOUBLE_REGISTER; 2337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // [basic_policy]: Distinguish between FIXED_SLOT and all other policies. 2367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org BasicPolicy basic_policy() const { return BasicPolicyField::decode(value_); } 2377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // [extended_policy]: Only for non-FIXED_SLOT. The finer-grained policy. 2397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ExtendedPolicy extended_policy() const { 240e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(basic_policy() == EXTENDED_POLICY); 2417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return ExtendedPolicyField::decode(value_); 2427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // [fixed_slot_index]: Only for FIXED_SLOT. 2457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int fixed_slot_index() const { 246e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(HasFixedSlotPolicy()); 2477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return static_cast<int>(value_) >> FixedSlotIndexField::kShift; 2487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // [fixed_register_index]: Only for FIXED_REGISTER or FIXED_DOUBLE_REGISTER. 2517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int fixed_register_index() const { 252e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(HasFixedRegisterPolicy() || HasFixedDoubleRegisterPolicy()); 2537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return FixedRegisterField::decode(value_); 2547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // [virtual_register]: The virtual register ID for this operand. 2577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int virtual_register() const { return VirtualRegisterField::decode(value_); } 2587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void set_virtual_register(unsigned id) { 2597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org value_ = VirtualRegisterField::update(value_, id); 2607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // [lifetime]: Only for non-FIXED_SLOT. 2637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool IsUsedAtStart() { 264e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(basic_policy() == EXTENDED_POLICY); 2657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return LifetimeField::decode(value_) == USED_AT_START; 2667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 2687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 270ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass MoveOperands FINAL { 2717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 2727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org MoveOperands(InstructionOperand* source, InstructionOperand* destination) 2737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : source_(source), destination_(destination) {} 2747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* source() const { return source_; } 2767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void set_source(InstructionOperand* operand) { source_ = operand; } 2777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* destination() const { return destination_; } 2797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void set_destination(InstructionOperand* operand) { destination_ = operand; } 2807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // The gap resolver marks moves as "in-progress" by clearing the 2827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // destination (but not the source). 2837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool IsPending() const { return destination_ == NULL && source_ != NULL; } 2847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // True if this move a move into the given destination operand. 2867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool Blocks(InstructionOperand* operand) const { 2877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return !IsEliminated() && source()->Equals(operand); 2887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // A move is redundant if it's been eliminated, if its source and 2917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // destination are the same, or if its destination is unneeded or constant. 2927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool IsRedundant() const { 2937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return IsEliminated() || source_->Equals(destination_) || IsIgnored() || 2947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org (destination_ != NULL && destination_->IsConstant()); 2957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 2967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 2977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool IsIgnored() const { 2987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return destination_ != NULL && destination_->IsIgnored(); 2997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // We clear both operands to indicate move that's been eliminated. 3027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void Eliminate() { source_ = destination_ = NULL; } 3037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool IsEliminated() const { 304e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(source_ != NULL || destination_ == NULL); 3057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return source_ == NULL; 3067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private: 3097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* source_; 3107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* destination_; 3117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 3127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgOStream& operator<<(OStream& os, const MoveOperands& mo); 3147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgtemplate <InstructionOperand::Kind kOperandKind, int kNumCachedOperands> 316ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass SubKindOperand FINAL : public InstructionOperand { 3177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 3187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static SubKindOperand* Create(int index, Zone* zone) { 319e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(index >= 0); 3207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (index < kNumCachedOperands) return &cache[index]; 3217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return new (zone) SubKindOperand(index); 3227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static SubKindOperand* cast(InstructionOperand* op) { 325e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(op->kind() == kOperandKind); 3267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return reinterpret_cast<SubKindOperand*>(op); 3277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static void SetUpCache(); 3307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static void TearDownCache(); 3317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private: 3337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static SubKindOperand* cache; 3347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org SubKindOperand() : InstructionOperand() {} 3367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit SubKindOperand(int index) 3377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : InstructionOperand(kOperandKind, index) {} 3387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 3397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#define INSTRUCTION_TYPEDEF_SUBKIND_OPERAND_CLASS(name, type, number) \ 3427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org typedef SubKindOperand<InstructionOperand::type, number> name##Operand; 3437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgINSTRUCTION_OPERAND_LIST(INSTRUCTION_TYPEDEF_SUBKIND_OPERAND_CLASS) 3447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#undef INSTRUCTION_TYPEDEF_SUBKIND_OPERAND_CLASS 3457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 347ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass ParallelMove FINAL : public ZoneObject { 3487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 3497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit ParallelMove(Zone* zone) : move_operands_(4, zone) {} 3507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void AddMove(InstructionOperand* from, InstructionOperand* to, Zone* zone) { 3527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org move_operands_.Add(MoveOperands(from, to), zone); 3537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool IsRedundant() const; 3567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ZoneList<MoveOperands>* move_operands() { return &move_operands_; } 3587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org const ZoneList<MoveOperands>* move_operands() const { 3597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return &move_operands_; 3607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private: 3637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ZoneList<MoveOperands> move_operands_; 3647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 3657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgOStream& operator<<(OStream& os, const ParallelMove& pm); 3677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 368ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass PointerMap FINAL : public ZoneObject { 3697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 3707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit PointerMap(Zone* zone) 3717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : pointer_operands_(8, zone), 3727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org untagged_operands_(0, zone), 3737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org instruction_position_(-1) {} 3747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org const ZoneList<InstructionOperand*>* GetNormalizedOperands() { 3767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org for (int i = 0; i < untagged_operands_.length(); ++i) { 3777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org RemovePointer(untagged_operands_[i]); 3787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org untagged_operands_.Clear(); 3807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return &pointer_operands_; 3817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int instruction_position() const { return instruction_position_; } 3837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void set_instruction_position(int pos) { 385e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instruction_position_ == -1); 3867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org instruction_position_ = pos; 3877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 3887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void RecordPointer(InstructionOperand* op, Zone* zone); 3907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void RemovePointer(InstructionOperand* op); 3917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void RecordUntagged(InstructionOperand* op, Zone* zone); 3927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private: 3947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org friend OStream& operator<<(OStream& os, const PointerMap& pm); 3957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 3967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ZoneList<InstructionOperand*> pointer_operands_; 3977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ZoneList<InstructionOperand*> untagged_operands_; 3987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int instruction_position_; 3997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 4007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgOStream& operator<<(OStream& os, const PointerMap& pm); 4027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// TODO(titzer): s/PointerMap/ReferenceMap/ 4047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass Instruction : public ZoneObject { 4057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 4067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org size_t OutputCount() const { return OutputCountField::decode(bit_field_); } 4077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* OutputAt(size_t i) const { 408e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(i < OutputCount()); 4097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return operands_[i]; 4107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4126474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org bool HasOutput() const { return OutputCount() == 1; } 4136474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org InstructionOperand* Output() const { return OutputAt(0); } 4146474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 4157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org size_t InputCount() const { return InputCountField::decode(bit_field_); } 4167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* InputAt(size_t i) const { 417e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(i < InputCount()); 4187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return operands_[OutputCount() + i]; 4197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org size_t TempCount() const { return TempCountField::decode(bit_field_); } 4227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* TempAt(size_t i) const { 423e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(i < TempCount()); 4247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return operands_[OutputCount() + InputCount() + i]; 4257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionCode opcode() const { return opcode_; } 4287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ArchOpcode arch_opcode() const { return ArchOpcodeField::decode(opcode()); } 4297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org AddressingMode addressing_mode() const { 4307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return AddressingModeField::decode(opcode()); 4317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FlagsMode flags_mode() const { return FlagsModeField::decode(opcode()); } 4337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FlagsCondition flags_condition() const { 4347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return FlagsConditionField::decode(opcode()); 4357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // TODO(titzer): make control and call into flags. 4387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static Instruction* New(Zone* zone, InstructionCode opcode) { 4397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return New(zone, opcode, 0, NULL, 0, NULL, 0, NULL); 4407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static Instruction* New(Zone* zone, InstructionCode opcode, 4437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org size_t output_count, InstructionOperand** outputs, 4447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org size_t input_count, InstructionOperand** inputs, 4457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org size_t temp_count, InstructionOperand** temps) { 446e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(opcode >= 0); 447e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(output_count == 0 || outputs != NULL); 448e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(input_count == 0 || inputs != NULL); 449e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(temp_count == 0 || temps != NULL); 4507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* none = NULL; 4517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org USE(none); 4527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int size = static_cast<int>(RoundUp(sizeof(Instruction), kPointerSize) + 4537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org (output_count + input_count + temp_count - 1) * 4547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org sizeof(none)); 4557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return new (zone->New(size)) Instruction( 4567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org opcode, output_count, outputs, input_count, inputs, temp_count, temps); 4577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // TODO(titzer): another holdover from lithium days; register allocator 4607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // should not need to know about control instructions. 4617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Instruction* MarkAsControl() { 4627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bit_field_ = IsControlField::update(bit_field_, true); 4637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return this; 4647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Instruction* MarkAsCall() { 4667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bit_field_ = IsCallField::update(bit_field_, true); 4677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return this; 4687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool IsControl() const { return IsControlField::decode(bit_field_); } 4707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool IsCall() const { return IsCallField::decode(bit_field_); } 4717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool NeedsPointerMap() const { return IsCall(); } 4727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool HasPointerMap() const { return pointer_map_ != NULL; } 4737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool IsGapMoves() const { 4757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return opcode() == kGapInstruction || opcode() == kBlockStartInstruction; 4767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool IsBlockStart() const { return opcode() == kBlockStartInstruction; } 4787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool IsSourcePosition() const { 4797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return opcode() == kSourcePositionInstruction; 4807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool ClobbersRegisters() const { return IsCall(); } 4837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool ClobbersTemps() const { return IsCall(); } 4847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool ClobbersDoubleRegisters() const { return IsCall(); } 4857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org PointerMap* pointer_map() const { return pointer_map_; } 4867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void set_pointer_map(PointerMap* map) { 488e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(NeedsPointerMap()); 489e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(NULL, pointer_map_); 4907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org pointer_map_ = map; 4917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 4927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Placement new operator so that we can smash instructions into 4947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // zone-allocated memory. 4957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void* operator new(size_t, void* location) { return location; } 4967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void operator delete(void* pointer, void* location) { UNREACHABLE(); } 4987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 4997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org protected: 5007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit Instruction(InstructionCode opcode) 5017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : opcode_(opcode), 5027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) | 5037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org TempCountField::encode(0) | IsCallField::encode(false) | 5047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org IsControlField::encode(false)), 5057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org pointer_map_(NULL) {} 5067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Instruction(InstructionCode opcode, size_t output_count, 5087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand** outputs, size_t input_count, 5097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand** inputs, size_t temp_count, 5107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand** temps) 5117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : opcode_(opcode), 5127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bit_field_(OutputCountField::encode(output_count) | 5137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InputCountField::encode(input_count) | 5147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org TempCountField::encode(temp_count) | 5157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org IsCallField::encode(false) | IsControlField::encode(false)), 5167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org pointer_map_(NULL) { 5177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org for (size_t i = 0; i < output_count; ++i) { 5187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org operands_[i] = outputs[i]; 5197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 5207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org for (size_t i = 0; i < input_count; ++i) { 5217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org operands_[output_count + i] = inputs[i]; 5227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 5237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org for (size_t i = 0; i < temp_count; ++i) { 5247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org operands_[output_count + input_count + i] = temps[i]; 5257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 5267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 5277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org protected: 5297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org typedef BitField<size_t, 0, 8> OutputCountField; 5307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org typedef BitField<size_t, 8, 16> InputCountField; 5317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org typedef BitField<size_t, 24, 6> TempCountField; 5327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org typedef BitField<bool, 30, 1> IsCallField; 5337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org typedef BitField<bool, 31, 1> IsControlField; 5347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionCode opcode_; 5367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org uint32_t bit_field_; 5377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org PointerMap* pointer_map_; 5387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionOperand* operands_[1]; 5397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 5407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgOStream& operator<<(OStream& os, const Instruction& instr); 5427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Represents moves inserted before an instruction due to register allocation. 5447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// TODO(titzer): squash GapInstruction back into Instruction, since essentially 5457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// every instruction can possibly have moves inserted before it. 5467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass GapInstruction : public Instruction { 5477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 5487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org enum InnerPosition { 5497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org BEFORE, 5507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org START, 5517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org END, 5527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org AFTER, 5537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org FIRST_INNER_POSITION = BEFORE, 5547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org LAST_INNER_POSITION = AFTER 5557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org }; 5567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ParallelMove* GetOrCreateParallelMove(InnerPosition pos, Zone* zone) { 5587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (parallel_moves_[pos] == NULL) { 5597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org parallel_moves_[pos] = new (zone) ParallelMove(zone); 5607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 5617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return parallel_moves_[pos]; 5627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 5637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ParallelMove* GetParallelMove(InnerPosition pos) { 5657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return parallel_moves_[pos]; 5667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 5677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static GapInstruction* New(Zone* zone) { 5697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void* buffer = zone->New(sizeof(GapInstruction)); 5707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return new (buffer) GapInstruction(kGapInstruction); 5717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 5727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static GapInstruction* cast(Instruction* instr) { 574e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->IsGapMoves()); 5757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return static_cast<GapInstruction*>(instr); 5767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 5777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static const GapInstruction* cast(const Instruction* instr) { 579e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->IsGapMoves()); 5807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return static_cast<const GapInstruction*>(instr); 5817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 5827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org protected: 5847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit GapInstruction(InstructionCode opcode) : Instruction(opcode) { 5857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org parallel_moves_[BEFORE] = NULL; 5867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org parallel_moves_[START] = NULL; 5877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org parallel_moves_[END] = NULL; 5887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org parallel_moves_[AFTER] = NULL; 5897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 5907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private: 5927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org friend OStream& operator<<(OStream& os, const Instruction& instr); 5937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ParallelMove* parallel_moves_[LAST_INNER_POSITION + 1]; 5947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 5957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 5977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// This special kind of gap move instruction represents the beginning of a 5987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// block of code. 5997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// TODO(titzer): move code_start and code_end from BasicBlock to here. 600ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass BlockStartInstruction FINAL : public GapInstruction { 6017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 6027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org BasicBlock* block() const { return block_; } 6037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Label* label() { return &label_; } 6047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static BlockStartInstruction* New(Zone* zone, BasicBlock* block) { 6067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void* buffer = zone->New(sizeof(BlockStartInstruction)); 6077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return new (buffer) BlockStartInstruction(block); 6087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 6097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static BlockStartInstruction* cast(Instruction* instr) { 611e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->IsBlockStart()); 6127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return static_cast<BlockStartInstruction*>(instr); 6137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 6147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private: 6167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit BlockStartInstruction(BasicBlock* block) 6177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : GapInstruction(kBlockStartInstruction), block_(block) {} 6187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org BasicBlock* block_; 6207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Label label_; 6217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 6227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 624ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass SourcePositionInstruction FINAL : public Instruction { 6257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 6267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static SourcePositionInstruction* New(Zone* zone, SourcePosition position) { 6277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void* buffer = zone->New(sizeof(SourcePositionInstruction)); 6287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return new (buffer) SourcePositionInstruction(position); 6297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 6307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org SourcePosition source_position() const { return source_position_; } 6327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static SourcePositionInstruction* cast(Instruction* instr) { 634e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->IsSourcePosition()); 6357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return static_cast<SourcePositionInstruction*>(instr); 6367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 6377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org static const SourcePositionInstruction* cast(const Instruction* instr) { 639e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(instr->IsSourcePosition()); 6407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return static_cast<const SourcePositionInstruction*>(instr); 6417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 6427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private: 6447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit SourcePositionInstruction(SourcePosition source_position) 6457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : Instruction(kSourcePositionInstruction), 6467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org source_position_(source_position) { 647e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!source_position_.IsInvalid()); 648e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!source_position_.IsUnknown()); 6497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 6507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org SourcePosition source_position_; 6527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 6537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 655ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass Constant FINAL { 6567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 6577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org enum Type { kInt32, kInt64, kFloat64, kExternalReference, kHeapObject }; 6587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit Constant(int32_t v) : type_(kInt32), value_(v) {} 6607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit Constant(int64_t v) : type_(kInt64), value_(v) {} 661e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org explicit Constant(double v) : type_(kFloat64), value_(bit_cast<int64_t>(v)) {} 6627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit Constant(ExternalReference ref) 663e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org : type_(kExternalReference), value_(bit_cast<intptr_t>(ref)) {} 6647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org explicit Constant(Handle<HeapObject> obj) 665e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org : type_(kHeapObject), value_(bit_cast<intptr_t>(obj)) {} 6667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Type type() const { return type_; } 6687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int32_t ToInt32() const { 670e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(kInt32, type()); 6717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return static_cast<int32_t>(value_); 6727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 6737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int64_t ToInt64() const { 6757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (type() == kInt32) return ToInt32(); 676e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(kInt64, type()); 6777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return value_; 6787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 6797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org double ToFloat64() const { 6817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org if (type() == kInt32) return ToInt32(); 682e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(kFloat64, type()); 683e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org return bit_cast<double>(value_); 6847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 6857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ExternalReference ToExternalReference() const { 687e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(kExternalReference, type()); 688e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org return bit_cast<ExternalReference>(static_cast<intptr_t>(value_)); 6897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 6907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Handle<HeapObject> ToHeapObject() const { 692e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(kHeapObject, type()); 693e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org return bit_cast<Handle<HeapObject> >(static_cast<intptr_t>(value_)); 6947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 6957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 6967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private: 6977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Type type_; 6987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int64_t value_; 6997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 7007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7019d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 7029d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgclass FrameStateDescriptor : public ZoneObject { 7039d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org public: 704ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org FrameStateDescriptor(const FrameStateCallInfo& state_info, 705a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org size_t parameters_count, size_t locals_count, 706a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org size_t stack_count, 7079aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org FrameStateDescriptor* outer_state = NULL) 708a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org : type_(state_info.type()), 709a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org bailout_id_(state_info.bailout_id()), 710ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org frame_state_combine_(state_info.state_combine()), 7119d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org parameters_count_(parameters_count), 7129d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org locals_count_(locals_count), 7139aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org stack_count_(stack_count), 714a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org outer_state_(outer_state), 715a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org jsfunction_(state_info.jsfunction()) {} 7169d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 717a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org FrameStateType type() const { return type_; } 7189d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org BailoutId bailout_id() const { return bailout_id_; } 719ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org OutputFrameStateCombine state_combine() const { return frame_state_combine_; } 720a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org size_t parameters_count() const { return parameters_count_; } 721a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org size_t locals_count() const { return locals_count_; } 722a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org size_t stack_count() const { return stack_count_; } 723a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org FrameStateDescriptor* outer_state() const { return outer_state_; } 724a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org MaybeHandle<JSFunction> jsfunction() const { return jsfunction_; } 7259d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 726a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org size_t size() const { 727ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org return parameters_count_ + locals_count_ + stack_count_ + 728a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org (HasContext() ? 1 : 0); 729ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org } 7309d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 731a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org size_t GetTotalSize() const { 732a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org size_t total_size = 0; 733a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org for (const FrameStateDescriptor* iter = this; iter != NULL; 7349aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org iter = iter->outer_state_) { 7359aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org total_size += iter->size(); 7369aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 7379aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org return total_size; 7389aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 7399aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 740a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org size_t GetHeight(OutputFrameStateCombine override) const { 741a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org size_t height = size() - parameters_count(); 742a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org switch (override) { 743a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org case kPushOutput: 744a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org ++height; 745a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org break; 746a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org case kIgnoreOutput: 747a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org break; 748a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org } 749a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org return height; 750a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org } 751a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 752a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org size_t GetFrameCount() const { 753a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org size_t count = 0; 754a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org for (const FrameStateDescriptor* iter = this; iter != NULL; 7559aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org iter = iter->outer_state_) { 7569aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org ++count; 7579aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 7589aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org return count; 7599aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 7609aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 761a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org size_t GetJSFrameCount() const { 762a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org size_t count = 0; 763a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org for (const FrameStateDescriptor* iter = this; iter != NULL; 764a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org iter = iter->outer_state_) { 765a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org if (iter->type_ == JS_FRAME) { 766a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org ++count; 767a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org } 768a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org } 769a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org return count; 770a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org } 771a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 772a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org bool HasContext() const { return type_ == JS_FRAME; } 773a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 7749d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org private: 775a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org FrameStateType type_; 7769d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org BailoutId bailout_id_; 777ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org OutputFrameStateCombine frame_state_combine_; 778a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org size_t parameters_count_; 779a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org size_t locals_count_; 780a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org size_t stack_count_; 7819aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org FrameStateDescriptor* outer_state_; 782a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org MaybeHandle<JSFunction> jsfunction_; 7839d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org}; 7849d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org 7857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgOStream& operator<<(OStream& os, const Constant& constant); 7867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 787fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgtypedef ZoneDeque<Constant> ConstantDeque; 7887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgtypedef std::map<int, Constant, std::less<int>, 7897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org zone_allocator<std::pair<int, Constant> > > ConstantMap; 7907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 791fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgtypedef ZoneDeque<Instruction*> InstructionDeque; 792fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgtypedef ZoneDeque<PointerMap*> PointerMapDeque; 793fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgtypedef ZoneVector<FrameStateDescriptor*> DeoptimizationVector; 7947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 7957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Represents architecture-specific generated code before, during, and after 7967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// register allocation. 7977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// TODO(titzer): s/IsDouble/IsFloat64/ 798ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass InstructionSequence FINAL { 7997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public: 8007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionSequence(Linkage* linkage, Graph* graph, Schedule* schedule) 8017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org : graph_(graph), 8027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org linkage_(linkage), 8037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org schedule_(schedule), 8047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org constants_(ConstantMap::key_compare(), 8057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ConstantMap::allocator_type(zone())), 806fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org immediates_(zone()), 807fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org instructions_(zone()), 8087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org next_virtual_register_(graph->NodeCount()), 809fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org pointer_maps_(zone()), 8107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org doubles_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), 8117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org references_(std::less<int>(), 8127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org VirtualRegisterSet::allocator_type(zone())), 813fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org deoptimization_entries_(zone()) {} 8147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int NextVirtualRegister() { return next_virtual_register_++; } 8167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int VirtualRegisterCount() const { return next_virtual_register_; } 8177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int ValueCount() const { return graph_->NodeCount(); } 8197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int BasicBlockCount() const { 8217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return static_cast<int>(schedule_->rpo_order()->size()); 8227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org BasicBlock* BlockAt(int rpo_number) const { 8257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return (*schedule_->rpo_order())[rpo_number]; 8267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org BasicBlock* GetContainingLoop(BasicBlock* block) { 8297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return block->loop_header_; 8307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int GetLoopEnd(BasicBlock* block) const { return block->loop_end_; } 8337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org BasicBlock* GetBasicBlock(int instruction_index); 8357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int GetVirtualRegister(Node* node) const { return node->id(); } 8377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool IsReference(int virtual_register) const; 8397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool IsDouble(int virtual_register) const; 8407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void MarkAsReference(int virtual_register); 8427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void MarkAsDouble(int virtual_register); 8437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void AddGapMove(int index, InstructionOperand* from, InstructionOperand* to); 8457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Label* GetLabel(BasicBlock* block); 8477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org BlockStartInstruction* GetBlockStart(BasicBlock* block); 8487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org typedef InstructionDeque::const_iterator const_iterator; 8507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org const_iterator begin() const { return instructions_.begin(); } 8517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org const_iterator end() const { return instructions_.end(); } 8527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org GapInstruction* GapAt(int index) const { 8547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return GapInstruction::cast(InstructionAt(index)); 8557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org bool IsGapAt(int index) const { return InstructionAt(index)->IsGapMoves(); } 8577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Instruction* InstructionAt(int index) const { 858e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(index >= 0); 859e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(index < static_cast<int>(instructions_.size())); 8607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return instructions_[index]; 8617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Frame* frame() { return &frame_; } 8647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Graph* graph() const { return graph_; } 8657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Isolate* isolate() const { return zone()->isolate(); } 8667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Linkage* linkage() const { return linkage_; } 8677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Schedule* schedule() const { return schedule_; } 8687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org const PointerMapDeque* pointer_maps() const { return &pointer_maps_; } 8697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Zone* zone() const { return graph_->zone(); } 8707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org // Used by the code generator while adding instructions. 8727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int AddInstruction(Instruction* instr, BasicBlock* block); 8737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void StartBlock(BasicBlock* block); 8747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void EndBlock(BasicBlock* block); 8757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org void AddConstant(int virtual_register, Constant constant) { 877e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(constants_.find(virtual_register) == constants_.end()); 8787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org constants_.insert(std::make_pair(virtual_register, constant)); 8797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Constant GetConstant(int virtual_register) const { 8817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ConstantMap::const_iterator it = constants_.find(virtual_register); 882e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(it != constants_.end()); 883e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(virtual_register, it->first); 8847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return it->second; 8857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org typedef ConstantDeque Immediates; 8887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org const Immediates& immediates() const { return immediates_; } 8897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 8907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int AddImmediate(Constant constant) { 8917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int index = static_cast<int>(immediates_.size()); 8927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org immediates_.push_back(constant); 8937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return index; 8947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 8957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Constant GetImmediate(int index) const { 896e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(index >= 0); 897e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(index < static_cast<int>(immediates_.size())); 8987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org return immediates_[index]; 8997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org } 9007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 901ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org class StateId { 902ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org public: 903ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org static StateId FromInt(int id) { return StateId(id); } 904ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org int ToInt() const { return id_; } 905ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org 906ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org private: 907ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org explicit StateId(int id) : id_(id) {} 908ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org int id_; 909ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org }; 910ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org 911ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org StateId AddFrameStateDescriptor(FrameStateDescriptor* descriptor); 912ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org FrameStateDescriptor* GetFrameStateDescriptor(StateId deoptimization_id); 913ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org int GetFrameStateDescriptorCount(); 9147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 9157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org private: 9167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org friend OStream& operator<<(OStream& os, const InstructionSequence& code); 9177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 9187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org typedef std::set<int, std::less<int>, ZoneIntAllocator> VirtualRegisterSet; 9197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 9207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Graph* graph_; 9217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Linkage* linkage_; 9227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Schedule* schedule_; 9237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ConstantMap constants_; 9247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org ConstantDeque immediates_; 9257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org InstructionDeque instructions_; 9267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org int next_virtual_register_; 9277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org PointerMapDeque pointer_maps_; 9287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org VirtualRegisterSet doubles_; 9297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org VirtualRegisterSet references_; 9307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org Frame frame_; 9317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org DeoptimizationVector deoptimization_entries_; 9327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}; 9337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 9347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgOStream& operator<<(OStream& os, const InstructionSequence& code); 9357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 9367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} // namespace compiler 9377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} // namespace internal 9387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org} // namespace v8 9397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org 9407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif // V8_COMPILER_INSTRUCTION_H_ 941