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

Side by Side Diff: src/compiler/js-inlining.cc

Issue 988423004: [turbofan] Context specialize during inlining. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Ben's idea. Created 5 years, 9 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 | « no previous file | test/cctest/compiler/test-run-inlining.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/js-inlining.h" 5 #include "src/compiler/js-inlining.h"
6 6
7 #include "src/ast.h" 7 #include "src/ast.h"
8 #include "src/ast-numbering.h" 8 #include "src/ast-numbering.h"
9 #include "src/compiler/all-nodes.h" 9 #include "src/compiler/all-nodes.h"
10 #include "src/compiler/ast-graph-builder.h" 10 #include "src/compiler/ast-graph-builder.h"
11 #include "src/compiler/common-operator.h" 11 #include "src/compiler/common-operator.h"
12 #include "src/compiler/js-context-specialization.h"
12 #include "src/compiler/js-operator.h" 13 #include "src/compiler/js-operator.h"
13 #include "src/compiler/node-matchers.h" 14 #include "src/compiler/node-matchers.h"
14 #include "src/compiler/node-properties.h" 15 #include "src/compiler/node-properties.h"
15 #include "src/compiler/operator-properties.h" 16 #include "src/compiler/operator-properties.h"
16 #include "src/full-codegen.h" 17 #include "src/full-codegen.h"
17 #include "src/parser.h" 18 #include "src/parser.h"
18 #include "src/rewriter.h" 19 #include "src/rewriter.h"
19 #include "src/scopes.h" 20 #include "src/scopes.h"
20 21
21 namespace v8 { 22 namespace v8 {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 size_t total_parameters() { return start_->op()->ValueOutputCount(); } 93 size_t total_parameters() { return start_->op()->ValueOutputCount(); }
93 94
94 // Counts only formal parameters. 95 // Counts only formal parameters.
95 size_t formal_parameters() { 96 size_t formal_parameters() {
96 DCHECK_GE(total_parameters(), 3u); 97 DCHECK_GE(total_parameters(), 3u);
97 return total_parameters() - 3; 98 return total_parameters() - 3;
98 } 99 }
99 100
100 // Inline this graph at {call}, use {jsgraph} and its zone to create 101 // Inline this graph at {call}, use {jsgraph} and its zone to create
101 // any new nodes. 102 // any new nodes.
102 Reduction InlineAtCall(JSGraph* jsgraph, Node* call, Node* context); 103 Reduction InlineAtCall(JSGraph* jsgraph, Node* call);
103 104
104 // Ensure that only a single return reaches the end node. 105 // Ensure that only a single return reaches the end node.
105 static void UnifyReturn(JSGraph* jsgraph); 106 static void UnifyReturn(JSGraph* jsgraph);
106 107
107 private: 108 private:
108 Node* start_; 109 Node* start_;
109 Node* end_; 110 Node* end_;
110 }; 111 };
111 112
112 113
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 private: 206 private:
206 Operator const sentinel_op_; 207 Operator const sentinel_op_;
207 Node* const sentinel_; 208 Node* const sentinel_;
208 NodeVector copies_; 209 NodeVector copies_;
209 Graph* const source_graph_; 210 Graph* const source_graph_;
210 Graph* const target_graph_; 211 Graph* const target_graph_;
211 Zone* const temp_zone_; 212 Zone* const temp_zone_;
212 }; 213 };
213 214
214 215
215 Reduction Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call, Node* context) { 216 Reduction Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call) {
216 // The scheduler is smart enough to place our code; we just ensure {control} 217 // The scheduler is smart enough to place our code; we just ensure {control}
217 // becomes the control input of the start of the inlinee, and {effect} becomes 218 // becomes the control input of the start of the inlinee, and {effect} becomes
218 // the effect input of the start of the inlinee. 219 // the effect input of the start of the inlinee.
219 Node* control = NodeProperties::GetControlInput(call); 220 Node* control = NodeProperties::GetControlInput(call);
220 Node* effect = NodeProperties::GetEffectInput(call); 221 Node* effect = NodeProperties::GetEffectInput(call);
221 222
222 // Context is last argument. 223 // Context is last argument.
223 int inlinee_context_index = static_cast<int>(total_parameters()) - 1; 224 int inlinee_context_index = static_cast<int>(total_parameters()) - 1;
224 // {inliner_inputs} counts JSFunction, Receiver, arguments, but not 225 // {inliner_inputs} counts JSFunction, Receiver, arguments, but not
225 // context, effect, control. 226 // context, effect, control.
226 int inliner_inputs = call->op()->ValueInputCount(); 227 int inliner_inputs = call->op()->ValueInputCount();
227 // Iterate over all uses of the start node. 228 // Iterate over all uses of the start node.
228 for (Edge edge : start_->use_edges()) { 229 for (Edge edge : start_->use_edges()) {
229 Node* use = edge.from(); 230 Node* use = edge.from();
230 switch (use->opcode()) { 231 switch (use->opcode()) {
231 case IrOpcode::kParameter: { 232 case IrOpcode::kParameter: {
232 int index = 1 + OpParameter<int>(use->op()); 233 int index = 1 + OpParameter<int>(use->op());
233 if (index < inliner_inputs && index < inlinee_context_index) { 234 if (index < inliner_inputs && index < inlinee_context_index) {
234 // There is an input from the call, and the index is a value 235 // There is an input from the call, and the index is a value
235 // projection but not the context, so rewire the input. 236 // projection but not the context, so rewire the input.
236 NodeProperties::ReplaceWithValue(use, call->InputAt(index)); 237 NodeProperties::ReplaceWithValue(use, call->InputAt(index));
237 } else if (index == inlinee_context_index) { 238 } else if (index == inlinee_context_index) {
238 // This is the context projection, rewire it to the context from the 239 // TODO(turbofan): We always context specialize inlinees currently, so
239 // JSFunction object. 240 // we should never get here.
240 NodeProperties::ReplaceWithValue(use, context); 241 UNREACHABLE();
241 } else if (index < inlinee_context_index) { 242 } else if (index < inlinee_context_index) {
242 // Call has fewer arguments than required, fill with undefined. 243 // Call has fewer arguments than required, fill with undefined.
243 NodeProperties::ReplaceWithValue(use, jsgraph->UndefinedConstant()); 244 NodeProperties::ReplaceWithValue(use, jsgraph->UndefinedConstant());
244 } else { 245 } else {
245 // We got too many arguments, discard for now. 246 // We got too many arguments, discard for now.
246 // TODO(sigurds): Fix to treat arguments array correctly. 247 // TODO(sigurds): Fix to treat arguments array correctly.
247 } 248 }
248 break; 249 break;
249 } 250 }
250 default: 251 default:
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 if (FLAG_trace_turbo_inlining) { 335 if (FLAG_trace_turbo_inlining) {
335 SmartArrayPointer<char> name = function->shared()->DebugName()->ToCString(); 336 SmartArrayPointer<char> name = function->shared()->DebugName()->ToCString();
336 PrintF("Inlining %s into %s\n", name.get(), 337 PrintF("Inlining %s into %s\n", name.get(),
337 info_->shared_info()->DebugName()->ToCString().get()); 338 info_->shared_info()->DebugName()->ToCString().get());
338 } 339 }
339 340
340 Graph graph(info.zone()); 341 Graph graph(info.zone());
341 JSGraph jsgraph(info.isolate(), &graph, jsgraph_->common(), 342 JSGraph jsgraph(info.isolate(), &graph, jsgraph_->common(),
342 jsgraph_->javascript(), jsgraph_->machine()); 343 jsgraph_->javascript(), jsgraph_->machine());
343 344
345 // The inlinee specializes to the context from the JSFunction object.
346 // TODO(turbofan): We might want to load the context from the JSFunction at
347 // runtime in case we only know the SharedFunctionInfo once we have dynamic
348 // type feedback in the compiler.
344 AstGraphBuilder graph_builder(local_zone_, &info, &jsgraph); 349 AstGraphBuilder graph_builder(local_zone_, &info, &jsgraph);
345 graph_builder.CreateGraph(false, false); 350 graph_builder.CreateGraph(true, false);
titzer 2015/03/10 08:16:21 Can we context specialization a flag to the inline
351 JSContextSpecializer context_specializer(&jsgraph);
352 GraphReducer graph_reducer(&graph, local_zone_);
353 graph_reducer.AddReducer(&context_specializer);
354 graph_reducer.ReduceGraph();
346 Inlinee::UnifyReturn(&jsgraph); 355 Inlinee::UnifyReturn(&jsgraph);
347 356
348 CopyVisitor visitor(&graph, jsgraph_->graph(), info.zone()); 357 CopyVisitor visitor(&graph, jsgraph_->graph(), info.zone());
349 visitor.CopyGraph(); 358 visitor.CopyGraph();
350 359
351 Inlinee inlinee(visitor.GetCopy(graph.start()), visitor.GetCopy(graph.end())); 360 Inlinee inlinee(visitor.GetCopy(graph.start()), visitor.GetCopy(graph.end()));
352 361
353 if (FLAG_turbo_deoptimization) { 362 if (FLAG_turbo_deoptimization) {
354 Node* outer_frame_state = call.frame_state(); 363 Node* outer_frame_state = call.frame_state();
355 // Insert argument adaptor frame if required. 364 // Insert argument adaptor frame if required.
356 if (call.formal_arguments() != inlinee.formal_parameters()) { 365 if (call.formal_arguments() != inlinee.formal_parameters()) {
357 outer_frame_state = 366 outer_frame_state =
358 CreateArgumentsAdaptorFrameState(&call, function, info.zone()); 367 CreateArgumentsAdaptorFrameState(&call, function, info.zone());
359 } 368 }
360 369
361 for (Node* node : visitor.copies()) { 370 for (Node* node : visitor.copies()) {
362 if (node && node->opcode() == IrOpcode::kFrameState) { 371 if (node && node->opcode() == IrOpcode::kFrameState) {
363 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op())); 372 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
364 AddClosureToFrameState(node, function); 373 AddClosureToFrameState(node, function);
365 NodeProperties::ReplaceFrameStateInput(node, 0, outer_frame_state); 374 NodeProperties::ReplaceFrameStateInput(node, 0, outer_frame_state);
366 } 375 }
367 } 376 }
368 } 377 }
369 378
370 // The inlinee uses the context from the JSFunction object. 379 return inlinee.InlineAtCall(jsgraph_, node);
371 // TODO(turbofan): We might want to load the context from the JSFunction at
372 // runtime in case we only know the SharedFunctionInfo once we have dynamic
373 // type feedback in the compiler.
374 Node* context = jsgraph_->HeapConstant(handle(function->context()));
375
376 return inlinee.InlineAtCall(jsgraph_, node, context);
377 } 380 }
378 381
379 } // namespace compiler 382 } // namespace compiler
380 } // namespace internal 383 } // namespace internal
381 } // namespace v8 384 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/cctest/compiler/test-run-inlining.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698