Commit 858602d8 authored by Leszek Swirski's avatar Leszek Swirski Committed by V8 LUCI CQ

[turbofan] Add dynamic sized GraphAssemblerLabels

The GraphAssemblerLabel VarCount template parameter now can have a
marker value ~0 which is marker for it being dynamic sized -- this means
that a bit of template magic turns its std::arrays into std::vectors.
Merging GraphAssemblerLabels works by duck-typing access to these
arrays/vectors.

These dynamic GraphAssemblerLabels are created whenever a single

GraphAssemblerLabels being created when instead a list of values
convertible to MachineRepresentation is passed in. Passing anything else
will result in a GraphAssemblerLabel with marker value ~1, which is
considered "invalid" and will give a compilation error down the line.

std: :vector is passed into MakeLabel, with the static
Change-Id: I833bdedac2f8e26fcc88aa59dd67b7e4b1c4296d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3913349
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83424}
parent a3485e7c
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
#ifndef V8_COMPILER_GRAPH_ASSEMBLER_H_ #ifndef V8_COMPILER_GRAPH_ASSEMBLER_H_
#define V8_COMPILER_GRAPH_ASSEMBLER_H_ #define V8_COMPILER_GRAPH_ASSEMBLER_H_
#include <type_traits>
#include "src/base/small-vector.h"
#include "src/codegen/tnode.h" #include "src/codegen/tnode.h"
#include "src/compiler/feedback-source.h" #include "src/compiler/feedback-source.h"
#include "src/compiler/js-graph.h" #include "src/compiler/js-graph.h"
...@@ -150,10 +153,44 @@ class GraphAssembler; ...@@ -150,10 +153,44 @@ class GraphAssembler;
enum class GraphAssemblerLabelType { kDeferred, kNonDeferred, kLoop }; enum class GraphAssemblerLabelType { kDeferred, kNonDeferred, kLoop };
namespace detail {
constexpr size_t kGraphAssemblerLabelDynamicCount = ~0u;
template <size_t VarCount>
struct GraphAssemblerHelper {
template <typename T>
using Array = std::array<T, VarCount>;
static constexpr bool kIsDynamic = false;
static Array<Node*> InitNodeArray(const Array<MachineRepresentation>& reps) {
return {};
}
};
template <>
struct GraphAssemblerHelper<kGraphAssemblerLabelDynamicCount> {
// TODO(leszeks): We could allow other sizes of small vector here, by encoding
// the size in the negative VarCount.
template <typename T>
using Array = base::SmallVector<T, 4>;
static constexpr bool kIsDynamic = true;
static Array<Node*> InitNodeArray(const Array<MachineRepresentation>& reps) {
return Array<Node*>(reps.size());
}
};
} // namespace detail
// Label with statically known count of incoming branches and phis. // Label with statically known count of incoming branches and phis.
template <size_t VarCount> template <size_t VarCount>
class GraphAssemblerLabel { class GraphAssemblerLabel {
using Helper = detail::GraphAssemblerHelper<VarCount>;
template <typename T>
using Array = typename Helper::template Array<T>;
static constexpr bool kIsDynamic = Helper::kIsDynamic;
public: public:
size_t Count() { return representations_.size(); }
Node* PhiAt(size_t index); Node* PhiAt(size_t index);
template <typename T> template <typename T>
...@@ -166,10 +203,11 @@ class GraphAssemblerLabel { ...@@ -166,10 +203,11 @@ class GraphAssemblerLabel {
bool IsUsed() const { return merged_count_ > 0; } bool IsUsed() const { return merged_count_ > 0; }
GraphAssemblerLabel(GraphAssemblerLabelType type, int loop_nesting_level, GraphAssemblerLabel(GraphAssemblerLabelType type, int loop_nesting_level,
const std::array<MachineRepresentation, VarCount>& reps) Array<MachineRepresentation> reps)
: type_(type), : type_(type),
loop_nesting_level_(loop_nesting_level), loop_nesting_level_(loop_nesting_level),
representations_(reps) {} bindings_(Helper::InitNodeArray(reps)),
representations_(std::move(reps)) {}
~GraphAssemblerLabel() { DCHECK(IsBound() || merged_count_ == 0); } ~GraphAssemblerLabel() { DCHECK(IsBound() || merged_count_ == 0); }
...@@ -192,10 +230,43 @@ class GraphAssemblerLabel { ...@@ -192,10 +230,43 @@ class GraphAssemblerLabel {
size_t merged_count_ = 0; size_t merged_count_ = 0;
Node* effect_; Node* effect_;
Node* control_; Node* control_;
std::array<Node*, VarCount> bindings_; Array<Node*> bindings_;
const std::array<MachineRepresentation, VarCount> representations_; const Array<MachineRepresentation> representations_;
}; };
using GraphAssemblerDynamicLabel =
GraphAssemblerLabel<detail::kGraphAssemblerLabelDynamicCount>;
namespace detail {
template <typename T, typename Enable, typename... Us>
struct GraphAssemblerLabelForXHelper;
// If the Us are a template pack each assignable to T, use a static label.
template <typename T, typename... Us>
struct GraphAssemblerLabelForXHelper<
T, std::enable_if_t<std::conjunction_v<std::is_assignable<T&, Us>...>>,
Us...> {
using Type = GraphAssemblerLabel<sizeof...(Us)>;
};
// If the single arg is a vector of U assignable to T, use a dynamic label.
template <typename T, typename U>
struct GraphAssemblerLabelForXHelper<
T, std::enable_if_t<std::is_assignable_v<T&, U>>, base::SmallVector<U, 4>> {
using Type = GraphAssemblerDynamicLabel;
};
template <typename... Vars>
using GraphAssemblerLabelForVars =
typename GraphAssemblerLabelForXHelper<Node*, void, Vars...>::Type;
template <typename... Reps>
using GraphAssemblerLabelForReps =
typename GraphAssemblerLabelForXHelper<MachineRepresentation, void,
Reps...>::Type;
} // namespace detail
using NodeChangedCallback = std::function<void(Node*)>; using NodeChangedCallback = std::function<void(Node*)>;
class V8_EXPORT_PRIVATE GraphAssembler { class V8_EXPORT_PRIVATE GraphAssembler {
public: public:
...@@ -212,35 +283,34 @@ class V8_EXPORT_PRIVATE GraphAssembler { ...@@ -212,35 +283,34 @@ class V8_EXPORT_PRIVATE GraphAssembler {
// Create label. // Create label.
template <typename... Reps> template <typename... Reps>
GraphAssemblerLabel<sizeof...(Reps)> MakeLabelFor( detail::GraphAssemblerLabelForReps<Reps...> MakeLabelFor(
GraphAssemblerLabelType type, Reps... reps) { GraphAssemblerLabelType type, Reps... reps) {
std::array<MachineRepresentation, sizeof...(Reps)> reps_array = {reps...}; std::array<MachineRepresentation, sizeof...(Reps)> reps_array = {reps...};
return MakeLabel<sizeof...(Reps)>(reps_array, type); return detail::GraphAssemblerLabelForReps<Reps...>(
type, loop_nesting_level_, std::move(reps_array));
} }
GraphAssemblerDynamicLabel MakeLabelFor(
// As above, but with an std::array of machine representations. GraphAssemblerLabelType type,
template <int VarCount> base::SmallVector<MachineRepresentation, 4> reps) {
GraphAssemblerLabel<VarCount> MakeLabel( return GraphAssemblerDynamicLabel(type, loop_nesting_level_,
std::array<MachineRepresentation, VarCount> reps_array, std::move(reps));
GraphAssemblerLabelType type) {
return GraphAssemblerLabel<VarCount>(type, loop_nesting_level_, reps_array);
} }
// Convenience wrapper for creating non-deferred labels. // Convenience wrapper for creating non-deferred labels.
template <typename... Reps> template <typename... Reps>
GraphAssemblerLabel<sizeof...(Reps)> MakeLabel(Reps... reps) { detail::GraphAssemblerLabelForReps<Reps...> MakeLabel(Reps... reps) {
return MakeLabelFor(GraphAssemblerLabelType::kNonDeferred, reps...); return MakeLabelFor(GraphAssemblerLabelType::kNonDeferred, reps...);
} }
// Convenience wrapper for creating loop labels. // Convenience wrapper for creating loop labels.
template <typename... Reps> template <typename... Reps>
GraphAssemblerLabel<sizeof...(Reps)> MakeLoopLabel(Reps... reps) { detail::GraphAssemblerLabelForReps<Reps...> MakeLoopLabel(Reps... reps) {
return MakeLabelFor(GraphAssemblerLabelType::kLoop, reps...); return MakeLabelFor(GraphAssemblerLabelType::kLoop, reps...);
} }
// Convenience wrapper for creating deferred labels. // Convenience wrapper for creating deferred labels.
template <typename... Reps> template <typename... Reps>
GraphAssemblerLabel<sizeof...(Reps)> MakeDeferredLabel(Reps... reps) { detail::GraphAssemblerLabelForReps<Reps...> MakeDeferredLabel(Reps... reps) {
return MakeLabelFor(GraphAssemblerLabelType::kDeferred, reps...); return MakeLabelFor(GraphAssemblerLabelType::kDeferred, reps...);
} }
...@@ -349,7 +419,7 @@ class V8_EXPORT_PRIVATE GraphAssembler { ...@@ -349,7 +419,7 @@ class V8_EXPORT_PRIVATE GraphAssembler {
void Bind(GraphAssemblerLabel<VarCount>* label); void Bind(GraphAssemblerLabel<VarCount>* label);
template <typename... Vars> template <typename... Vars>
void Goto(GraphAssemblerLabel<sizeof...(Vars)>* label, Vars...); void Goto(detail::GraphAssemblerLabelForVars<Vars...>* label, Vars...);
// Branch hints are inferred from if_true/if_false deferred states. // Branch hints are inferred from if_true/if_false deferred states.
void BranchWithCriticalSafetyCheck(Node* condition, void BranchWithCriticalSafetyCheck(Node* condition,
...@@ -358,13 +428,14 @@ class V8_EXPORT_PRIVATE GraphAssembler { ...@@ -358,13 +428,14 @@ class V8_EXPORT_PRIVATE GraphAssembler {
// Branch hints are inferred from if_true/if_false deferred states. // Branch hints are inferred from if_true/if_false deferred states.
template <typename... Vars> template <typename... Vars>
void Branch(Node* condition, GraphAssemblerLabel<sizeof...(Vars)>* if_true, void Branch(Node* condition,
GraphAssemblerLabel<sizeof...(Vars)>* if_false, Vars...); detail::GraphAssemblerLabelForVars<Vars...>* if_true,
detail::GraphAssemblerLabelForVars<Vars...>* if_false, Vars...);
template <typename... Vars> template <typename... Vars>
void BranchWithHint(Node* condition, void BranchWithHint(Node* condition,
GraphAssemblerLabel<sizeof...(Vars)>* if_true, detail::GraphAssemblerLabelForVars<Vars...>* if_true,
GraphAssemblerLabel<sizeof...(Vars)>* if_false, detail::GraphAssemblerLabelForVars<Vars...>* if_false,
BranchHint hint, Vars...); BranchHint hint, Vars...);
// Control helpers. // Control helpers.
...@@ -372,7 +443,8 @@ class V8_EXPORT_PRIVATE GraphAssembler { ...@@ -372,7 +443,8 @@ class V8_EXPORT_PRIVATE GraphAssembler {
// {GotoIf(c, l, h)} is equivalent to {BranchWithHint(c, l, templ, h); // {GotoIf(c, l, h)} is equivalent to {BranchWithHint(c, l, templ, h);
// Bind(templ)}. // Bind(templ)}.
template <typename... Vars> template <typename... Vars>
void GotoIf(Node* condition, GraphAssemblerLabel<sizeof...(Vars)>* label, void GotoIf(Node* condition,
detail::GraphAssemblerLabelForVars<Vars...>* label,
BranchHint hint, Vars...); BranchHint hint, Vars...);
// {GotoIfNot(c, l, h)} is equivalent to {BranchWithHint(c, templ, l, h); // {GotoIfNot(c, l, h)} is equivalent to {BranchWithHint(c, templ, l, h);
...@@ -381,18 +453,19 @@ class V8_EXPORT_PRIVATE GraphAssembler { ...@@ -381,18 +453,19 @@ class V8_EXPORT_PRIVATE GraphAssembler {
// so {GotoIfNot(..., BranchHint::kTrue)} means "optimize for the case where // so {GotoIfNot(..., BranchHint::kTrue)} means "optimize for the case where
// the branch is *not* taken". // the branch is *not* taken".
template <typename... Vars> template <typename... Vars>
void GotoIfNot(Node* condition, GraphAssemblerLabel<sizeof...(Vars)>* label, void GotoIfNot(Node* condition,
detail::GraphAssemblerLabelForVars<Vars...>* label,
BranchHint hint, Vars...); BranchHint hint, Vars...);
// {GotoIf(c, l)} is equivalent to {Branch(c, l, templ);Bind(templ)}. // {GotoIf(c, l)} is equivalent to {Branch(c, l, templ);Bind(templ)}.
template <typename... Vars> template <typename... Vars>
void GotoIf(Node* condition, GraphAssemblerLabel<sizeof...(Vars)>* label, void GotoIf(Node* condition,
Vars...); detail::GraphAssemblerLabelForVars<Vars...>* label, Vars...);
// {GotoIfNot(c, l)} is equivalent to {Branch(c, templ, l);Bind(templ)}. // {GotoIfNot(c, l)} is equivalent to {Branch(c, templ, l);Bind(templ)}.
template <typename... Vars> template <typename... Vars>
void GotoIfNot(Node* condition, GraphAssemblerLabel<sizeof...(Vars)>* label, void GotoIfNot(Node* condition,
Vars...); detail::GraphAssemblerLabelForVars<Vars...>* label, Vars...);
bool HasActiveBlock() const { bool HasActiveBlock() const {
// This is false if the current block has been terminated (e.g. by a Goto or // This is false if the current block has been terminated (e.g. by a Goto or
...@@ -437,7 +510,8 @@ class V8_EXPORT_PRIVATE GraphAssembler { ...@@ -437,7 +510,8 @@ class V8_EXPORT_PRIVATE GraphAssembler {
protected: protected:
template <typename... Vars> template <typename... Vars>
void MergeState(GraphAssemblerLabel<sizeof...(Vars)>* label, Vars... vars); void MergeState(detail::GraphAssemblerLabelForVars<Vars...>* label,
Vars... vars);
V8_INLINE Node* AddClonedNode(Node* node); V8_INLINE Node* AddClonedNode(Node* node);
...@@ -525,8 +599,8 @@ class V8_EXPORT_PRIVATE GraphAssembler { ...@@ -525,8 +599,8 @@ class V8_EXPORT_PRIVATE GraphAssembler {
template <typename... Vars> template <typename... Vars>
void BranchImpl(Node* condition, void BranchImpl(Node* condition,
GraphAssemblerLabel<sizeof...(Vars)>* if_true, detail::GraphAssemblerLabelForVars<Vars...>* if_true,
GraphAssemblerLabel<sizeof...(Vars)>* if_false, detail::GraphAssemblerLabelForVars<Vars...>* if_false,
BranchHint hint, Vars...); BranchHint hint, Vars...);
Zone* temp_zone_; Zone* temp_zone_;
...@@ -556,18 +630,21 @@ class V8_EXPORT_PRIVATE GraphAssembler { ...@@ -556,18 +630,21 @@ class V8_EXPORT_PRIVATE GraphAssembler {
template <size_t VarCount> template <size_t VarCount>
Node* GraphAssemblerLabel<VarCount>::PhiAt(size_t index) { Node* GraphAssemblerLabel<VarCount>::PhiAt(size_t index) {
DCHECK(IsBound()); DCHECK(IsBound());
DCHECK_LT(index, VarCount); DCHECK_LT(index, Count());
return bindings_[index]; return bindings_[index];
} }
template <typename... Vars> template <typename... Vars>
void GraphAssembler::MergeState(GraphAssemblerLabel<sizeof...(Vars)>* label, void GraphAssembler::MergeState(
Vars... vars) { detail::GraphAssemblerLabelForVars<Vars...>* label, Vars... vars) {
using NodeArray = typename detail::GraphAssemblerLabelForVars<
Vars...>::template Array<Node*>;
RestoreEffectControlScope restore_effect_control_scope(this); RestoreEffectControlScope restore_effect_control_scope(this);
const int merged_count = static_cast<int>(label->merged_count_); const int merged_count = static_cast<int>(label->merged_count_);
static constexpr int kVarCount = sizeof...(vars);
std::array<Node*, kVarCount> var_array = {vars...}; const size_t var_count = label->Count();
NodeArray var_array{vars...};
const bool is_loop_exit = label->loop_nesting_level_ != loop_nesting_level_; const bool is_loop_exit = label->loop_nesting_level_ != loop_nesting_level_;
if (is_loop_exit) { if (is_loop_exit) {
...@@ -585,7 +662,7 @@ void GraphAssembler::MergeState(GraphAssemblerLabel<sizeof...(Vars)>* label, ...@@ -585,7 +662,7 @@ void GraphAssembler::MergeState(GraphAssemblerLabel<sizeof...(Vars)>* label,
AddNode(graph()->NewNode(common()->LoopExit(), control(), AddNode(graph()->NewNode(common()->LoopExit(), control(),
*loop_headers_.back())); *loop_headers_.back()));
AddNode(graph()->NewNode(common()->LoopExitEffect(), effect(), control())); AddNode(graph()->NewNode(common()->LoopExitEffect(), effect(), control()));
for (size_t i = 0; i < kVarCount; i++) { for (size_t i = 0; i < var_count; i++) {
var_array[i] = AddNode(graph()->NewNode( var_array[i] = AddNode(graph()->NewNode(
common()->LoopExitValue(MachineRepresentation::kTagged), var_array[i], common()->LoopExitValue(MachineRepresentation::kTagged), var_array[i],
control())); control()));
...@@ -602,7 +679,7 @@ void GraphAssembler::MergeState(GraphAssemblerLabel<sizeof...(Vars)>* label, ...@@ -602,7 +679,7 @@ void GraphAssembler::MergeState(GraphAssemblerLabel<sizeof...(Vars)>* label,
Node* terminate = graph()->NewNode(common()->Terminate(), label->effect_, Node* terminate = graph()->NewNode(common()->Terminate(), label->effect_,
label->control_); label->control_);
NodeProperties::MergeControlToEnd(graph(), common(), terminate); NodeProperties::MergeControlToEnd(graph(), common(), terminate);
for (size_t i = 0; i < kVarCount; i++) { for (size_t i = 0; i < var_count; i++) {
label->bindings_[i] = label->bindings_[i] =
graph()->NewNode(common()->Phi(label->representations_[i], 2), graph()->NewNode(common()->Phi(label->representations_[i], 2),
var_array[i], var_array[i], label->control_); var_array[i], var_array[i], label->control_);
...@@ -612,7 +689,7 @@ void GraphAssembler::MergeState(GraphAssemblerLabel<sizeof...(Vars)>* label, ...@@ -612,7 +689,7 @@ void GraphAssembler::MergeState(GraphAssemblerLabel<sizeof...(Vars)>* label,
DCHECK_EQ(1, merged_count); DCHECK_EQ(1, merged_count);
label->control_->ReplaceInput(1, control()); label->control_->ReplaceInput(1, control());
label->effect_->ReplaceInput(1, effect()); label->effect_->ReplaceInput(1, effect());
for (size_t i = 0; i < kVarCount; i++) { for (size_t i = 0; i < var_count; i++) {
label->bindings_[i]->ReplaceInput(1, var_array[i]); label->bindings_[i]->ReplaceInput(1, var_array[i]);
CHECK(!NodeProperties::IsTyped(var_array[i])); // Unsupported. CHECK(!NodeProperties::IsTyped(var_array[i])); // Unsupported.
} }
...@@ -624,7 +701,7 @@ void GraphAssembler::MergeState(GraphAssemblerLabel<sizeof...(Vars)>* label, ...@@ -624,7 +701,7 @@ void GraphAssembler::MergeState(GraphAssemblerLabel<sizeof...(Vars)>* label,
// Just set the control, effect and variables directly. // Just set the control, effect and variables directly.
label->control_ = control(); label->control_ = control();
label->effect_ = effect(); label->effect_ = effect();
for (size_t i = 0; i < kVarCount; i++) { for (size_t i = 0; i < var_count; i++) {
label->bindings_[i] = var_array[i]; label->bindings_[i] = var_array[i];
} }
} else if (merged_count == 1) { } else if (merged_count == 1) {
...@@ -633,7 +710,7 @@ void GraphAssembler::MergeState(GraphAssemblerLabel<sizeof...(Vars)>* label, ...@@ -633,7 +710,7 @@ void GraphAssembler::MergeState(GraphAssemblerLabel<sizeof...(Vars)>* label,
graph()->NewNode(common()->Merge(2), label->control_, control()); graph()->NewNode(common()->Merge(2), label->control_, control());
label->effect_ = graph()->NewNode(common()->EffectPhi(2), label->effect_, label->effect_ = graph()->NewNode(common()->EffectPhi(2), label->effect_,
effect(), label->control_); effect(), label->control_);
for (size_t i = 0; i < kVarCount; i++) { for (size_t i = 0; i < var_count; i++) {
label->bindings_[i] = graph()->NewNode( label->bindings_[i] = graph()->NewNode(
common()->Phi(label->representations_[i], 2), label->bindings_[i], common()->Phi(label->representations_[i], 2), label->bindings_[i],
var_array[i], label->control_); var_array[i], label->control_);
...@@ -651,7 +728,7 @@ void GraphAssembler::MergeState(GraphAssemblerLabel<sizeof...(Vars)>* label, ...@@ -651,7 +728,7 @@ void GraphAssembler::MergeState(GraphAssemblerLabel<sizeof...(Vars)>* label,
NodeProperties::ChangeOp(label->effect_, NodeProperties::ChangeOp(label->effect_,
common()->EffectPhi(merged_count + 1)); common()->EffectPhi(merged_count + 1));
for (size_t i = 0; i < kVarCount; i++) { for (size_t i = 0; i < var_count; i++) {
DCHECK_EQ(IrOpcode::kPhi, label->bindings_[i]->opcode()); DCHECK_EQ(IrOpcode::kPhi, label->bindings_[i]->opcode());
label->bindings_[i]->ReplaceInput(merged_count, var_array[i]); label->bindings_[i]->ReplaceInput(merged_count, var_array[i]);
label->bindings_[i]->AppendInput(graph()->zone(), label->control_); label->bindings_[i]->AppendInput(graph()->zone(), label->control_);
...@@ -686,7 +763,7 @@ void GraphAssembler::Bind(GraphAssemblerLabel<VarCount>* label) { ...@@ -686,7 +763,7 @@ void GraphAssembler::Bind(GraphAssemblerLabel<VarCount>* label) {
if (label->merged_count_ > 1 || label->IsLoop()) { if (label->merged_count_ > 1 || label->IsLoop()) {
AddNode(label->control_); AddNode(label->control_);
AddNode(label->effect_); AddNode(label->effect_);
for (size_t i = 0; i < VarCount; i++) { for (size_t i = 0; i < label->Count(); i++) {
AddNode(label->bindings_[i]); AddNode(label->bindings_[i]);
} }
} else { } else {
...@@ -697,10 +774,9 @@ void GraphAssembler::Bind(GraphAssemblerLabel<VarCount>* label) { ...@@ -697,10 +774,9 @@ void GraphAssembler::Bind(GraphAssemblerLabel<VarCount>* label) {
} }
template <typename... Vars> template <typename... Vars>
void GraphAssembler::Branch(Node* condition, void GraphAssembler::Branch(
GraphAssemblerLabel<sizeof...(Vars)>* if_true, Node* condition, detail::GraphAssemblerLabelForVars<Vars...>* if_true,
GraphAssemblerLabel<sizeof...(Vars)>* if_false, detail::GraphAssemblerLabelForVars<Vars...>* if_false, Vars... vars) {
Vars... vars) {
BranchHint hint = BranchHint::kNone; BranchHint hint = BranchHint::kNone;
if (if_true->IsDeferred() != if_false->IsDeferred()) { if (if_true->IsDeferred() != if_false->IsDeferred()) {
hint = if_false->IsDeferred() ? BranchHint::kTrue : BranchHint::kFalse; hint = if_false->IsDeferred() ? BranchHint::kTrue : BranchHint::kFalse;
...@@ -711,17 +787,17 @@ void GraphAssembler::Branch(Node* condition, ...@@ -711,17 +787,17 @@ void GraphAssembler::Branch(Node* condition,
template <typename... Vars> template <typename... Vars>
void GraphAssembler::BranchWithHint( void GraphAssembler::BranchWithHint(
Node* condition, GraphAssemblerLabel<sizeof...(Vars)>* if_true, Node* condition, detail::GraphAssemblerLabelForVars<Vars...>* if_true,
GraphAssemblerLabel<sizeof...(Vars)>* if_false, BranchHint hint, detail::GraphAssemblerLabelForVars<Vars...>* if_false, BranchHint hint,
Vars... vars) { Vars... vars) {
BranchImpl(condition, if_true, if_false, hint, vars...); BranchImpl(condition, if_true, if_false, hint, vars...);
} }
template <typename... Vars> template <typename... Vars>
void GraphAssembler::BranchImpl(Node* condition, void GraphAssembler::BranchImpl(
GraphAssemblerLabel<sizeof...(Vars)>* if_true, Node* condition, detail::GraphAssemblerLabelForVars<Vars...>* if_true,
GraphAssemblerLabel<sizeof...(Vars)>* if_false, detail::GraphAssemblerLabelForVars<Vars...>* if_false, BranchHint hint,
BranchHint hint, Vars... vars) { Vars... vars) {
DCHECK_NOT_NULL(control()); DCHECK_NOT_NULL(control());
Node* branch = graph()->NewNode(common()->Branch(hint), condition, control()); Node* branch = graph()->NewNode(common()->Branch(hint), condition, control());
...@@ -737,7 +813,7 @@ void GraphAssembler::BranchImpl(Node* condition, ...@@ -737,7 +813,7 @@ void GraphAssembler::BranchImpl(Node* condition,
} }
template <typename... Vars> template <typename... Vars>
void GraphAssembler::Goto(GraphAssemblerLabel<sizeof...(Vars)>* label, void GraphAssembler::Goto(detail::GraphAssemblerLabelForVars<Vars...>* label,
Vars... vars) { Vars... vars) {
DCHECK_NOT_NULL(control()); DCHECK_NOT_NULL(control());
DCHECK_NOT_NULL(effect()); DCHECK_NOT_NULL(effect());
...@@ -749,7 +825,7 @@ void GraphAssembler::Goto(GraphAssemblerLabel<sizeof...(Vars)>* label, ...@@ -749,7 +825,7 @@ void GraphAssembler::Goto(GraphAssemblerLabel<sizeof...(Vars)>* label,
template <typename... Vars> template <typename... Vars>
void GraphAssembler::GotoIf(Node* condition, void GraphAssembler::GotoIf(Node* condition,
GraphAssemblerLabel<sizeof...(Vars)>* label, detail::GraphAssemblerLabelForVars<Vars...>* label,
BranchHint hint, Vars... vars) { BranchHint hint, Vars... vars) {
Node* branch = graph()->NewNode(common()->Branch(hint), condition, control()); Node* branch = graph()->NewNode(common()->Branch(hint), condition, control());
...@@ -760,9 +836,9 @@ void GraphAssembler::GotoIf(Node* condition, ...@@ -760,9 +836,9 @@ void GraphAssembler::GotoIf(Node* condition,
} }
template <typename... Vars> template <typename... Vars>
void GraphAssembler::GotoIfNot(Node* condition, void GraphAssembler::GotoIfNot(
GraphAssemblerLabel<sizeof...(Vars)>* label, Node* condition, detail::GraphAssemblerLabelForVars<Vars...>* label,
BranchHint hint, Vars... vars) { BranchHint hint, Vars... vars) {
Node* branch = graph()->NewNode(common()->Branch(hint), condition, control()); Node* branch = graph()->NewNode(common()->Branch(hint), condition, control());
control_ = graph()->NewNode(common()->IfFalse(), branch); control_ = graph()->NewNode(common()->IfFalse(), branch);
...@@ -773,7 +849,7 @@ void GraphAssembler::GotoIfNot(Node* condition, ...@@ -773,7 +849,7 @@ void GraphAssembler::GotoIfNot(Node* condition,
template <typename... Vars> template <typename... Vars>
void GraphAssembler::GotoIf(Node* condition, void GraphAssembler::GotoIf(Node* condition,
GraphAssemblerLabel<sizeof...(Vars)>* label, detail::GraphAssemblerLabelForVars<Vars...>* label,
Vars... vars) { Vars... vars) {
BranchHint hint = BranchHint hint =
label->IsDeferred() ? BranchHint::kFalse : BranchHint::kNone; label->IsDeferred() ? BranchHint::kFalse : BranchHint::kNone;
...@@ -781,9 +857,9 @@ void GraphAssembler::GotoIf(Node* condition, ...@@ -781,9 +857,9 @@ void GraphAssembler::GotoIf(Node* condition,
} }
template <typename... Vars> template <typename... Vars>
void GraphAssembler::GotoIfNot(Node* condition, void GraphAssembler::GotoIfNot(
GraphAssemblerLabel<sizeof...(Vars)>* label, Node* condition, detail::GraphAssemblerLabelForVars<Vars...>* label,
Vars... vars) { Vars... vars) {
BranchHint hint = label->IsDeferred() ? BranchHint::kTrue : BranchHint::kNone; BranchHint hint = label->IsDeferred() ? BranchHint::kTrue : BranchHint::kNone;
return GotoIfNot(condition, label, hint, vars...); return GotoIfNot(condition, label, hint, vars...);
} }
......
...@@ -744,10 +744,7 @@ class IteratingArrayBuiltinReducerAssembler : public JSCallReducerAssembler { ...@@ -744,10 +744,7 @@ class IteratingArrayBuiltinReducerAssembler : public JSCallReducerAssembler {
TNode<Vars>... vars) { TNode<Vars>... vars) {
if (!IsHoleyElementsKind(kind)) return o; if (!IsHoleyElementsKind(kind)) return o;
std::array<MachineRepresentation, sizeof...(Vars)> reps = { auto if_not_hole = MakeLabel(MachineRepresentationOf<Vars>::value...);
MachineRepresentationOf<Vars>::value...};
auto if_not_hole =
MakeLabel<sizeof...(Vars)>(reps, GraphAssemblerLabelType::kNonDeferred);
BranchWithHint(HoleCheck(kind, o), continue_label, &if_not_hole, BranchWithHint(HoleCheck(kind, o), continue_label, &if_not_hole,
BranchHint::kFalse, vars...); BranchHint::kFalse, vars...);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment