Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/graph-assembler.cc')
-rw-r--r--deps/v8/src/compiler/graph-assembler.cc96
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()));