Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: src/compiler/osr.cc

Issue 2384113002: [turbofan] Osr value typing + dynamic type checks on entry. (Closed)
Patch Set: Fix liveness block Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/opcodes.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/osr.h" 5 #include "src/compiler/osr.h"
6 #include "src/ast/scopes.h" 6 #include "src/ast/scopes.h"
7 #include "src/compilation-info.h" 7 #include "src/compilation-info.h"
8 #include "src/compiler/all-nodes.h" 8 #include "src/compiler/all-nodes.h"
9 #include "src/compiler/common-operator-reducer.h" 9 #include "src/compiler/common-operator-reducer.h"
10 #include "src/compiler/common-operator.h" 10 #include "src/compiler/common-operator.h"
(...skipping 29 matching lines...) Expand all
40 #define TRACE_COND (FLAG_trace_turbo_graph && FLAG_trace_osr) 40 #define TRACE_COND (FLAG_trace_turbo_graph && FLAG_trace_osr)
41 #else 41 #else
42 #define TRACE_COND false 42 #define TRACE_COND false
43 #endif 43 #endif
44 44
45 #define TRACE(...) \ 45 #define TRACE(...) \
46 do { \ 46 do { \
47 if (TRACE_COND) PrintF(__VA_ARGS__); \ 47 if (TRACE_COND) PrintF(__VA_ARGS__); \
48 } while (false) 48 } while (false)
49 49
50 namespace {
50 51
51 // Peel outer loops and rewire the graph so that control reduction can 52 // Peel outer loops and rewire the graph so that control reduction can
52 // produce a properly formed graph. 53 // produce a properly formed graph.
53 static void PeelOuterLoopsForOsr(Graph* graph, CommonOperatorBuilder* common, 54 void PeelOuterLoopsForOsr(Graph* graph, CommonOperatorBuilder* common,
54 Zone* tmp_zone, Node* dead, 55 Zone* tmp_zone, Node* dead, LoopTree* loop_tree,
55 LoopTree* loop_tree, LoopTree::Loop* osr_loop, 56 LoopTree::Loop* osr_loop, Node* osr_normal_entry,
56 Node* osr_normal_entry, Node* osr_loop_entry) { 57 Node* osr_loop_entry) {
57 const size_t original_count = graph->NodeCount(); 58 const size_t original_count = graph->NodeCount();
58 AllNodes all(tmp_zone, graph); 59 AllNodes all(tmp_zone, graph);
59 NodeVector tmp_inputs(tmp_zone); 60 NodeVector tmp_inputs(tmp_zone);
60 Node* sentinel = graph->NewNode(dead->op()); 61 Node* sentinel = graph->NewNode(dead->op());
61 62
62 // Make a copy of the graph for each outer loop. 63 // Make a copy of the graph for each outer loop.
63 ZoneVector<NodeVector*> copies(tmp_zone); 64 ZoneVector<NodeVector*> copies(tmp_zone);
64 for (LoopTree::Loop* loop = osr_loop->parent(); loop; loop = loop->parent()) { 65 for (LoopTree::Loop* loop = osr_loop->parent(); loop; loop = loop->parent()) {
65 void* stuff = tmp_zone->New(sizeof(NodeVector)); 66 void* stuff = tmp_zone->New(sizeof(NodeVector));
66 NodeVector* mapping = 67 NodeVector* mapping =
(...skipping 19 matching lines...) Expand all
86 87
87 // Copy all nodes. 88 // Copy all nodes.
88 for (size_t i = 0; i < all.reachable.size(); i++) { 89 for (size_t i = 0; i < all.reachable.size(); i++) {
89 Node* orig = all.reachable[i]; 90 Node* orig = all.reachable[i];
90 Node* copy = mapping->at(orig->id()); 91 Node* copy = mapping->at(orig->id());
91 if (copy != sentinel) { 92 if (copy != sentinel) {
92 // Mapping already exists. 93 // Mapping already exists.
93 continue; 94 continue;
94 } 95 }
95 if (orig->InputCount() == 0 || orig->opcode() == IrOpcode::kParameter || 96 if (orig->InputCount() == 0 || orig->opcode() == IrOpcode::kParameter ||
96 orig->opcode() == IrOpcode::kOsrValue) { 97 orig->opcode() == IrOpcode::kOsrValue ||
98 orig->opcode() == IrOpcode::kOsrGuard) {
97 // No need to copy leaf nodes or parameters. 99 // No need to copy leaf nodes or parameters.
98 mapping->at(orig->id()) = orig; 100 mapping->at(orig->id()) = orig;
99 continue; 101 continue;
100 } 102 }
101 103
102 // Copy the node. 104 // Copy the node.
103 tmp_inputs.clear(); 105 tmp_inputs.clear();
104 for (Node* input : orig->inputs()) { 106 for (Node* input : orig->inputs()) {
105 tmp_inputs.push_back(mapping->at(input->id())); 107 tmp_inputs.push_back(mapping->at(input->id()));
106 } 108 }
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 } 250 }
249 } 251 }
250 252
251 if (FLAG_trace_turbo_graph) { // Simple textual RPO. 253 if (FLAG_trace_turbo_graph) { // Simple textual RPO.
252 OFStream os(stdout); 254 OFStream os(stdout);
253 os << "-- Graph after OSR duplication -- " << std::endl; 255 os << "-- Graph after OSR duplication -- " << std::endl;
254 os << AsRPO(*graph); 256 os << AsRPO(*graph);
255 } 257 }
256 } 258 }
257 259
260 void SetTypeForOsrValue(Node* osr_value, Node* loop,
261 CommonOperatorBuilder* common) {
262 Node* osr_guard = nullptr;
263 for (Node* use : osr_value->uses()) {
264 if (use->opcode() == IrOpcode::kOsrGuard) {
265 DCHECK_EQ(use->InputAt(0), osr_value);
266 osr_guard = use;
267 break;
268 }
269 }
270
271 OsrGuardType guard_type = OsrGuardType::kAny;
272 // Find the phi that uses the OsrGuard node and get the type from
273 // there. Skip the search if the OsrGuard does not have value use
274 // (i.e., if there is other use beyond the effect use).
275 if (osr_guard->UseCount() > 1) {
276 Type* type = nullptr;
277 for (Node* use : osr_guard->uses()) {
278 if (use->opcode() == IrOpcode::kPhi) {
279 if (NodeProperties::GetControlInput(use) != loop) continue;
280 CHECK_NULL(type);
281 type = NodeProperties::GetType(use);
282 }
283 }
284 CHECK_NOT_NULL(type);
285
286 if (type->Is(Type::SignedSmall())) {
287 guard_type = OsrGuardType::kSignedSmall;
288 }
289 }
290
291 NodeProperties::ChangeOp(osr_guard, common->OsrGuard(guard_type));
292 }
293
294 } // namespace
258 295
259 void OsrHelper::Deconstruct(JSGraph* jsgraph, CommonOperatorBuilder* common, 296 void OsrHelper::Deconstruct(JSGraph* jsgraph, CommonOperatorBuilder* common,
260 Zone* tmp_zone) { 297 Zone* tmp_zone) {
261 Graph* graph = jsgraph->graph(); 298 Graph* graph = jsgraph->graph();
262 Node* osr_normal_entry = nullptr; 299 Node* osr_normal_entry = nullptr;
263 Node* osr_loop_entry = nullptr; 300 Node* osr_loop_entry = nullptr;
264 Node* osr_loop = nullptr; 301 Node* osr_loop = nullptr;
265 302
266 for (Node* node : graph->start()->uses()) { 303 for (Node* node : graph->start()->uses()) {
267 if (node->opcode() == IrOpcode::kOsrLoopEntry) { 304 if (node->opcode() == IrOpcode::kOsrLoopEntry) {
268 osr_loop_entry = node; // found the OSR loop entry 305 osr_loop_entry = node; // found the OSR loop entry
269 } else if (node->opcode() == IrOpcode::kOsrNormalEntry) { 306 } else if (node->opcode() == IrOpcode::kOsrNormalEntry) {
270 osr_normal_entry = node; 307 osr_normal_entry = node;
271 } 308 }
272 } 309 }
273 310
274 CHECK_NOT_NULL(osr_normal_entry); // Should have found the OSR normal entry. 311 CHECK_NOT_NULL(osr_normal_entry); // Should have found the OSR normal entry.
275 CHECK_NOT_NULL(osr_loop_entry); // Should have found the OSR loop entry. 312 CHECK_NOT_NULL(osr_loop_entry); // Should have found the OSR loop entry.
276 313
277 for (Node* use : osr_loop_entry->uses()) { 314 for (Node* use : osr_loop_entry->uses()) {
278 if (use->opcode() == IrOpcode::kLoop) { 315 if (use->opcode() == IrOpcode::kLoop) {
279 CHECK(!osr_loop); // should be only one OSR loop. 316 CHECK(!osr_loop); // should be only one OSR loop.
280 osr_loop = use; // found the OSR loop. 317 osr_loop = use; // found the OSR loop.
281 } 318 }
282 } 319 }
283 320
284 CHECK(osr_loop); // Should have found the OSR loop. 321 CHECK(osr_loop); // Should have found the OSR loop.
285 322
323 for (Node* use : osr_loop_entry->uses()) {
324 if (use->opcode() == IrOpcode::kOsrValue) {
325 SetTypeForOsrValue(use, osr_loop, common);
326 }
327 }
328
286 // Analyze the graph to determine how deeply nested the OSR loop is. 329 // Analyze the graph to determine how deeply nested the OSR loop is.
287 LoopTree* loop_tree = LoopFinder::BuildLoopTree(graph, tmp_zone); 330 LoopTree* loop_tree = LoopFinder::BuildLoopTree(graph, tmp_zone);
288 331
289 Node* dead = jsgraph->Dead(); 332 Node* dead = jsgraph->Dead();
290 LoopTree::Loop* loop = loop_tree->ContainingLoop(osr_loop); 333 LoopTree::Loop* loop = loop_tree->ContainingLoop(osr_loop);
291 if (loop->depth() > 0) { 334 if (loop->depth() > 0) {
292 PeelOuterLoopsForOsr(graph, common, tmp_zone, dead, loop_tree, loop, 335 PeelOuterLoopsForOsr(graph, common, tmp_zone, dead, loop_tree, loop,
293 osr_normal_entry, osr_loop_entry); 336 osr_normal_entry, osr_loop_entry);
294 } 337 }
295 338
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 375
333 void OsrHelper::SetupFrame(Frame* frame) { 376 void OsrHelper::SetupFrame(Frame* frame) {
334 // The optimized frame will subsume the unoptimized frame. Do so by reserving 377 // The optimized frame will subsume the unoptimized frame. Do so by reserving
335 // the first spill slots. 378 // the first spill slots.
336 frame->ReserveSpillSlots(UnoptimizedFrameSlots()); 379 frame->ReserveSpillSlots(UnoptimizedFrameSlots());
337 } 380 }
338 381
339 } // namespace compiler 382 } // namespace compiler
340 } // namespace internal 383 } // namespace internal
341 } // namespace v8 384 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/opcodes.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698