diff options
Diffstat (limited to 'deps/v8/src/compiler/graph-assembler.cc')
-rw-r--r-- | deps/v8/src/compiler/graph-assembler.cc | 96 |
1 files changed, 85 insertions, 11 deletions
diff --git a/deps/v8/src/compiler/graph-assembler.cc b/deps/v8/src/compiler/graph-assembler.cc index 246bf1e2291..6057f1ce649 100644 --- a/deps/v8/src/compiler/graph-assembler.cc +++ b/deps/v8/src/compiler/graph-assembler.cc @@ -19,7 +19,8 @@ namespace compiler { class GraphAssembler::BasicBlockUpdater { public: - BasicBlockUpdater(Schedule* schedule, Graph* graph, Zone* temp_zone); + BasicBlockUpdater(Schedule* schedule, Graph* graph, + CommonOperatorBuilder* common, Zone* temp_zone); Node* AddNode(Node* node); Node* AddNode(Node* node, BasicBlock* to); @@ -48,6 +49,7 @@ class GraphAssembler::BasicBlockUpdater { bool IsOriginalNode(Node* node); void UpdateSuccessors(BasicBlock* block); void SetBlockDeferredFromPredecessors(); + void RemoveSuccessorsFromSchedule(); void CopyForChange(); Zone* temp_zone_; @@ -64,6 +66,7 @@ class GraphAssembler::BasicBlockUpdater { Schedule* schedule_; Graph* graph_; + CommonOperatorBuilder* common_; // The nodes in the original block if we are in 'changed' state. Retained to // avoid invalidating iterators that are iterating over the original nodes of @@ -85,14 +88,15 @@ class GraphAssembler::BasicBlockUpdater { State state_; }; -GraphAssembler::BasicBlockUpdater::BasicBlockUpdater(Schedule* schedule, - Graph* graph, - Zone* temp_zone) +GraphAssembler::BasicBlockUpdater::BasicBlockUpdater( + Schedule* schedule, Graph* graph, CommonOperatorBuilder* common, + Zone* temp_zone) : temp_zone_(temp_zone), current_block_(nullptr), original_block_(nullptr), schedule_(schedule), graph_(graph), + common_(common), saved_nodes_(schedule->zone()), saved_successors_(schedule->zone()), original_control_(BasicBlock::kNone), @@ -264,11 +268,66 @@ void GraphAssembler::BasicBlockUpdater::AddGoto(BasicBlock* from, current_block_ = nullptr; } +void GraphAssembler::BasicBlockUpdater::RemoveSuccessorsFromSchedule() { + ZoneSet<BasicBlock*> blocks(temp_zone()); + ZoneQueue<BasicBlock*> worklist(temp_zone()); + + for (SuccessorInfo succ : saved_successors_) { + BasicBlock* block = succ.block; + block->predecessors().erase(block->predecessors().begin() + succ.index); + blocks.insert(block); + worklist.push(block); + } + saved_successors_.clear(); + + // Walk through blocks until we get to the end node, then remove the path from + // end, clearing their successors / predecessors. + // This works because the unreachable paths form self-contained control flow + // that doesn't re-merge with reachable control flow (checked below) and + // DeadCodeElimination::ReduceEffectPhi preventing Unreachable from going into + // an effect-phi. We would need to extend this if we need the ability to mark + // control flow as unreachable later in the pipeline. + while (!worklist.empty()) { + BasicBlock* current = worklist.front(); + worklist.pop(); + + for (BasicBlock* successor : current->successors()) { + // Remove the block from sucessors predecessors. + ZoneVector<BasicBlock*>& predecessors = successor->predecessors(); + auto it = std::find(predecessors.begin(), predecessors.end(), current); + DCHECK_EQ(*it, current); + predecessors.erase(it); + + if (successor == schedule_->end()) { + // If we have reached the end block, remove this block's control input + // from the end node's control inputs. + DCHECK_EQ(current->SuccessorCount(), 1); + NodeProperties::RemoveControlFromEnd(graph_, common_, + current->control_input()); + } else { + // Otherwise, add successor to worklist if it's not already been seen. + if (blocks.insert(successor).second) { + worklist.push(successor); + } + } + } + current->ClearSuccessors(); + } + +#ifdef DEBUG + // Ensure that the set of blocks being removed from the schedule are self + // contained, i.e., all predecessors have been removed from these blocks. + for (BasicBlock* block : blocks) { + CHECK_EQ(block->PredecessorCount(), 0); + CHECK_EQ(block->SuccessorCount(), 0); + } +#endif +} + void GraphAssembler::BasicBlockUpdater::AddThrow(Node* node) { if (state_ == kUnchanged) { CopyForChange(); } - schedule_->AddThrow(current_block_, node); // Clear original successors and replace the block's original control and // control input to the throw, since this block is now connected directly to @@ -280,10 +339,19 @@ void GraphAssembler::BasicBlockUpdater::AddThrow(Node* node) { original_control_input_ = node; original_control_ = BasicBlock::kThrow; - for (SuccessorInfo succ : saved_successors_) { - succ.block->RemovePredecessor(succ.index); + bool already_connected_to_end = + saved_successors_.size() == 1 && + saved_successors_[0].block == schedule_->end(); + if (!already_connected_to_end) { + // Remove all successor blocks from the schedule. + RemoveSuccessorsFromSchedule(); + + // Update current block's successor withend. + DCHECK(saved_successors_.empty()); + size_t index = schedule_->end()->predecessors().size(); + schedule_->end()->AddPredecessor(current_block_); + saved_successors_.push_back({schedule_->end(), index}); } - saved_successors_.clear(); } void GraphAssembler::BasicBlockUpdater::UpdateSuccessors(BasicBlock* block) { @@ -341,9 +409,10 @@ GraphAssembler::GraphAssembler(MachineGraph* mcgraph, Zone* zone, mcgraph_(mcgraph), effect_(nullptr), control_(nullptr), - block_updater_(schedule != nullptr ? new BasicBlockUpdater( - schedule, mcgraph->graph(), zone) - : nullptr), + block_updater_(schedule != nullptr + ? new BasicBlockUpdater(schedule, mcgraph->graph(), + mcgraph->common(), zone) + : nullptr), loop_headers_(zone), mark_loop_exits_(mark_loop_exits) {} @@ -590,6 +659,11 @@ TNode<Boolean> JSGraphAssembler::ObjectIsCallable(TNode<Object> value) { graph()->NewNode(simplified()->ObjectIsCallable(), value)); } +TNode<Boolean> JSGraphAssembler::ObjectIsUndetectable(TNode<Object> value) { + return AddNode<Boolean>( + graph()->NewNode(simplified()->ObjectIsUndetectable(), value)); +} + Node* JSGraphAssembler::CheckIf(Node* cond, DeoptimizeReason reason) { return AddNode(graph()->NewNode(simplified()->CheckIf(reason), cond, effect(), control())); |