DFG should only have two mechanisms for describing effectfulness of nodes; previously...
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGNodeFlags.h
1 /*
2  * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef DFGNodeFlags_h
27 #define DFGNodeFlags_h
28
29 #if ENABLE(DFG_JIT)
30
31 #include <wtf/PrintStream.h>
32 #include <wtf/StdLibExtras.h>
33
34 namespace JSC { namespace DFG {
35
36 // Entries in the NodeType enum (below) are composed of an id, a result type (possibly none)
37 // and some additional informative flags (must generate, is constant, etc).
38 #define NodeResultMask                   0x0007
39 #define NodeResultJS                     0x0001
40 #define NodeResultNumber                 0x0002
41 #define NodeResultDouble                 0x0003
42 #define NodeResultInt32                  0x0004
43 #define NodeResultInt52                  0x0005
44 #define NodeResultBoolean                0x0006
45 #define NodeResultStorage                0x0007
46                                 
47 #define NodeMustGenerate                 0x0008 // set on nodes that have side effects, and may not trivially be removed by DCE.
48 #define NodeHasVarArgs                   0x0010
49 // 0x0020 and 0x0040 are free.
50                                 
51 #define NodeBehaviorMask                 0x0780
52 #define NodeMayOverflowInBaseline        0x0080
53 #define NodeMayOverflowInDFG             0x0100
54 #define NodeMayNegZeroInBaseline         0x0200
55 #define NodeMayNegZeroInDFG              0x0400
56                                 
57 #define NodeBytecodeBackPropMask         0xf800
58 #define NodeBytecodeUseBottom            0x0000
59 #define NodeBytecodeUsesAsNumber         0x0800 // The result of this computation may be used in a context that observes fractional, or bigger-than-int32, results.
60 #define NodeBytecodeNeedsNegZero         0x1000 // The result of this computation may be used in a context that observes -0.
61 #define NodeBytecodeUsesAsOther          0x2000 // The result of this computation may be used in a context that distinguishes between NaN and other things (like undefined).
62 #define NodeBytecodeUsesAsValue          (NodeBytecodeUsesAsNumber | NodeBytecodeNeedsNegZero | NodeBytecodeUsesAsOther)
63 #define NodeBytecodeUsesAsInt            0x4000 // The result of this computation is known to be used in a context that prefers, but does not require, integer values.
64 #define NodeBytecodeUsesAsArrayIndex     0x8000 // The result of this computation is known to be used in a context that strongly prefers integer values, to the point that we should avoid using doubles if at all possible.
65
66 #define NodeArithFlagsMask               (NodeBehaviorMask | NodeBytecodeBackPropMask)
67
68 #define NodeRelevantToOSR               0x10000
69
70 #define NodeIsFlushed                   0x20000 // Computed by CPSRethreadingPhase, will tell you which local nodes are backwards-reachable from a Flush.
71
72 #define NodeMiscFlag1                   0x40000
73 #define NodeMiscFlag2                   0x80000
74
75 typedef uint32_t NodeFlags;
76
77 static inline bool bytecodeUsesAsNumber(NodeFlags flags)
78 {
79     return !!(flags & NodeBytecodeUsesAsNumber);
80 }
81
82 static inline bool bytecodeCanTruncateInteger(NodeFlags flags)
83 {
84     return !bytecodeUsesAsNumber(flags);
85 }
86
87 static inline bool bytecodeCanIgnoreNegativeZero(NodeFlags flags)
88 {
89     return !(flags & NodeBytecodeNeedsNegZero);
90 }
91
92 enum RareCaseProfilingSource {
93     BaselineRareCase, // Comes from slow case counting in the baseline JIT.
94     DFGRareCase, // Comes from OSR exit profiles.
95     AllRareCases
96 };
97
98 static inline bool nodeMayOverflow(NodeFlags flags, RareCaseProfilingSource source)
99 {
100     NodeFlags mask = 0;
101     switch (source) {
102     case BaselineRareCase:
103         mask = NodeMayOverflowInBaseline;
104         break;
105     case DFGRareCase:
106         mask = NodeMayOverflowInDFG;
107         break;
108     case AllRareCases:
109         mask = NodeMayOverflowInBaseline | NodeMayOverflowInDFG;
110         break;
111     }
112     return !!(flags & mask);
113 }
114
115 static inline bool nodeMayNegZero(NodeFlags flags, RareCaseProfilingSource source)
116 {
117     NodeFlags mask = 0;
118     switch (source) {
119     case BaselineRareCase:
120         mask = NodeMayNegZeroInBaseline;
121         break;
122     case DFGRareCase:
123         mask = NodeMayNegZeroInDFG;
124         break;
125     case AllRareCases:
126         mask = NodeMayNegZeroInBaseline | NodeMayNegZeroInDFG;
127         break;
128     }
129     return !!(flags & mask);
130 }
131
132 static inline bool nodeCanSpeculateInt32(NodeFlags flags, RareCaseProfilingSource source)
133 {
134     if (nodeMayOverflow(flags, source))
135         return !bytecodeUsesAsNumber(flags);
136     
137     if (nodeMayNegZero(flags, source))
138         return bytecodeCanIgnoreNegativeZero(flags);
139     
140     return true;
141 }
142
143 static inline bool nodeCanSpeculateInt52(NodeFlags flags, RareCaseProfilingSource source)
144 {
145     if (nodeMayNegZero(flags, source))
146         return bytecodeCanIgnoreNegativeZero(flags);
147     
148     return true;
149 }
150
151 // FIXME: Get rid of this.
152 // https://bugs.webkit.org/show_bug.cgi?id=131689
153 static inline NodeFlags canonicalResultRepresentation(NodeFlags flags)
154 {
155     switch (flags) {
156     case NodeResultDouble:
157     case NodeResultInt52:
158     case NodeResultStorage:
159         return flags;
160     default:
161         return NodeResultJS;
162     }
163 }
164
165 void dumpNodeFlags(PrintStream&, NodeFlags);
166 MAKE_PRINT_ADAPTOR(NodeFlagsDump, NodeFlags, dumpNodeFlags);
167
168 } } // namespace JSC::DFG
169
170 #endif // ENABLE(DFG_JIT)
171
172 #endif // DFGNodeFlags_h
173