547075d4bec514f96161ed39749ad25672391ca8
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGNodeFlags.h
1 /*
2  * Copyright (C) 2012, 2013, 2014 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 #define NodeClobbersWorld                0x0020
50 #define NodeMightClobber                 0x0040
51                                 
52 #define NodeBehaviorMask                 0x0780
53 #define NodeMayOverflowInBaseline        0x0080
54 #define NodeMayOverflowInDFG             0x0100
55 #define NodeMayNegZeroInBaseline         0x0200
56 #define NodeMayNegZeroInDFG              0x0400
57                                 
58 #define NodeBytecodeBackPropMask         0xf800
59 #define NodeBytecodeUseBottom            0x0000
60 #define NodeBytecodeUsesAsNumber         0x0800 // The result of this computation may be used in a context that observes fractional, or bigger-than-int32, results.
61 #define NodeBytecodeNeedsNegZero         0x1000 // The result of this computation may be used in a context that observes -0.
62 #define NodeBytecodeUsesAsOther          0x2000 // The result of this computation may be used in a context that distinguishes between NaN and other things (like undefined).
63 #define NodeBytecodeUsesAsValue          (NodeBytecodeUsesAsNumber | NodeBytecodeNeedsNegZero | NodeBytecodeUsesAsOther)
64 #define NodeBytecodeUsesAsInt            0x4000 // The result of this computation is known to be used in a context that prefers, but does not require, integer values.
65 #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.
66
67 #define NodeArithFlagsMask               (NodeBehaviorMask | NodeBytecodeBackPropMask)
68
69 #define NodeRelevantToOSR               0x10000
70
71 #define NodeIsFlushed                   0x20000 // Computed by CPSRethreadingPhase, will tell you which local nodes are backwards-reachable from a Flush.
72
73 #define NodeMiscFlag1                   0x40000
74 #define NodeMiscFlag2                   0x80000
75
76 typedef uint32_t NodeFlags;
77
78 static inline bool bytecodeUsesAsNumber(NodeFlags flags)
79 {
80     return !!(flags & NodeBytecodeUsesAsNumber);
81 }
82
83 static inline bool bytecodeCanTruncateInteger(NodeFlags flags)
84 {
85     return !bytecodeUsesAsNumber(flags);
86 }
87
88 static inline bool bytecodeCanIgnoreNegativeZero(NodeFlags flags)
89 {
90     return !(flags & NodeBytecodeNeedsNegZero);
91 }
92
93 enum RareCaseProfilingSource {
94     BaselineRareCase, // Comes from slow case counting in the baseline JIT.
95     DFGRareCase, // Comes from OSR exit profiles.
96     AllRareCases
97 };
98
99 static inline bool nodeMayOverflow(NodeFlags flags, RareCaseProfilingSource source)
100 {
101     NodeFlags mask = 0;
102     switch (source) {
103     case BaselineRareCase:
104         mask = NodeMayOverflowInBaseline;
105         break;
106     case DFGRareCase:
107         mask = NodeMayOverflowInDFG;
108         break;
109     case AllRareCases:
110         mask = NodeMayOverflowInBaseline | NodeMayOverflowInDFG;
111         break;
112     }
113     return !!(flags & mask);
114 }
115
116 static inline bool nodeMayNegZero(NodeFlags flags, RareCaseProfilingSource source)
117 {
118     NodeFlags mask = 0;
119     switch (source) {
120     case BaselineRareCase:
121         mask = NodeMayNegZeroInBaseline;
122         break;
123     case DFGRareCase:
124         mask = NodeMayNegZeroInDFG;
125         break;
126     case AllRareCases:
127         mask = NodeMayNegZeroInBaseline | NodeMayNegZeroInDFG;
128         break;
129     }
130     return !!(flags & mask);
131 }
132
133 static inline bool nodeCanSpeculateInt32(NodeFlags flags, RareCaseProfilingSource source)
134 {
135     if (nodeMayOverflow(flags, source))
136         return !bytecodeUsesAsNumber(flags);
137     
138     if (nodeMayNegZero(flags, source))
139         return bytecodeCanIgnoreNegativeZero(flags);
140     
141     return true;
142 }
143
144 static inline bool nodeCanSpeculateInt52(NodeFlags flags, RareCaseProfilingSource source)
145 {
146     if (nodeMayNegZero(flags, source))
147         return bytecodeCanIgnoreNegativeZero(flags);
148     
149     return true;
150 }
151
152 // FIXME: Get rid of this.
153 // https://bugs.webkit.org/show_bug.cgi?id=131689
154 static inline NodeFlags canonicalResultRepresentation(NodeFlags flags)
155 {
156     switch (flags) {
157     case NodeResultDouble:
158     case NodeResultInt52:
159     case NodeResultStorage:
160         return flags;
161     default:
162         return NodeResultJS;
163     }
164 }
165
166 void dumpNodeFlags(PrintStream&, NodeFlags);
167 MAKE_PRINT_ADAPTOR(NodeFlagsDump, NodeFlags, dumpNodeFlags);
168
169 } } // namespace JSC::DFG
170
171 #endif // ENABLE(DFG_JIT)
172
173 #endif // DFGNodeFlags_h
174