OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 // Class for intrinsifying functions. | 4 // Class for intrinsifying functions. |
5 | 5 |
6 #include "vm/assembler.h" | 6 #include "vm/assembler.h" |
7 #include "vm/compiler.h" | 7 #include "vm/compiler.h" |
8 #include "vm/cpu.h" | 8 #include "vm/cpu.h" |
9 #include "vm/flags.h" | 9 #include "vm/flags.h" |
10 #include "vm/flow_graph.h" | 10 #include "vm/flow_graph.h" |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 | 278 |
279 | 279 |
280 // Notes about the graph intrinsics: | 280 // Notes about the graph intrinsics: |
281 // | 281 // |
282 // IR instructions which would jump to a deoptimization sequence on failure | 282 // IR instructions which would jump to a deoptimization sequence on failure |
283 // instead branch to the intrinsic slow path. | 283 // instead branch to the intrinsic slow path. |
284 // | 284 // |
285 class BlockBuilder : public ValueObject { | 285 class BlockBuilder : public ValueObject { |
286 public: | 286 public: |
287 BlockBuilder(FlowGraph* flow_graph, TargetEntryInstr* entry) | 287 BlockBuilder(FlowGraph* flow_graph, TargetEntryInstr* entry) |
288 : flow_graph_(flow_graph), | 288 : flow_graph_(flow_graph), entry_(entry), current_(entry) {} |
289 entry_(entry), | |
290 current_(entry), | |
291 empty_env_(new Environment(0, | |
292 0, | |
293 Thread::kNoDeoptId, | |
294 flow_graph->parsed_function(), | |
295 NULL)) {} | |
296 | 289 |
297 Definition* AddToInitialDefinitions(Definition* def) { | 290 Definition* AddToInitialDefinitions(Definition* def) { |
298 def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); | 291 def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); |
299 flow_graph_->AddToInitialDefinitions(def); | 292 flow_graph_->AddToInitialDefinitions(def); |
300 return def; | 293 return def; |
301 } | 294 } |
302 | 295 |
303 Definition* AddDefinition(Definition* def) { | 296 Definition* AddDefinition(Definition* def) { |
304 def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); | 297 def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); |
305 AddInstruction(def); | 298 current_ = current_->AppendInstruction(def); |
306 return def; | 299 return def; |
307 } | 300 } |
308 | 301 |
309 Instruction* AddInstruction(Instruction* instr) { | 302 Instruction* AddInstruction(Instruction* instr) { |
310 if (instr->ComputeCanDeoptimize()) { | |
311 // Since we use the presence of an environment to determine if an | |
312 // instructions can deoptimize, we need an empty enviroment for | |
313 // instructions that "deoptimize" to the intrinsic fall-through code. | |
314 instr->SetEnvironment(empty_env_); | |
315 } | |
316 current_ = current_->AppendInstruction(instr); | 303 current_ = current_->AppendInstruction(instr); |
317 return instr; | 304 return instr; |
318 } | 305 } |
319 | 306 |
320 void AddIntrinsicReturn(Value* value) { | 307 void AddIntrinsicReturn(Value* value) { |
321 ReturnInstr* instr = new ReturnInstr(TokenPos(), value); | 308 ReturnInstr* instr = new ReturnInstr(TokenPos(), value); |
322 AddInstruction(instr); | 309 AddInstruction(instr); |
323 entry_->set_last_instruction(instr); | 310 entry_->set_last_instruction(instr); |
324 } | 311 } |
325 | 312 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 new InvokeMathCFunctionInstr(args, Thread::kNoDeoptId, recognized_kind, | 353 new InvokeMathCFunctionInstr(args, Thread::kNoDeoptId, recognized_kind, |
367 TokenPos()); | 354 TokenPos()); |
368 AddDefinition(invoke_math_c_function); | 355 AddDefinition(invoke_math_c_function); |
369 return invoke_math_c_function; | 356 return invoke_math_c_function; |
370 } | 357 } |
371 | 358 |
372 | 359 |
373 FlowGraph* flow_graph_; | 360 FlowGraph* flow_graph_; |
374 BlockEntryInstr* entry_; | 361 BlockEntryInstr* entry_; |
375 Instruction* current_; | 362 Instruction* current_; |
376 Environment* empty_env_; | |
377 }; | 363 }; |
378 | 364 |
379 | 365 |
380 static void PrepareIndexedOp(BlockBuilder* builder, | 366 static void PrepareIndexedOp(BlockBuilder* builder, |
381 Definition* array, | 367 Definition* array, |
382 Definition* index, | 368 Definition* index, |
383 intptr_t length_offset) { | 369 intptr_t length_offset) { |
384 Definition* length = builder->AddDefinition(new LoadFieldInstr( | 370 Definition* length = builder->AddDefinition(new LoadFieldInstr( |
385 new Value(array), length_offset, Type::ZoneHandle(Type::SmiType()), | 371 new Value(array), length_offset, Type::ZoneHandle(Type::SmiType()), |
386 TokenPosition::kNoSource)); | 372 TokenPosition::kNoSource)); |
(...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1181 } | 1167 } |
1182 | 1168 |
1183 | 1169 |
1184 void Intrinsifier::RegExp_ExecuteMatchSticky(Assembler* assembler) { | 1170 void Intrinsifier::RegExp_ExecuteMatchSticky(Assembler* assembler) { |
1185 IntrinsifyRegExpExecuteMatch(assembler, /*sticky=*/true); | 1171 IntrinsifyRegExpExecuteMatch(assembler, /*sticky=*/true); |
1186 } | 1172 } |
1187 #endif // !defined(TARGET_ARCH_DBC) | 1173 #endif // !defined(TARGET_ARCH_DBC) |
1188 | 1174 |
1189 | 1175 |
1190 } // namespace dart | 1176 } // namespace dart |
OLD | NEW |