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 |
3 | // BSD-style license that can be found in the LICENSE file. |
4 | |
5 | #ifndef RUNTIME_VM_COMPILER_FRONTEND_FLOW_GRAPH_BUILDER_H_ |
6 | #define RUNTIME_VM_COMPILER_FRONTEND_FLOW_GRAPH_BUILDER_H_ |
7 | |
8 | #if defined(DART_PRECOMPILED_RUNTIME) |
9 | #error "AOT runtime should not use compiler sources (including header files)" |
10 | #endif // defined(DART_PRECOMPILED_RUNTIME) |
11 | |
12 | #include "platform/assert.h" |
13 | #include "platform/globals.h" |
14 | #include "vm/allocation.h" |
15 | #include "vm/compiler/backend/flow_graph.h" |
16 | #include "vm/compiler/backend/il.h" |
17 | #include "vm/growable_array.h" |
18 | #include "vm/raw_object.h" |
19 | |
20 | namespace dart { |
21 | |
22 | // A class to collect the exits from an inlined function during graph |
23 | // construction so they can be plugged into the caller's flow graph. |
24 | class InlineExitCollector : public ZoneAllocated { |
25 | public: |
26 | InlineExitCollector(FlowGraph* caller_graph, Definition* call) |
27 | : caller_graph_(caller_graph), call_(call), exits_(4) {} |
28 | |
29 | void AddExit(ReturnInstr* exit); |
30 | |
31 | void Union(const InlineExitCollector* other); |
32 | |
33 | // Before replacing a call with a graph, the outer environment needs to be |
34 | // attached to each instruction in the callee graph and the caller graph |
35 | // needs to have its block and instruction ID state updated. |
36 | // Additionally we need to remove all unreachable exits from the list of |
37 | // collected exits. |
38 | void PrepareGraphs(FlowGraph* callee_graph); |
39 | |
40 | // Inline a graph at a call site. |
41 | // |
42 | // Assumes the callee is in SSA with a correct dominator tree and use |
43 | // lists. |
44 | // |
45 | // After inlining the caller graph will have correctly adjusted the use |
46 | // lists. The block orders will need to be recomputed. |
47 | void ReplaceCall(BlockEntryInstr* callee_entry); |
48 | |
49 | private: |
50 | struct Data { |
51 | BlockEntryInstr* exit_block; |
52 | ReturnInstr* exit_return; |
53 | }; |
54 | |
55 | BlockEntryInstr* ExitBlockAt(intptr_t i) const { |
56 | ASSERT(exits_[i].exit_block != NULL); |
57 | return exits_[i].exit_block; |
58 | } |
59 | |
60 | Instruction* LastInstructionAt(intptr_t i) const { |
61 | return ReturnAt(i)->previous(); |
62 | } |
63 | |
64 | Value* ValueAt(intptr_t i) const { return ReturnAt(i)->value(); } |
65 | |
66 | ReturnInstr* ReturnAt(intptr_t i) const { return exits_[i].exit_return; } |
67 | |
68 | static int LowestBlockIdFirst(const Data* a, const Data* b); |
69 | void SortExits(); |
70 | void RemoveUnreachableExits(FlowGraph* callee_graph); |
71 | |
72 | Definition* JoinReturns(BlockEntryInstr** exit_block, |
73 | Instruction** last_instruction, |
74 | intptr_t try_index); |
75 | |
76 | Isolate* isolate() const { return caller_graph_->isolate(); } |
77 | Zone* zone() const { return caller_graph_->zone(); } |
78 | |
79 | FlowGraph* caller_graph_; |
80 | Definition* call_; |
81 | GrowableArray<Data> exits_; |
82 | }; |
83 | |
84 | bool SimpleInstanceOfType(const AbstractType& type); |
85 | uword FindDoubleConstant(double value); |
86 | |
87 | } // namespace dart |
88 | |
89 | #endif // RUNTIME_VM_COMPILER_FRONTEND_FLOW_GRAPH_BUILDER_H_ |
90 |