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

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

Issue 1135483004: [turbofan] Add AdvancedReducer::ReplaceWithValue() method and convert JSInlining to an AdvancedRedu… (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 7 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/js-inlining.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/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"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 return value_inputs - 2; 52 return value_inputs - 2;
53 } 53 }
54 54
55 Node* frame_state() { return NodeProperties::GetFrameStateInput(call_, 0); } 55 Node* frame_state() { return NodeProperties::GetFrameStateInput(call_, 0); }
56 56
57 private: 57 private:
58 Node* call_; 58 Node* call_;
59 }; 59 };
60 60
61 61
62 namespace {
63
64 // A facade on a JSFunction's graph to facilitate inlining. It assumes 62 // A facade on a JSFunction's graph to facilitate inlining. It assumes
65 // that the function graph has only one return statement, and provides 63 // that the function graph has only one return statement, and provides
66 // {UnifyReturn} to convert a function graph to that end. 64 // {UnifyReturn} to convert a function graph to that end.
67 class Inlinee { 65 struct Inlinee {
68 public:
69 Inlinee(Node* start, Node* end) : start_(start), end_(end) {} 66 Inlinee(Node* start, Node* end) : start_(start), end_(end) {}
70 67
71 // Returns the last regular control node, that is 68 // Returns the last regular control node, that is
72 // the last control node before the end node. 69 // the last control node before the end node.
73 Node* end_block() { return NodeProperties::GetControlInput(unique_return()); } 70 Node* end_block() { return NodeProperties::GetControlInput(unique_return()); }
74 71
75 // Return the effect output of the graph, 72 // Return the effect output of the graph,
76 // that is the effect input of the return statement of the inlinee. 73 // that is the effect input of the return statement of the inlinee.
77 Node* effect_output() { 74 Node* effect_output() {
78 return NodeProperties::GetEffectInput(unique_return()); 75 return NodeProperties::GetEffectInput(unique_return());
(...skipping 17 matching lines...) Expand all
96 93
97 // Counts JSFunction, Receiver, arguments, context but not effect, control. 94 // Counts JSFunction, Receiver, arguments, context but not effect, control.
98 size_t total_parameters() { return start_->op()->ValueOutputCount(); } 95 size_t total_parameters() { return start_->op()->ValueOutputCount(); }
99 96
100 // Counts only formal parameters. 97 // Counts only formal parameters.
101 size_t formal_parameters() { 98 size_t formal_parameters() {
102 DCHECK_GE(total_parameters(), 3u); 99 DCHECK_GE(total_parameters(), 3u);
103 return total_parameters() - 3; 100 return total_parameters() - 3;
104 } 101 }
105 102
106 // Inline this graph at {call}, use {jsgraph} and its zone to create
107 // any new nodes.
108 Reduction InlineAtCall(JSGraph* jsgraph, Node* call);
109
110 // Ensure that only a single return reaches the end node. 103 // Ensure that only a single return reaches the end node.
111 static void UnifyReturn(JSGraph* jsgraph); 104 static void UnifyReturn(JSGraph* jsgraph);
112 105
113 private:
114 Node* start_; 106 Node* start_;
115 Node* end_; 107 Node* end_;
116 }; 108 };
117 109
118 110
119 void Inlinee::UnifyReturn(JSGraph* jsgraph) { 111 void Inlinee::UnifyReturn(JSGraph* jsgraph) {
120 Graph* graph = jsgraph->graph(); 112 Graph* graph = jsgraph->graph();
121 113
122 Node* final_merge = NodeProperties::GetControlInput(graph->end(), 0); 114 Node* final_merge = NodeProperties::GetControlInput(graph->end(), 0);
123 if (final_merge->opcode() == IrOpcode::kReturn) { 115 if (final_merge->opcode() == IrOpcode::kReturn) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 private: 203 private:
212 Operator const sentinel_op_; 204 Operator const sentinel_op_;
213 Node* const sentinel_; 205 Node* const sentinel_;
214 NodeVector copies_; 206 NodeVector copies_;
215 Graph* const source_graph_; 207 Graph* const source_graph_;
216 Graph* const target_graph_; 208 Graph* const target_graph_;
217 Zone* const temp_zone_; 209 Zone* const temp_zone_;
218 }; 210 };
219 211
220 212
221 Reduction Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call) { 213 Reduction JSInliner::InlineCall(Node* call, Inlinee& inlinee) {
222 // The scheduler is smart enough to place our code; we just ensure {control} 214 // The scheduler is smart enough to place our code; we just ensure {control}
223 // becomes the control input of the start of the inlinee, and {effect} becomes 215 // becomes the control input of the start of the inlinee, and {effect} becomes
224 // the effect input of the start of the inlinee. 216 // the effect input of the start of the inlinee.
225 Node* control = NodeProperties::GetControlInput(call); 217 Node* control = NodeProperties::GetControlInput(call);
226 Node* effect = NodeProperties::GetEffectInput(call); 218 Node* effect = NodeProperties::GetEffectInput(call);
227 219
228 // Context is last argument. 220 // Context is last argument.
229 int inlinee_context_index = static_cast<int>(total_parameters()) - 1; 221 int inlinee_context_index = static_cast<int>(inlinee.total_parameters()) - 1;
230 // {inliner_inputs} counts JSFunction, Receiver, arguments, but not 222 // {inliner_inputs} counts JSFunction, Receiver, arguments, but not
231 // context, effect, control. 223 // context, effect, control.
232 int inliner_inputs = call->op()->ValueInputCount(); 224 int inliner_inputs = call->op()->ValueInputCount();
233 // Iterate over all uses of the start node. 225 // Iterate over all uses of the start node.
234 for (Edge edge : start_->use_edges()) { 226 for (Edge edge : inlinee.start_->use_edges()) {
235 Node* use = edge.from(); 227 Node* use = edge.from();
236 switch (use->opcode()) { 228 switch (use->opcode()) {
237 case IrOpcode::kParameter: { 229 case IrOpcode::kParameter: {
238 int index = 1 + ParameterIndexOf(use->op()); 230 int index = 1 + ParameterIndexOf(use->op());
239 if (index < inliner_inputs && index < inlinee_context_index) { 231 if (index < inliner_inputs && index < inlinee_context_index) {
240 // There is an input from the call, and the index is a value 232 // There is an input from the call, and the index is a value
241 // projection but not the context, so rewire the input. 233 // projection but not the context, so rewire the input.
242 NodeProperties::ReplaceWithValue(use, call->InputAt(index)); 234 ReplaceWithValue(use, call->InputAt(index));
243 } else if (index == inlinee_context_index) { 235 } else if (index == inlinee_context_index) {
244 // TODO(turbofan): We always context specialize inlinees currently, so 236 // TODO(turbofan): We always context specialize inlinees currently, so
245 // we should never get here. 237 // we should never get here.
246 UNREACHABLE(); 238 UNREACHABLE();
247 } else if (index < inlinee_context_index) { 239 } else if (index < inlinee_context_index) {
248 // Call has fewer arguments than required, fill with undefined. 240 // Call has fewer arguments than required, fill with undefined.
249 NodeProperties::ReplaceWithValue(use, jsgraph->UndefinedConstant()); 241 ReplaceWithValue(use, jsgraph_->UndefinedConstant());
250 } else { 242 } else {
251 // We got too many arguments, discard for now. 243 // We got too many arguments, discard for now.
252 // TODO(sigurds): Fix to treat arguments array correctly. 244 // TODO(sigurds): Fix to treat arguments array correctly.
253 } 245 }
254 break; 246 break;
255 } 247 }
256 default: 248 default:
257 if (NodeProperties::IsEffectEdge(edge)) { 249 if (NodeProperties::IsEffectEdge(edge)) {
258 edge.UpdateTo(effect); 250 edge.UpdateTo(effect);
259 } else if (NodeProperties::IsControlEdge(edge)) { 251 } else if (NodeProperties::IsControlEdge(edge)) {
260 edge.UpdateTo(control); 252 edge.UpdateTo(control);
261 } else { 253 } else {
262 UNREACHABLE(); 254 UNREACHABLE();
263 } 255 }
264 break; 256 break;
265 } 257 }
266 } 258 }
267 259
268 NodeProperties::ReplaceWithValue(call, value_output(), effect_output(), 260 ReplaceWithValue(call, inlinee.value_output(), inlinee.effect_output(),
269 control_output()); 261 inlinee.control_output());
270 262
271 return Reducer::Replace(value_output()); 263 return Replace(inlinee.value_output());
272 } 264 }
273 265
274 } // namespace
275
276 266
277 void JSInliner::AddClosureToFrameState(Node* frame_state, 267 void JSInliner::AddClosureToFrameState(Node* frame_state,
278 Handle<JSFunction> jsfunction) { 268 Handle<JSFunction> jsfunction) {
279 FrameStateCallInfo call_info = OpParameter<FrameStateCallInfo>(frame_state); 269 FrameStateCallInfo call_info = OpParameter<FrameStateCallInfo>(frame_state);
280 const Operator* op = jsgraph_->common()->FrameState( 270 const Operator* op = jsgraph_->common()->FrameState(
281 FrameStateType::JS_FRAME, call_info.bailout_id(), 271 FrameStateType::JS_FRAME, call_info.bailout_id(),
282 call_info.state_combine(), jsfunction); 272 call_info.state_combine(), jsfunction);
283 frame_state->set_op(op); 273 frame_state->set_op(op);
284 } 274 }
285 275
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 } 364 }
375 365
376 for (Node* node : visitor.copies()) { 366 for (Node* node : visitor.copies()) {
377 if (node && node->opcode() == IrOpcode::kFrameState) { 367 if (node && node->opcode() == IrOpcode::kFrameState) {
378 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op())); 368 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
379 AddClosureToFrameState(node, function); 369 AddClosureToFrameState(node, function);
380 NodeProperties::ReplaceFrameStateInput(node, 0, outer_frame_state); 370 NodeProperties::ReplaceFrameStateInput(node, 0, outer_frame_state);
381 } 371 }
382 } 372 }
383 373
384 return inlinee.InlineAtCall(jsgraph_, node); 374 return InlineCall(node, inlinee);
385 } 375 }
386 376
387 } // namespace compiler 377 } // namespace compiler
388 } // namespace internal 378 } // namespace internal
389 } // namespace v8 379 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-inlining.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698