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

Side by Side Diff: runtime/vm/flow_graph_compiler_dbc.cc

Issue 1992963002: Enable optimizer pipeline for DBC. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 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
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_DBC. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_DBC.
6 #if defined(TARGET_ARCH_DBC) 6 #if defined(TARGET_ARCH_DBC)
7 7
8 #include "vm/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "vm/ast_printer.h" 10 #include "vm/ast_printer.h"
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 83
84 void FlowGraphCompiler::ExitIntrinsicMode() { 84 void FlowGraphCompiler::ExitIntrinsicMode() {
85 ASSERT(intrinsic_mode()); 85 ASSERT(intrinsic_mode());
86 intrinsic_mode_ = false; 86 intrinsic_mode_ = false;
87 } 87 }
88 88
89 89
90 RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler, 90 RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
91 DeoptInfoBuilder* builder, 91 DeoptInfoBuilder* builder,
92 const Array& deopt_table) { 92 const Array& deopt_table) {
93 UNIMPLEMENTED(); 93 if (deopt_env_ == NULL) {
94 return TypedData::null(); 94 ++builder->current_info_number_;
95 return TypedData::null();
96 }
97
98 intptr_t stack_height = compiler->StackSize();
99 AllocateIncomingParametersRecursive(deopt_env_, &stack_height);
100
101 intptr_t slot_ix = 0;
102 Environment* current = deopt_env_;
103
104 // Emit all kMaterializeObject instructions describing objects to be
105 // materialized on the deoptimization as a prefix to the deoptimization info.
106 EmitMaterializations(deopt_env_, builder);
107
108 // The real frame starts here.
109 builder->MarkFrameStart();
110
111 Zone* zone = compiler->zone();
112
113 builder->AddCallerFp(slot_ix++);
114 builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
115 builder->AddPcMarker(Function::ZoneHandle(zone), slot_ix++);
116 builder->AddConstant(Function::ZoneHandle(zone), slot_ix++);
117
118 // Emit all values that are needed for materialization as a part of the
119 // expression stack for the bottom-most frame. This guarantees that GC
120 // will be able to find them during materialization.
121 slot_ix = builder->EmitMaterializationArguments(slot_ix);
122
123 // For the innermost environment, set outgoing arguments and the locals.
124 for (intptr_t i = current->Length() - 1;
125 i >= current->fixed_parameter_count();
126 i--) {
127 builder->AddCopy(current->ValueAt(i), current->LocationAt(i), slot_ix++);
128 }
129
zra 2016/05/19 16:24:27 Extra newline.
Vyacheslav Egorov (Google) 2016/05/20 12:11:47 Done.
130
131 builder->AddCallerFp(slot_ix++);
132
133 Environment* previous = current;
134 current = current->outer();
135 while (current != NULL) {
136 // For any outer environment the deopt id is that of the call instruction
137 // which is recorded in the outer environment.
138 builder->AddReturnAddress(
139 current->function(),
140 Thread::ToDeoptAfter(current->deopt_id()),
141 slot_ix++);
142
143 builder->AddPcMarker(previous->function(), slot_ix++);
144 builder->AddConstant(previous->function(), slot_ix++);
145
146 // The values of outgoing arguments can be changed from the inlined call so
147 // we must read them from the previous environment.
148 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
149 builder->AddCopy(previous->ValueAt(i),
150 previous->LocationAt(i),
151 slot_ix++);
152 }
153
154 // Set the locals, note that outgoing arguments are not in the environment.
155 for (intptr_t i = current->Length() - 1;
156 i >= current->fixed_parameter_count();
157 i--) {
158 builder->AddCopy(current->ValueAt(i),
159 current->LocationAt(i),
160 slot_ix++);
161 }
162
163 builder->AddCallerFp(slot_ix++);
164
165 // Iterate on the outer environment.
166 previous = current;
167 current = current->outer();
168 }
169 // The previous pointer is now the outermost environment.
170 ASSERT(previous != NULL);
171
172 // For the outermost environment, set caller PC.
173 builder->AddCallerPc(slot_ix++);
174
175 builder->AddPcMarker(previous->function(), slot_ix++);
176 builder->AddConstant(previous->function(), slot_ix++);
177
178
179 // For the outermost environment, set the incoming arguments.
180 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
181 builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++);
182 }
183
184 return builder->CreateDeoptInfo(deopt_table);
95 } 185 }
96 186
97 187
188 void FlowGraphCompiler::RecordAfterCall(Instruction* instr) {
189 RecordSafepoint(instr->locs());
190 // Marks either the continuation point in unoptimized code or the
191 // deoptimization point in optimized code, after call.
192 const intptr_t deopt_id_after = Thread::ToDeoptAfter(instr->deopt_id());
193 if (is_optimizing()) {
194 // Return/ReturnTOS instruction drops incoming arguments so
195 // we have to drop outgoing arguments from the innermost environment.
196 // On all other architectures caller drops outgoing arguments itself
197 // hence the difference.
198 pending_deoptimization_env_->DropArguments(instr->ArgumentCount());
199 AddDeoptIndexAtCall(deopt_id_after, instr->token_pos());
200 } else {
201 // Add deoptimization continuation point after the call and before the
202 // arguments are removed.
203 // In optimized code this descriptor is needed for exception handling.
204 AddCurrentDescriptor(RawPcDescriptors::kDeopt,
205 deopt_id_after,
206 instr->token_pos());
207 }
208 }
209
210
98 void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler, 211 void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler,
99 intptr_t stub_ix) { 212 intptr_t stub_ix) {
100 UNIMPLEMENTED(); 213 UNIMPLEMENTED();
101 } 214 }
102 215
103 216
104 #define __ assembler()-> 217 #define __ assembler()->
105 218
106 219
107 void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos, 220 void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos,
108 intptr_t deopt_id, 221 intptr_t deopt_id,
109 const AbstractType& dst_type, 222 const AbstractType& dst_type,
110 const String& dst_name, 223 const String& dst_name,
111 LocationSummary* locs) { 224 LocationSummary* locs) {
112 ASSERT(!is_optimizing());
113 SubtypeTestCache& test_cache = SubtypeTestCache::Handle(); 225 SubtypeTestCache& test_cache = SubtypeTestCache::Handle();
114 if (!dst_type.IsVoidType() && dst_type.IsInstantiated()) { 226 if (!dst_type.IsVoidType() && dst_type.IsInstantiated()) {
115 test_cache = SubtypeTestCache::New(); 227 test_cache = SubtypeTestCache::New();
116 } 228 }
117 229
230 if (is_optimizing()) {
231 __ Push(locs->in(0).reg());
232 __ Push(locs->in(1).reg());
233 }
118 __ PushConstant(dst_type); 234 __ PushConstant(dst_type);
119 __ PushConstant(dst_name); 235 __ PushConstant(dst_name);
120 __ AssertAssignable(__ AddConstant(test_cache)); 236 __ AssertAssignable(__ AddConstant(test_cache));
237 RecordSafepoint(locs);
121 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos); 238 AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos);
239 if (is_optimizing()) {
240 __ Drop1();
Florian Schneider 2016/05/19 13:21:40 __ Drop(2)?
Vyacheslav Egorov (Google) 2016/05/19 15:19:40 Explained why Drop(1)
241 }
122 } 242 }
123 243
124 244
125 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) { 245 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
126 if (!is_optimizing()) { 246 if (!is_optimizing()) {
127 Definition* defn = instr->AsDefinition(); 247 Definition* defn = instr->AsDefinition();
128 if ((defn != NULL) && 248 if ((defn != NULL) &&
129 (defn->tag() != Instruction::kPushArgument) && 249 (defn->tag() != Instruction::kPushArgument) &&
130 (defn->tag() != Instruction::kStoreIndexed) && 250 (defn->tag() != Instruction::kStoreIndexed) &&
131 (defn->tag() != Instruction::kStoreStaticField) && 251 (defn->tag() != Instruction::kStoreStaticField) &&
(...skipping 29 matching lines...) Expand all
161 const int num_opt_pos_params = function.NumOptionalPositionalParameters(); 281 const int num_opt_pos_params = function.NumOptionalPositionalParameters();
162 const int num_opt_named_params = function.NumOptionalNamedParameters(); 282 const int num_opt_named_params = function.NumOptionalNamedParameters();
163 const int num_params = 283 const int num_params =
164 num_fixed_params + num_opt_pos_params + num_opt_named_params; 284 num_fixed_params + num_opt_pos_params + num_opt_named_params;
165 const bool has_optional_params = (num_opt_pos_params != 0) || 285 const bool has_optional_params = (num_opt_pos_params != 0) ||
166 (num_opt_named_params != 0); 286 (num_opt_named_params != 0);
167 const int num_locals = parsed_function().num_stack_locals(); 287 const int num_locals = parsed_function().num_stack_locals();
168 const intptr_t context_index = 288 const intptr_t context_index =
169 -parsed_function().current_context_var()->index() - 1; 289 -parsed_function().current_context_var()->index() - 1;
170 290
291 if (CanOptimizeFunction() &&
292 function.IsOptimizable() &&
293 (!is_optimizing() || may_reoptimize())) {
294 __ HotCheck(!is_optimizing(), GetOptimizationThreshold());
295 }
296
171 if (has_optional_params) { 297 if (has_optional_params) {
172 __ EntryOpt(num_fixed_params, num_opt_pos_params, num_opt_named_params); 298 __ EntryOptional(num_fixed_params,
299 num_opt_pos_params,
300 num_opt_named_params);
301 } else if (!is_optimizing()) {
302 __ Entry(num_fixed_params, num_locals, context_index);
173 } else { 303 } else {
174 __ Entry(num_fixed_params, num_locals, context_index); 304 __ EntryOptimized(num_fixed_params,
305 flow_graph_.graph_entry()->spill_slot_count());
175 } 306 }
176 307
177 if (num_opt_named_params != 0) { 308 if (num_opt_named_params != 0) {
178 LocalScope* scope = parsed_function().node_sequence()->scope(); 309 LocalScope* scope = parsed_function().node_sequence()->scope();
179 310
180 // Start by alphabetically sorting the names of the optional parameters. 311 // Start by alphabetically sorting the names of the optional parameters.
181 LocalVariable** opt_param = 312 LocalVariable** opt_param =
182 zone()->Alloc<LocalVariable*>(num_opt_named_params); 313 zone()->Alloc<LocalVariable*>(num_opt_named_params);
183 int* opt_param_position = zone()->Alloc<int>(num_opt_named_params); 314 int* opt_param_position = zone()->Alloc<int>(num_opt_named_params);
184 for (int pos = num_fixed_params; pos < num_params; pos++) { 315 for (int pos = num_fixed_params; pos < num_params; pos++) {
(...skipping 20 matching lines...) Expand all
205 __ LoadConstant(param_pos, value); 336 __ LoadConstant(param_pos, value);
206 } 337 }
207 } else if (num_opt_pos_params != 0) { 338 } else if (num_opt_pos_params != 0) {
208 for (intptr_t i = 0; i < num_opt_pos_params; i++) { 339 for (intptr_t i = 0; i < num_opt_pos_params; i++) {
209 const Object& value = parsed_function().DefaultParameterValueAt(i); 340 const Object& value = parsed_function().DefaultParameterValueAt(i);
210 __ LoadConstant(num_fixed_params + i, value); 341 __ LoadConstant(num_fixed_params + i, value);
211 } 342 }
212 } 343 }
213 344
214 345
215 ASSERT(num_locals > 0); // There is always at least context_var.
216 if (has_optional_params) { 346 if (has_optional_params) {
217 ASSERT(!is_optimizing()); 347 if (!is_optimizing()) {
218 __ Frame(num_locals); // Reserve space for locals. 348 ASSERT(num_locals > 0); // There is always at least context_var.
349 __ Frame(num_locals); // Reserve space for locals.
350 } else if (flow_graph_.graph_entry()->spill_slot_count() >
351 flow_graph_.num_copied_params()) {
352 __ Frame(flow_graph_.graph_entry()->spill_slot_count() -
353 flow_graph_.num_copied_params());
354 }
219 } 355 }
220 356
221 if (function.IsClosureFunction()) { 357 if (function.IsClosureFunction()) {
222 Register reg = context_index; 358 Register reg = is_optimizing() ? flow_graph_.num_copied_params()
359 : context_index;
223 Register closure_reg = reg; 360 Register closure_reg = reg;
224 LocalScope* scope = parsed_function().node_sequence()->scope(); 361 LocalScope* scope = parsed_function().node_sequence()->scope();
225 LocalVariable* local = scope->VariableAt(0); 362 LocalVariable* local = scope->VariableAt(0);
226 if (local->index() > 0) { 363 if (local->index() > 0) {
227 __ Move(reg, -local->index()); 364 __ Move(reg, -local->index());
228 } else { 365 } else {
229 closure_reg = -local->index() - 1; 366 closure_reg = -local->index() - 1;
230 } 367 }
231 __ LoadField(reg, closure_reg, Closure::context_offset() / kWordSize); 368 __ LoadField(reg, closure_reg, Closure::context_offset() / kWordSize);
232 } else if (has_optional_params) { 369 } else if (has_optional_params && !is_optimizing()) {
233 __ LoadConstant(context_index, 370 __ LoadConstant(context_index,
234 Object::Handle(isolate()->object_store()->empty_context())); 371 Object::Handle(isolate()->object_store()->empty_context()));
235 } 372 }
236 } 373 }
237 374
238 375
239 void FlowGraphCompiler::CompileGraph() { 376 void FlowGraphCompiler::CompileGraph() {
240 InitCompiler(); 377 InitCompiler();
241 378
242 if (TryIntrinsify()) { 379 if (TryIntrinsify()) {
243 // Skip regular code generation. 380 // Skip regular code generation.
244 return; 381 return;
245 } 382 }
246 383
247 EmitFrameEntry(); 384 EmitFrameEntry();
248 VisitBlocks(); 385 VisitBlocks();
249 } 386 }
250 387
251 388
252 #undef __ 389 #undef __
253 #define __ compiler_->assembler()-> 390 #define __ compiler_->assembler()->
254 391
255 392
256 void ParallelMoveResolver::EmitMove(int index) { 393 void ParallelMoveResolver::EmitMove(int index) {
257 UNIMPLEMENTED(); 394 MoveOperands* move = moves_[index];
395 const Location source = move->src();
396 const Location destination = move->dest();
397 if (source.IsStackSlot() && destination.IsRegister()) {
398 // Only allow access to the arguments.
399 ASSERT(source.base_reg() == FPREG);
400 ASSERT(source.stack_index() < 0);
401 __ Move(destination.reg(), -kParamEndSlotFromFp + source.stack_index());
402 } else if (source.IsRegister() && destination.IsRegister()) {
403 __ Move(destination.reg(), source.reg());
404 } else if (source.IsConstant() && destination.IsRegister()) {
405 __ LoadConstant(destination.reg(), source.constant());
406 } else {
407 compiler_->Bailout("Unsupported move");
408 }
409
410 move->Eliminate();
258 } 411 }
259 412
260 413
261 void ParallelMoveResolver::EmitSwap(int index) { 414 void ParallelMoveResolver::EmitSwap(int index) {
262 UNIMPLEMENTED(); 415 MoveOperands* move = moves_[index];
416 const Location source = move->src();
417 const Location destination = move->dest();
418
419 if (source.IsRegister() && destination.IsRegister()) {
420 __ Swap(destination.reg(), source.reg());
421 } else {
422 UNREACHABLE();
Florian Schneider 2016/05/19 13:21:40 Use ASSERT instead of if-statement?
Vyacheslav Egorov (Google) 2016/05/19 15:19:40 Done.
423 }
424
425 // The swap of source and destination has executed a move from source to
426 // destination.
427 move->Eliminate();
428
429 // Any unperformed (including pending) move with a source of either
430 // this move's source or destination needs to have their source
431 // changed to reflect the state of affairs after the swap.
432 for (int i = 0; i < moves_.length(); ++i) {
433 const MoveOperands& other_move = *moves_[i];
434 if (other_move.Blocks(source)) {
435 moves_[i]->set_src(destination);
436 } else if (other_move.Blocks(destination)) {
437 moves_[i]->set_src(source);
438 }
439 }
263 } 440 }
264 441
265 442
266 void ParallelMoveResolver::MoveMemoryToMemory(const Address& dst, 443 void ParallelMoveResolver::MoveMemoryToMemory(const Address& dst,
267 const Address& src) { 444 const Address& src) {
268 UNREACHABLE(); 445 UNREACHABLE();
269 } 446 }
270 447
271 448
272 void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) { 449 void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { 498 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
322 UNIMPLEMENTED(); 499 UNIMPLEMENTED();
323 } 500 }
324 501
325 502
326 #undef __ 503 #undef __
327 504
328 } // namespace dart 505 } // namespace dart
329 506
330 #endif // defined TARGET_ARCH_DBC 507 #endif // defined TARGET_ARCH_DBC
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698