Commit d39ba102 authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

[gasm] Implement ReduceArrayPrototypeReduce using the graph assembler

Very similar to the recent ArrayPrototypeForEach port, this moves the
Reduce reduction, which previously operated directly on the graph, to
graph assembler.

Nothing too interesting here, but it's becoming clearer that we will
need more flexible Branch (multiple merge values) and If (a `break`
mechanism) handling in the future.

Bug: v8:9972
Change-Id: Ic48c85305ba721a9a43c67f7ad13c60da310487e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1934329
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarMichael Stanton <mvstanton@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65233}
parent dc3a90be
...@@ -1731,10 +1731,10 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) { ...@@ -1731,10 +1731,10 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) {
Node* map = __ HeapConstant(maps[i]); Node* map = __ HeapConstant(maps[i]);
Node* check = __ TaggedEqual(value_map, map); Node* check = __ TaggedEqual(value_map, map);
if (i == map_count - 1) { if (i == map_count - 1) {
__ Branch(check, &done, &migrate, IsSafetyCheck::kCriticalSafetyCheck); __ BranchWithCriticalSafetyCheck(check, &done, &migrate);
} else { } else {
auto next_map = __ MakeLabel(); auto next_map = __ MakeLabel();
__ Branch(check, &done, &next_map, IsSafetyCheck::kCriticalSafetyCheck); __ BranchWithCriticalSafetyCheck(check, &done, &next_map);
__ Bind(&next_map); __ Bind(&next_map);
} }
} }
...@@ -1777,7 +1777,7 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) { ...@@ -1777,7 +1777,7 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) {
frame_state, IsSafetyCheck::kCriticalSafetyCheck); frame_state, IsSafetyCheck::kCriticalSafetyCheck);
} else { } else {
auto next_map = __ MakeLabel(); auto next_map = __ MakeLabel();
__ Branch(check, &done, &next_map, IsSafetyCheck::kCriticalSafetyCheck); __ BranchWithCriticalSafetyCheck(check, &done, &next_map);
__ Bind(&next_map); __ Bind(&next_map);
} }
} }
...@@ -1799,7 +1799,7 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) { ...@@ -1799,7 +1799,7 @@ void EffectControlLinearizer::LowerCheckMaps(Node* node, Node* frame_state) {
frame_state, IsSafetyCheck::kCriticalSafetyCheck); frame_state, IsSafetyCheck::kCriticalSafetyCheck);
} else { } else {
auto next_map = __ MakeLabel(); auto next_map = __ MakeLabel();
__ Branch(check, &done, &next_map, IsSafetyCheck::kCriticalSafetyCheck); __ BranchWithCriticalSafetyCheck(check, &done, &next_map);
__ Bind(&next_map); __ Bind(&next_map);
} }
} }
...@@ -1824,7 +1824,7 @@ Node* EffectControlLinearizer::LowerCompareMaps(Node* node) { ...@@ -1824,7 +1824,7 @@ Node* EffectControlLinearizer::LowerCompareMaps(Node* node) {
auto next_map = __ MakeLabel(); auto next_map = __ MakeLabel();
auto passed = __ MakeLabel(); auto passed = __ MakeLabel();
__ Branch(check, &passed, &next_map, IsSafetyCheck::kCriticalSafetyCheck); __ BranchWithCriticalSafetyCheck(check, &passed, &next_map);
__ Bind(&passed); __ Bind(&passed);
__ Goto(&done, __ Int32Constant(1)); __ Goto(&done, __ Int32Constant(1));
......
...@@ -523,10 +523,19 @@ Node* GraphAssembler::NumberAdd(Node* lhs, Node* rhs) { ...@@ -523,10 +523,19 @@ Node* GraphAssembler::NumberAdd(Node* lhs, Node* rhs) {
return AddNode(graph()->NewNode(simplified()->NumberAdd(), lhs, rhs)); return AddNode(graph()->NewNode(simplified()->NumberAdd(), lhs, rhs));
} }
Node* GraphAssembler::NumberSubtract(Node* lhs, Node* rhs) {
return AddNode(graph()->NewNode(simplified()->NumberSubtract(), lhs, rhs));
}
Node* GraphAssembler::NumberLessThan(Node* lhs, Node* rhs) { Node* GraphAssembler::NumberLessThan(Node* lhs, Node* rhs) {
return AddNode(graph()->NewNode(simplified()->NumberLessThan(), lhs, rhs)); return AddNode(graph()->NewNode(simplified()->NumberLessThan(), lhs, rhs));
} }
Node* GraphAssembler::NumberLessThanOrEqual(Node* lhs, Node* rhs) {
return AddNode(
graph()->NewNode(simplified()->NumberLessThanOrEqual(), lhs, rhs));
}
Node* GraphAssembler::StringSubstring(Node* string, Node* from, Node* to) { Node* GraphAssembler::StringSubstring(Node* string, Node* from, Node* to) {
return AddNode(graph()->NewNode(simplified()->StringSubstring(), string, from, return AddNode(graph()->NewNode(simplified()->StringSubstring(), string, from,
to, effect(), control())); to, effect(), control()));
...@@ -536,6 +545,11 @@ Node* GraphAssembler::ObjectIsCallable(Node* value) { ...@@ -536,6 +545,11 @@ Node* GraphAssembler::ObjectIsCallable(Node* value) {
return AddNode(graph()->NewNode(simplified()->ObjectIsCallable(), value)); return AddNode(graph()->NewNode(simplified()->ObjectIsCallable(), value));
} }
Node* GraphAssembler::CheckIf(Node* cond, DeoptimizeReason reason) {
return AddNode(graph()->NewNode(simplified()->CheckIf(reason), cond, effect(),
control()));
}
Node* GraphAssembler::NumberIsFloat64Hole(Node* value) { Node* GraphAssembler::NumberIsFloat64Hole(Node* value) {
return AddNode(graph()->NewNode(simplified()->NumberIsFloat64Hole(), value)); return AddNode(graph()->NewNode(simplified()->NumberIsFloat64Hole(), value));
} }
...@@ -658,50 +672,36 @@ Node* GraphAssembler::DeoptimizeIfNot(DeoptimizeReason reason, ...@@ -658,50 +672,36 @@ Node* GraphAssembler::DeoptimizeIfNot(DeoptimizeReason reason,
condition, frame_state, effect(), control())); condition, frame_state, effect(), control()));
} }
void GraphAssembler::Branch(Node* condition, GraphAssemblerLabel<0u>* if_true, void GraphAssembler::BranchWithCriticalSafetyCheck(
GraphAssemblerLabel<0u>* if_false, Node* condition, GraphAssemblerLabel<0u>* if_true,
IsSafetyCheck is_safety_check) { GraphAssemblerLabel<0u>* if_false) {
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;
} }
Branch(condition, if_true, if_false, hint, is_safety_check); BranchImpl(condition, if_true, if_false, hint,
IsSafetyCheck::kCriticalSafetyCheck);
} }
void GraphAssembler::Branch(Node* condition, GraphAssemblerLabel<0u>* if_true, void GraphAssembler::RecordBranchInBlockUpdater(Node* branch,
GraphAssemblerLabel<0u>* if_false, BranchHint hint, Node* if_true_control,
IsSafetyCheck is_safety_check) { Node* if_false_control,
DCHECK_NOT_NULL(control()); BasicBlock* if_true_block,
BasicBlock* if_false_block) {
DCHECK_NOT_NULL(block_updater_);
// TODO(9684): Only split the current basic block if the label's target
// block has multiple merges.
BasicBlock* if_true_target = block_updater_->SplitBasicBlock();
BasicBlock* if_false_target = block_updater_->SplitBasicBlock();
Node* branch = graph()->NewNode(common()->Branch(hint, is_safety_check), block_updater_->AddBranch(branch, if_true_target, if_false_target);
condition, control());
Node* if_true_control = control_ = block_updater_->AddNode(if_true_control, if_true_target);
graph()->NewNode(common()->IfTrue(), branch); block_updater_->AddGoto(if_true_target, if_true_block);
MergeState(if_true);
Node* if_false_control = control_ = block_updater_->AddNode(if_false_control, if_false_target);
graph()->NewNode(common()->IfFalse(), branch); block_updater_->AddGoto(if_false_target, if_false_block);
MergeState(if_false);
if (block_updater_) {
// TODO(9684): Only split the current basic block if the label's target
// block has multiple merges.
BasicBlock* if_true_target = block_updater_->SplitBasicBlock();
BasicBlock* if_false_target = block_updater_->SplitBasicBlock();
block_updater_->AddBranch(branch, if_true_target, if_false_target);
block_updater_->AddNode(if_true_control, if_true_target);
block_updater_->AddGoto(if_true_target, if_true->basic_block());
block_updater_->AddNode(if_false_control, if_false_target);
block_updater_->AddGoto(if_false_target, if_false->basic_block());
}
control_ = nullptr;
effect_ = nullptr;
} }
void GraphAssembler::BindBasicBlock(BasicBlock* block) { void GraphAssembler::BindBasicBlock(BasicBlock* block) {
......
...@@ -264,9 +264,12 @@ class V8_EXPORT_PRIVATE GraphAssembler { ...@@ -264,9 +264,12 @@ class V8_EXPORT_PRIVATE GraphAssembler {
Node* NumberMin(Node* lhs, Node* rhs); Node* NumberMin(Node* lhs, Node* rhs);
Node* NumberMax(Node* lhs, Node* rhs); Node* NumberMax(Node* lhs, Node* rhs);
Node* NumberLessThan(Node* lhs, Node* rhs); Node* NumberLessThan(Node* lhs, Node* rhs);
Node* NumberLessThanOrEqual(Node* lhs, Node* rhs);
Node* NumberAdd(Node* lhs, Node* rhs); Node* NumberAdd(Node* lhs, Node* rhs);
Node* NumberSubtract(Node* lhs, Node* rhs);
Node* StringSubstring(Node* string, Node* from, Node* to); Node* StringSubstring(Node* string, Node* from, Node* to);
Node* ObjectIsCallable(Node* value); Node* ObjectIsCallable(Node* value);
Node* CheckIf(Node* cond, DeoptimizeReason reason);
Node* NumberIsFloat64Hole(Node* value); Node* NumberIsFloat64Hole(Node* value);
Node* TypeGuard(Type type, Node* value); Node* TypeGuard(Type type, Node* value);
...@@ -306,14 +309,21 @@ class V8_EXPORT_PRIVATE GraphAssembler { ...@@ -306,14 +309,21 @@ class V8_EXPORT_PRIVATE GraphAssembler {
template <typename... Vars> template <typename... Vars>
void Goto(GraphAssemblerLabel<sizeof...(Vars)>* label, Vars...); void Goto(GraphAssemblerLabel<sizeof...(Vars)>* label, Vars...);
void Branch(Node* condition, GraphAssemblerLabel<0u>* if_true, // Branch hints are inferred from if_true/if_false deferred states.
GraphAssemblerLabel<0u>* if_false, BranchHint hint, void BranchWithCriticalSafetyCheck(Node* condition,
IsSafetyCheck is_safety_check = IsSafetyCheck::kNoSafetyCheck); GraphAssemblerLabel<0u>* if_true,
// Branch hints in this version are inferred from if_true/if_false deferred GraphAssemblerLabel<0u>* if_false);
// states.
void Branch(Node* condition, GraphAssemblerLabel<0u>* if_true, // Branch hints are inferred from if_true/if_false deferred states.
GraphAssemblerLabel<0u>* if_false, template <typename... Vars>
IsSafetyCheck is_safety_check = IsSafetyCheck::kNoSafetyCheck); void Branch(Node* condition, GraphAssemblerLabel<sizeof...(Vars)>* if_true,
GraphAssemblerLabel<sizeof...(Vars)>* if_false, Vars...);
template <typename... Vars>
void BranchWithHint(Node* condition,
GraphAssemblerLabel<sizeof...(Vars)>* if_true,
GraphAssemblerLabel<sizeof...(Vars)>* if_false,
BranchHint hint, Vars...);
// Control helpers. // Control helpers.
// {GotoIf(c, l)} is equivalent to {Branch(c, l, templ);Bind(templ)}. // {GotoIf(c, l)} is equivalent to {Branch(c, l, templ);Bind(templ)}.
...@@ -374,6 +384,17 @@ class V8_EXPORT_PRIVATE GraphAssembler { ...@@ -374,6 +384,17 @@ class V8_EXPORT_PRIVATE GraphAssembler {
return jsgraph()->simplified(); return jsgraph()->simplified();
} }
private:
template <typename... Vars>
void BranchImpl(Node* condition,
GraphAssemblerLabel<sizeof...(Vars)>* if_true,
GraphAssemblerLabel<sizeof...(Vars)>* if_false,
BranchHint hint, IsSafetyCheck is_safety_check, Vars...);
void RecordBranchInBlockUpdater(Node* branch, Node* if_true_control,
Node* if_false_control,
BasicBlock* if_true_block,
BasicBlock* if_false_block);
SetOncePointer<Operator const> to_number_operator_; SetOncePointer<Operator const> to_number_operator_;
Zone* temp_zone_; Zone* temp_zone_;
JSGraph* jsgraph_; JSGraph* jsgraph_;
...@@ -490,6 +511,57 @@ void GraphAssembler::Bind(GraphAssemblerLabel<VarCount>* label) { ...@@ -490,6 +511,57 @@ void GraphAssembler::Bind(GraphAssemblerLabel<VarCount>* label) {
} }
} }
template <typename... Vars>
void GraphAssembler::Branch(Node* condition,
GraphAssemblerLabel<sizeof...(Vars)>* if_true,
GraphAssemblerLabel<sizeof...(Vars)>* if_false,
Vars... vars) {
BranchHint hint = BranchHint::kNone;
if (if_true->IsDeferred() != if_false->IsDeferred()) {
hint = if_false->IsDeferred() ? BranchHint::kTrue : BranchHint::kFalse;
}
BranchImpl(condition, if_true, if_false, hint, IsSafetyCheck::kNoSafetyCheck,
vars...);
}
template <typename... Vars>
void GraphAssembler::BranchWithHint(
Node* condition, GraphAssemblerLabel<sizeof...(Vars)>* if_true,
GraphAssemblerLabel<sizeof...(Vars)>* if_false, BranchHint hint,
Vars... vars) {
BranchImpl(condition, if_true, if_false, hint, IsSafetyCheck::kNoSafetyCheck,
vars...);
}
template <typename... Vars>
void GraphAssembler::BranchImpl(Node* condition,
GraphAssemblerLabel<sizeof...(Vars)>* if_true,
GraphAssemblerLabel<sizeof...(Vars)>* if_false,
BranchHint hint, IsSafetyCheck is_safety_check,
Vars... vars) {
DCHECK_NOT_NULL(control());
Node* branch = graph()->NewNode(common()->Branch(hint, is_safety_check),
condition, control());
Node* if_true_control = control_ =
graph()->NewNode(common()->IfTrue(), branch);
MergeState(if_true, vars...);
Node* if_false_control = control_ =
graph()->NewNode(common()->IfFalse(), branch);
MergeState(if_false, vars...);
if (block_updater_) {
RecordBranchInBlockUpdater(branch, if_true_control, if_false_control,
if_true->basic_block(), if_false->basic_block());
}
control_ = nullptr;
effect_ = nullptr;
}
template <typename... Vars> template <typename... Vars>
void GraphAssembler::Goto(GraphAssemblerLabel<sizeof...(Vars)>* label, void GraphAssembler::Goto(GraphAssemblerLabel<sizeof...(Vars)>* label,
Vars... vars) { Vars... vars) {
......
This diff is collapsed.
...@@ -84,9 +84,9 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer { ...@@ -84,9 +84,9 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer {
Reduction ReduceReflectGetPrototypeOf(Node* node); Reduction ReduceReflectGetPrototypeOf(Node* node);
Reduction ReduceReflectHas(Node* node); Reduction ReduceReflectHas(Node* node);
Reduction ReduceArrayForEach(Node* node, const SharedFunctionInfoRef& shared); Reduction ReduceArrayForEach(Node* node, const SharedFunctionInfoRef& shared);
enum class ArrayReduceDirection { kLeft, kRight }; Reduction ReduceArrayReduce(Node* node, const SharedFunctionInfoRef& shared);
Reduction ReduceArrayReduce(Node* node, ArrayReduceDirection direction, Reduction ReduceArrayReduceRight(Node* node,
const SharedFunctionInfoRef& shared); const SharedFunctionInfoRef& shared);
Reduction ReduceArrayMap(Node* node, const SharedFunctionInfoRef& shared); Reduction ReduceArrayMap(Node* node, const SharedFunctionInfoRef& shared);
Reduction ReduceArrayFilter(Node* node, const SharedFunctionInfoRef& shared); Reduction ReduceArrayFilter(Node* node, const SharedFunctionInfoRef& shared);
enum class ArrayFindVariant { kFind, kFindIndex }; enum class ArrayFindVariant { kFind, kFindIndex };
......
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