162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Copyright 2016 the V8 project authors. All rights reserved. 262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// found in the LICENSE file. 462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#ifndef V8_COMPILER_GRAPH_ASSEMBLER_H_ 662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define V8_COMPILER_GRAPH_ASSEMBLER_H_ 762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/compiler/js-graph.h" 962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/compiler/node.h" 1062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/compiler/simplified-operator.h" 1162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 1262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochnamespace v8 { 1362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochnamespace internal { 1462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 1562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochclass JSGraph; 1662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochclass Graph; 1762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 1862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochnamespace compiler { 1962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 2062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define PURE_ASSEMBLER_MACH_UNOP_LIST(V) \ 2162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(ChangeInt32ToInt64) \ 2262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(ChangeInt32ToFloat64) \ 2362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(ChangeUint32ToFloat64) \ 2462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(ChangeUint32ToUint64) \ 2562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(ChangeFloat64ToInt32) \ 2662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(ChangeFloat64ToUint32) \ 2762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(TruncateInt64ToInt32) \ 2862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(RoundFloat64ToInt32) \ 2962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(TruncateFloat64ToWord32) \ 3062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float64ExtractHighWord32) \ 3162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float64Abs) \ 3262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(BitcastWordToTagged) 3362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 3462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define PURE_ASSEMBLER_MACH_BINOP_LIST(V) \ 3562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(WordShl) \ 3662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(WordSar) \ 3762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(WordAnd) \ 3862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Word32Or) \ 3962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Word32And) \ 4062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Word32Shr) \ 4162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Word32Shl) \ 4262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(IntAdd) \ 4362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(IntSub) \ 4462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(UintLessThan) \ 4562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Int32Add) \ 4662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Int32Sub) \ 4762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Int32Mul) \ 4862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Int32LessThanOrEqual) \ 4962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Uint32LessThanOrEqual) \ 5062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Uint32LessThan) \ 5162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Int32LessThan) \ 5262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float64Add) \ 5362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float64Sub) \ 5462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float64Mod) \ 5562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float64Equal) \ 5662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float64LessThan) \ 5762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Float64LessThanOrEqual) \ 5862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Word32Equal) \ 5962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(WordEqual) 6062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 6162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define CHECKED_ASSEMBLER_MACH_BINOP_LIST(V) \ 6262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Int32AddWithOverflow) \ 6362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Int32SubWithOverflow) \ 6462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Int32MulWithOverflow) \ 6562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Int32Mod) \ 6662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Int32Div) \ 6762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Uint32Mod) \ 6862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(Uint32Div) 6962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 7062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define JSGRAPH_SINGLETON_CONSTANT_LIST(V) \ 7162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(TrueConstant) \ 7262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(FalseConstant) \ 7362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(HeapNumberMapConstant) \ 7462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(NoContextConstant) \ 7562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(EmptyStringConstant) \ 7662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(UndefinedConstant) \ 7762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(TheHoleConstant) \ 7862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(FixedArrayMapConstant) \ 7962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(ToNumberBuiltinConstant) \ 8062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(AllocateInNewSpaceStubConstant) \ 8162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V(AllocateInOldSpaceStubConstant) 8262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 8362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochclass GraphAssembler; 8462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 8562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochenum class GraphAssemblerLabelType { kDeferred, kNonDeferred }; 8662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 8762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Label with statically known count of incoming branches and phis. 8862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate <size_t MergeCount, size_t VarCount = 0u> 8962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochclass GraphAssemblerStaticLabel { 9062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch public: 9162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* PhiAt(size_t index); 9262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 9362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch template <typename... Reps> 9462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch explicit GraphAssemblerStaticLabel(GraphAssemblerLabelType is_deferred, 9562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Reps... reps) 9662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : is_deferred_(is_deferred == GraphAssemblerLabelType::kDeferred) { 9762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch STATIC_ASSERT(VarCount == sizeof...(reps)); 9862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MachineRepresentation reps_array[] = {MachineRepresentation::kNone, 9962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch reps...}; 10062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch for (size_t i = 0; i < VarCount; i++) { 10162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch representations_[i] = reps_array[i + 1]; 10262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 10362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 10462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 10562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ~GraphAssemblerStaticLabel() { DCHECK(IsBound() || MergedCount() == 0); } 10662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 10762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch private: 10862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch friend class GraphAssembler; 10962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 11062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void SetBound() { 11162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(!IsBound()); 11262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(merged_count_, MergeCount); 11362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch is_bound_ = true; 11462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 11562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool IsBound() const { return is_bound_; } 11662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 11762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t PhiCount() const { return VarCount; } 11862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t MaxMergeCount() const { return MergeCount; } 11962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t MergedCount() const { return merged_count_; } 12062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool IsDeferred() const { return is_deferred_; } 12162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 12262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // For each phi, the buffer must have at least MaxMergeCount() + 1 12362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // node entries. 12462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node** GetBindingsPtrFor(size_t phi_index) { 12562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_LT(phi_index, PhiCount()); 12662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return &bindings_[phi_index * (MergeCount + 1)]; 12762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 12862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void SetBinding(size_t phi_index, size_t merge_index, Node* binding) { 12962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_LT(phi_index, PhiCount()); 13062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_LT(merge_index, MergeCount); 13162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bindings_[phi_index * (MergeCount + 1) + merge_index] = binding; 13262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 13362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MachineRepresentation GetRepresentationFor(size_t phi_index) { 13462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_LT(phi_index, PhiCount()); 13562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return representations_[phi_index]; 13662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 13762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // The controls buffer must have at least MaxMergeCount() entries. 13862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node** GetControlsPtr() { return controls_; } 13962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // The effects buffer must have at least MaxMergeCount() + 1 entries. 14062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node** GetEffectsPtr() { return effects_; } 14162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void IncrementMergedCount() { merged_count_++; } 14262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 14362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool is_bound_ = false; 14462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool is_deferred_; 14562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t merged_count_ = 0; 14662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* effects_[MergeCount + 1]; // Extra element for control edge, 14762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // so that we can use the array to 14862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // construct EffectPhi. 14962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* controls_[MergeCount]; 15062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* bindings_[(MergeCount + 1) * VarCount + 1]; 15162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MachineRepresentation representations_[VarCount + 1]; 15262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}; 15362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 15462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// General label (with zone allocated buffers for incoming branches and phi 15562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// inputs). 15662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochclass GraphAssemblerLabel { 15762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch public: 15862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* PhiAt(size_t index); 15962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 16062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GraphAssemblerLabel(GraphAssemblerLabelType is_deferred, size_t merge_count, 16162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t var_count, MachineRepresentation* representations, 16262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Zone* zone); 16362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 16462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ~GraphAssemblerLabel(); 16562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 16662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch private: 16762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch friend class GraphAssembler; 16862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 16962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void SetBound() { 17062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(!is_bound_); 17162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch is_bound_ = true; 17262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 17362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool IsBound() const { return is_bound_; } 17462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t PhiCount() const { return var_count_; } 17562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t MaxMergeCount() const { return max_merge_count_; } 17662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t MergedCount() const { return merged_count_; } 17762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool IsDeferred() const { return is_deferred_; } 17862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 17962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // For each phi, the buffer must have at least MaxMergeCount() + 1 18062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // node entries. 18162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node** GetBindingsPtrFor(size_t phi_index); 18262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void SetBinding(size_t phi_index, size_t merge_index, Node* binding); 18362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MachineRepresentation GetRepresentationFor(size_t phi_index); 18462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // The controls buffer must have at least MaxMergeCount() entries. 18562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node** GetControlsPtr(); 18662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // The effects buffer must have at least MaxMergeCount() + 1 entries. 18762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node** GetEffectsPtr(); 18862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void IncrementMergedCount() { merged_count_++; } 18962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 19062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool is_bound_ = false; 19162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool is_deferred_; 19262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t merged_count_ = 0; 19362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t max_merge_count_; 19462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t var_count_; 19562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node** effects_ = nullptr; 19662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node** controls_ = nullptr; 19762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node** bindings_ = nullptr; 19862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MachineRepresentation* representations_ = nullptr; 19962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}; 20062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 20162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochclass GraphAssembler { 20262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch public: 20362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GraphAssembler(JSGraph* jsgraph, Node* effect, Node* control, Zone* zone); 20462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 20562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void Reset(Node* effect, Node* control); 20662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 20762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Create non-deferred label with statically known number of incoming 20862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // gotos/branches. 20962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch template <size_t MergeCount, typename... Reps> 21062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static GraphAssemblerStaticLabel<MergeCount, sizeof...(Reps)> MakeLabel( 21162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Reps... reps) { 21262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return GraphAssemblerStaticLabel<MergeCount, sizeof...(Reps)>( 21362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GraphAssemblerLabelType::kNonDeferred, reps...); 21462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 21562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 21662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Create deferred label with statically known number of incoming 21762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // gotos/branches. 21862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch template <size_t MergeCount, typename... Reps> 21962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static GraphAssemblerStaticLabel<MergeCount, sizeof...(Reps)> 22062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MakeDeferredLabel(Reps... reps) { 22162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return GraphAssemblerStaticLabel<MergeCount, sizeof...(Reps)>( 22262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GraphAssemblerLabelType::kDeferred, reps...); 22362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 22462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 22562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Create label with number of incoming branches supplied at runtime. 22662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch template <typename... Reps> 22762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GraphAssemblerLabel MakeLabelFor(GraphAssemblerLabelType is_deferred, 22862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t merge_count, Reps... reps) { 22962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MachineRepresentation reps_array[] = {MachineRepresentation::kNone, 23062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch reps...}; 23162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return GraphAssemblerLabel(is_deferred, merge_count, sizeof...(reps), 23262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch &(reps_array[1]), temp_zone()); 23362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 23462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 23562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Value creation. 23662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* IntPtrConstant(intptr_t value); 23762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* Uint32Constant(int32_t value); 23862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* Int32Constant(int32_t value); 23962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* UniqueInt32Constant(int32_t value); 24062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* SmiConstant(int32_t value); 24162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* Float64Constant(double value); 24262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* Projection(int index, Node* value); 24362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* HeapConstant(Handle<HeapObject> object); 24462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* CEntryStubConstant(int result_size); 24562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* ExternalConstant(ExternalReference ref); 24662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 24762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define SINGLETON_CONST_DECL(Name) Node* Name(); 24862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSGRAPH_SINGLETON_CONSTANT_LIST(SINGLETON_CONST_DECL) 24962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#undef SINGLETON_CONST_DECL 25062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 25162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define PURE_UNOP_DECL(Name) Node* Name(Node* input); 25262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PURE_ASSEMBLER_MACH_UNOP_LIST(PURE_UNOP_DECL) 25362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#undef PURE_UNOP_DECL 25462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 25562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define BINOP_DECL(Name) Node* Name(Node* left, Node* right); 25662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PURE_ASSEMBLER_MACH_BINOP_LIST(BINOP_DECL) 25762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CHECKED_ASSEMBLER_MACH_BINOP_LIST(BINOP_DECL) 25862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#undef BINOP_DECL 25962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 26062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* Float64RoundDown(Node* value); 26162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 26262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* ToNumber(Node* value); 26362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* Allocate(PretenureFlag pretenure, Node* size); 26462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* LoadField(FieldAccess const&, Node* object); 26562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* LoadElement(ElementAccess const&, Node* object, Node* index); 26662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* StoreField(FieldAccess const&, Node* object, Node* value); 26762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* StoreElement(ElementAccess const&, Node* object, Node* index, 26862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* value); 26962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 27062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* Store(StoreRepresentation rep, Node* object, Node* offset, Node* value); 27162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* Load(MachineType rep, Node* object, Node* offset); 27262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 27362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* Retain(Node* buffer); 27462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* UnsafePointerAdd(Node* base, Node* external); 27562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 27662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* DeoptimizeIf(DeoptimizeReason reason, Node* condition, 27762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* frame_state); 27862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* DeoptimizeUnless(DeoptimizeKind kind, DeoptimizeReason reason, 27962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* condition, Node* frame_state); 28062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* DeoptimizeUnless(DeoptimizeReason reason, Node* condition, 28162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* frame_state); 28262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch template <typename... Args> 28362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* Call(const CallDescriptor* desc, Args... args); 28462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch template <typename... Args> 28562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* Call(const Operator* op, Args... args); 28662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 28762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Basic control operations. 28862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch template <class LabelType> 28962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void Bind(LabelType* label); 29062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 29162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch template <class LabelType, typename... vars> 29262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void Goto(LabelType* label, vars...); 29362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 29462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void Branch(Node* condition, GraphAssemblerStaticLabel<1>* if_true, 29562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch GraphAssemblerStaticLabel<1>* if_false); 29662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 29762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Control helpers. 29862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // {GotoIf(c, l)} is equivalent to {Branch(c, l, templ);Bind(templ)}. 29962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch template <class LabelType, typename... vars> 30062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void GotoIf(Node* condition, LabelType* label, vars...); 30162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 30262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // {GotoUnless(c, l)} is equivalent to {Branch(c, templ, l);Bind(templ)}. 30362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch template <class LabelType, typename... vars> 30462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void GotoUnless(Node* condition, LabelType* label, vars...); 30562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 30662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Extractors (should be only used when destructing/resetting the assembler). 30762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* ExtractCurrentControl(); 30862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* ExtractCurrentEffect(); 30962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 31062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch private: 31162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch template <class LabelType, typename... Vars> 31262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch void MergeState(LabelType label, Vars... vars); 31362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 31462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Operator const* ToNumberOperator(); 31562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 31662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSGraph* jsgraph() const { return jsgraph_; } 31762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Graph* graph() const { return jsgraph_->graph(); } 31862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Zone* temp_zone() const { return temp_zone_; } 31962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CommonOperatorBuilder* common() const { return jsgraph()->common(); } 32062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MachineOperatorBuilder* machine() const { return jsgraph()->machine(); } 32162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch SimplifiedOperatorBuilder* simplified() const { 32262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return jsgraph()->simplified(); 32362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 32462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 32562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch SetOncePointer<Operator const> to_number_operator_; 32662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Zone* temp_zone_; 32762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSGraph* jsgraph_; 32862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* current_effect_; 32962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* current_control_; 33062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}; 33162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 33262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate <size_t MergeCount, size_t VarCount> 33362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* GraphAssemblerStaticLabel<MergeCount, VarCount>::PhiAt(size_t index) { 33462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(IsBound()); 33562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return GetBindingsPtrFor(index)[0]; 33662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 33762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 33862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate <class LabelType, typename... Vars> 33962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid GraphAssembler::MergeState(LabelType label, Vars... vars) { 34062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(!label->IsBound()); 34162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch size_t merged_count = label->MergedCount(); 34262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_LT(merged_count, label->MaxMergeCount()); 34362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(label->PhiCount(), sizeof...(vars)); 34462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch label->GetEffectsPtr()[merged_count] = current_effect_; 34562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch label->GetControlsPtr()[merged_count] = current_control_; 34662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // We need to start with nullptr to avoid 0-length arrays. 34762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* var_array[] = {nullptr, vars...}; 34862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch for (size_t i = 0; i < sizeof...(vars); i++) { 34962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch label->SetBinding(i, merged_count, var_array[i + 1]); 35062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 35162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch label->IncrementMergedCount(); 35262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 35362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 35462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate <class LabelType> 35562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid GraphAssembler::Bind(LabelType* label) { 35662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(current_control_ == nullptr); 35762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(current_effect_ == nullptr); 35862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(label->MaxMergeCount() > 0); 35962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(label->MaxMergeCount(), label->MergedCount()); 36062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 36162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int merge_count = static_cast<int>(label->MaxMergeCount()); 36262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (merge_count == 1) { 36362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch current_control_ = label->GetControlsPtr()[0]; 36462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch current_effect_ = label->GetEffectsPtr()[0]; 36562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch label->SetBound(); 36662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return; 36762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 36862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 36962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch current_control_ = graph()->NewNode(common()->Merge(merge_count), merge_count, 37062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch label->GetControlsPtr()); 37162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 37262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node** effects = label->GetEffectsPtr(); 37362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch current_effect_ = effects[0]; 37462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch for (size_t i = 1; i < label->MaxMergeCount(); i++) { 37562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (current_effect_ != effects[i]) { 37662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch effects[label->MaxMergeCount()] = current_control_; 37762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch current_effect_ = graph()->NewNode(common()->EffectPhi(merge_count), 37862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch merge_count + 1, effects); 37962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch break; 38062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 38162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 38262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 38362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch for (size_t var = 0; var < label->PhiCount(); var++) { 38462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node** bindings = label->GetBindingsPtrFor(var); 38562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bindings[label->MaxMergeCount()] = current_control_; 38662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bindings[0] = graph()->NewNode( 38762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch common()->Phi(label->GetRepresentationFor(var), merge_count), 38862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch merge_count + 1, bindings); 38962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 39062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 39162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch label->SetBound(); 39262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 39362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 39462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate <class LabelType, typename... Vars> 39562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid GraphAssembler::Goto(LabelType* label, Vars... vars) { 39662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_NOT_NULL(current_control_); 39762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_NOT_NULL(current_effect_); 39862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MergeState(label, vars...); 39962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch current_control_ = nullptr; 40062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch current_effect_ = nullptr; 40162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 40262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 40362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate <class LabelType, typename... Vars> 40462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid GraphAssembler::GotoIf(Node* condition, LabelType* label, Vars... vars) { 40562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch BranchHint hint = 40662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch label->IsDeferred() ? BranchHint::kFalse : BranchHint::kNone; 40762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* branch = 40862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch graph()->NewNode(common()->Branch(hint), condition, current_control_); 40962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 41062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch current_control_ = graph()->NewNode(common()->IfTrue(), branch); 41162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MergeState(label, vars...); 41262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 41362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch current_control_ = graph()->NewNode(common()->IfFalse(), branch); 41462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 41562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 41662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate <class LabelType, typename... Vars> 41762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid GraphAssembler::GotoUnless(Node* condition, LabelType* label, 41862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Vars... vars) { 41962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch BranchHint hint = label->IsDeferred() ? BranchHint::kTrue : BranchHint::kNone; 42062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* branch = 42162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch graph()->NewNode(common()->Branch(hint), condition, current_control_); 42262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 42362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch current_control_ = graph()->NewNode(common()->IfFalse(), branch); 42462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MergeState(label, vars...); 42562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 42662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch current_control_ = graph()->NewNode(common()->IfTrue(), branch); 42762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 42862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 42962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate <typename... Args> 43062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* GraphAssembler::Call(const CallDescriptor* desc, Args... args) { 43162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const Operator* op = common()->Call(desc); 43262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Call(op, args...); 43362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 43462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 43562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate <typename... Args> 43662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochNode* GraphAssembler::Call(const Operator* op, Args... args) { 43762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(IrOpcode::kCall, op->opcode()); 43862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* args_array[] = {args..., current_effect_, current_control_}; 43962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int size = static_cast<int>(sizeof...(args)) + op->EffectInputCount() + 44062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch op->ControlInputCount(); 44162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* call = graph()->NewNode(op, size, args_array); 44262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(0, op->ControlOutputCount()); 44362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch current_effect_ = call; 44462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return call; 44562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 44662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 44762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} // namespace compiler 44862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} // namespace internal 44962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} // namespace v8 45062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 45162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#endif // V8_COMPILER_GRAPH_ASSEMBLER_H_ 452