Commit 0c0ab3dc authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[ignition/turbofan] Use Switch node for Switch bytecode

Uses CheckSmi to force the switch argument to be a Smi, so that it can
be used as an input into a Switch node.

Change-Id: Ibec6beaeebc2168a3f80b86512c70a99d52f2575
Reviewed-on: https://chromium-review.googlesource.com/505621
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45397}
parent 9fd599ef
...@@ -2165,24 +2165,25 @@ void BytecodeGraphBuilder::VisitJumpIfNotUndefinedConstant() { ...@@ -2165,24 +2165,25 @@ void BytecodeGraphBuilder::VisitJumpIfNotUndefinedConstant() {
void BytecodeGraphBuilder::VisitJumpLoop() { BuildJump(); } void BytecodeGraphBuilder::VisitJumpLoop() { BuildJump(); }
void BytecodeGraphBuilder::VisitSwitchOnSmiNoFeedback() { void BytecodeGraphBuilder::BuildSwitchOnSmi(Node* condition) {
PrepareEagerCheckpoint(); interpreter::JumpTableTargetOffsets offsets =
bytecode_iterator().GetJumpTableTargetOffsets();
Node* acc = environment()->LookupAccumulator();
for (const auto& entry : bytecode_iterator().GetJumpTableTargetOffsets()) { NewSwitch(condition, offsets.size() + 1);
// TODO(leszeks): This should be a switch, but under OSR we fail to type the for (const auto& entry : offsets) {
// input correctly so we have to do a JS strict equal instead.
NewBranch(
NewNode(javascript()->StrictEqual(CompareOperationHint::kSignedSmall),
acc, jsgraph()->SmiConstant(entry.case_value)));
{
SubEnvironment sub_environment(this); SubEnvironment sub_environment(this);
NewIfTrue(); NewIfValue(entry.case_value);
MergeIntoSuccessorEnvironment(entry.target_offset); MergeIntoSuccessorEnvironment(entry.target_offset);
} }
NewIfFalse(); NewIfDefault();
} }
void BytecodeGraphBuilder::VisitSwitchOnSmiNoFeedback() {
PrepareEagerCheckpoint();
Node* acc = environment()->LookupAccumulator();
Node* acc_smi = NewNode(simplified()->CheckSmi(), acc);
BuildSwitchOnSmi(acc_smi);
} }
void BytecodeGraphBuilder::VisitStackCheck() { void BytecodeGraphBuilder::VisitStackCheck() {
......
...@@ -91,11 +91,16 @@ class BytecodeGraphBuilder { ...@@ -91,11 +91,16 @@ class BytecodeGraphBuilder {
// Helpers to create new control nodes. // Helpers to create new control nodes.
Node* NewIfTrue() { return NewNode(common()->IfTrue()); } Node* NewIfTrue() { return NewNode(common()->IfTrue()); }
Node* NewIfFalse() { return NewNode(common()->IfFalse()); } Node* NewIfFalse() { return NewNode(common()->IfFalse()); }
Node* NewIfValue(int32_t value) { return NewNode(common()->IfValue(value)); }
Node* NewIfDefault() { return NewNode(common()->IfDefault()); }
Node* NewMerge() { return NewNode(common()->Merge(1), true); } Node* NewMerge() { return NewNode(common()->Merge(1), true); }
Node* NewLoop() { return NewNode(common()->Loop(1), true); } Node* NewLoop() { return NewNode(common()->Loop(1), true); }
Node* NewBranch(Node* condition, BranchHint hint = BranchHint::kNone) { Node* NewBranch(Node* condition, BranchHint hint = BranchHint::kNone) {
return NewNode(common()->Branch(hint), condition); return NewNode(common()->Branch(hint), condition);
} }
Node* NewSwitch(Node* condition, int control_output_count) {
return NewNode(common()->Switch(control_output_count), condition);
}
// Creates a new Phi node having {count} input values. // Creates a new Phi node having {count} input values.
Node* NewPhi(int count, Node* input, Node* control); Node* NewPhi(int count, Node* input, Node* control);
...@@ -222,6 +227,8 @@ class BytecodeGraphBuilder { ...@@ -222,6 +227,8 @@ class BytecodeGraphBuilder {
void BuildJumpIfNotHole(); void BuildJumpIfNotHole();
void BuildJumpIfJSReceiver(); void BuildJumpIfJSReceiver();
void BuildSwitchOnSmi(Node* condition);
// Simulates control flow by forward-propagating environments. // Simulates control flow by forward-propagating environments.
void MergeIntoSuccessorEnvironment(int target_offset); void MergeIntoSuccessorEnvironment(int target_offset);
void BuildLoopHeaderEnvironment(int current_offset); void BuildLoopHeaderEnvironment(int current_offset);
......
...@@ -237,6 +237,15 @@ JumpTableTargetOffsets::iterator JumpTableTargetOffsets::end() const { ...@@ -237,6 +237,15 @@ JumpTableTargetOffsets::iterator JumpTableTargetOffsets::end() const {
return iterator(case_value_base_ + table_size_, table_start_ + table_size_, return iterator(case_value_base_ + table_size_, table_start_ + table_size_,
table_start_ + table_size_, accessor_); table_start_ + table_size_, accessor_);
} }
int JumpTableTargetOffsets::size() const {
int ret = 0;
// TODO(leszeks): Is there a more efficient way of doing this than iterating?
for (const auto& entry : *this) {
USE(entry);
ret++;
}
return ret;
}
JumpTableTargetOffsets::iterator::iterator( JumpTableTargetOffsets::iterator::iterator(
int case_value, int table_offset, int table_end, int case_value, int table_offset, int table_end,
......
...@@ -51,6 +51,8 @@ class V8_EXPORT_PRIVATE JumpTableTargetOffsets final { ...@@ -51,6 +51,8 @@ class V8_EXPORT_PRIVATE JumpTableTargetOffsets final {
iterator begin() const; iterator begin() const;
iterator end() const; iterator end() const;
int size() const;
private: private:
const BytecodeArrayAccessor* accessor_; const BytecodeArrayAccessor* accessor_;
int table_start_; int table_start_;
......
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