Line data Source code
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
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_COMPILER_OSR_H_
6 : #define V8_COMPILER_OSR_H_
7 :
8 : #include "src/zone/zone.h"
9 :
10 : // TurboFan structures OSR graphs in a way that separates almost all phases of
11 : // compilation from OSR implementation details. This is accomplished with
12 : // special control nodes that are added at graph building time. In particular,
13 : // the graph is built in such a way that typing still computes the best types
14 : // and optimizations and lowering work unchanged. All that remains is to
15 : // deconstruct the OSR artifacts before scheduling and code generation.
16 :
17 : // Graphs built for OSR from the AstGraphBuilder are structured as follows:
18 : // Start
19 : // +-------------------^^-----+
20 : // | |
21 : // OsrNormalEntry OsrLoopEntry <-------------+
22 : // | | |
23 : // control flow before loop | A OsrValue
24 : // | | | |
25 : // | +------------------------+ | +-------+
26 : // | | +-------------+ | | +--------+
27 : // | | | | | | | |
28 : // ( Loop )<-----------|------------------ ( phi ) |
29 : // | | |
30 : // loop body | backedge(s) |
31 : // | | | |
32 : // | +--------------+ B <-----+
33 : // |
34 : // end
35 :
36 : // The control structure expresses the relationship that the loop has a separate
37 : // entrypoint which corresponds to entering the loop directly from the middle
38 : // of unoptimized code.
39 : // Similarly, the values that come in from unoptimized code are represented with
40 : // {OsrValue} nodes that merge into any phis associated with the OSR loop.
41 : // In the above diagram, nodes {A} and {B} represent values in the "normal"
42 : // graph that correspond to the values of those phis before the loop and on any
43 : // backedges, respectively.
44 :
45 : // To deconstruct OSR, we simply replace the uses of the {OsrNormalEntry}
46 : // control node with {Dead} and {OsrLoopEntry} with start and run the
47 : // {ControlReducer}. Control reduction propagates the dead control forward,
48 : // essentially "killing" all the code before the OSR loop. The entrypoint to the
49 : // loop corresponding to the "normal" entry path will also be removed, as well
50 : // as the inputs to the loop phis, resulting in the reduced graph:
51 :
52 : // Start
53 : // Dead |^-------------------------+
54 : // | | |
55 : // | | |
56 : // | | |
57 : // disconnected, dead | A=dead OsrValue
58 : // | |
59 : // +------------------+ +------+
60 : // | +-------------+ | +--------+
61 : // | | | | | |
62 : // ( Loop )<-----------|------------------ ( phi ) |
63 : // | | |
64 : // loop body | backedge(s) |
65 : // | | | |
66 : // | +--------------+ B <-----+
67 : // |
68 : // end
69 :
70 : // Other than the presences of the OsrValue nodes, this is a normal, schedulable
71 : // graph. OsrValue nodes are handled specially in the instruction selector to
72 : // simply load from the unoptimized frame.
73 :
74 : // For nested OSR loops, loop peeling must first be applied as many times as
75 : // necessary in order to bring the OSR loop up to the top level (i.e. to be
76 : // an outer loop).
77 :
78 : namespace v8 {
79 : namespace internal {
80 :
81 : class CompilationInfo;
82 :
83 : namespace compiler {
84 :
85 : class JSGraph;
86 : class CommonOperatorBuilder;
87 : class Frame;
88 : class Linkage;
89 :
90 : // Encapsulates logic relating to OSR compilations as well has handles some
91 : // details of the frame layout.
92 : class OsrHelper {
93 : public:
94 : explicit OsrHelper(CompilationInfo* info);
95 : // Only for testing.
96 : OsrHelper(size_t parameter_count, size_t stack_slot_count)
97 : : parameter_count_(parameter_count),
98 : stack_slot_count_(stack_slot_count) {}
99 :
100 : // Deconstructs the artificial {OsrNormalEntry} and rewrites the graph so
101 : // that only the path corresponding to {OsrLoopEntry} remains.
102 : void Deconstruct(JSGraph* jsgraph, CommonOperatorBuilder* common,
103 : Zone* tmp_zone);
104 :
105 : // Prepares the frame w.r.t. OSR.
106 : void SetupFrame(Frame* frame);
107 :
108 : // Returns the number of unoptimized frame slots for this OSR.
109 : size_t UnoptimizedFrameSlots() { return stack_slot_count_; }
110 :
111 : // Returns the environment index of the first stack slot.
112 : static int FirstStackSlotIndex(int parameter_count) {
113 : // n.b. unlike Crankshaft, TurboFan environments do not contain the context.
114 25895 : return 1 + parameter_count; // receiver + params
115 : }
116 :
117 : private:
118 : size_t parameter_count_;
119 : size_t stack_slot_count_;
120 : };
121 :
122 : } // namespace compiler
123 : } // namespace internal
124 : } // namespace v8
125 :
126 : #endif // V8_COMPILER_OSR_H_
|