a319c9c2141c32a8c56313a2a5f323bef6d7b918
[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 NodeMayOverflowInt32InBaseline   0x0080
53 #define NodeMayOverflowInt32InDFG        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 NodeIsFlushed                   0x10000 // Computed by CPSRethreadingPhase, will tell you which local nodes are backwards-reachable from a Flush.
69
70 #define NodeMiscFlag1                   0x20000
71 #define NodeMiscFlag2                   0x40000
72 #define NodeMiscFlag3                   0x80000
73
74 typedef uint32_t NodeFlags;
75
76 static inline bool bytecodeUsesAsNumber(NodeFlags flags)
77 {
78     return !!(flags & NodeBytecodeUsesAsNumber);
79 }
80
81 static inline bool bytecodeCanTruncateInteger(NodeFlags flags)
82 {
83     return !bytecodeUsesAsNumber(flags);
84 }
85
86 static inline bool bytecodeCanIgnoreNegativeZero(NodeFlags flags)
87 {
88     return !(flags & NodeBytecodeNeedsNegZero);
89 }
90
91 enum RareCaseProfilingSource {
92     BaselineRareCase, // Comes from slow case counting in the baseline JIT.
93     DFGRareCase, // Comes from OSR exit profiles.
94     AllRareCases
95 };
96
97 static inline bool nodeMayOverflowInt32(NodeFlags flags, RareCaseProfilingSource source)
98 {
99     NodeFlags mask = 0;
100     switch (source) {
101     case BaselineRareCase:
102         mask = NodeMayOverflowInt32InBaseline;
103         break;
104     case DFGRareCase:
105         mask = NodeMayOverflowInt32InDFG;
106         break;
107     case AllRareCases:
108         mask = NodeMayOverflowInt32InBaseline | NodeMayOverflowInt32InDFG;
109         break;
110     }
111     return !!(flags & mask);
112 }
113
114 static inline bool nodeMayNegZero(NodeFlags flags, RareCaseProfilingSource source)
115 {
116     NodeFlags mask = 0;
117     switch (source) {
118     case BaselineRareCase:
119         mask = NodeMayNegZeroInBaseline;
120         break;
121     case DFGRareCase:
122         mask = NodeMayNegZeroInDFG;
123         break;
124     case AllRareCases:
125         mask = NodeMayNegZeroInBaseline | NodeMayNegZeroInDFG;
126         break;
127     }
128     return !!(flags & mask);
129 }
130
131 static inline bool nodeCanSpeculateInt32(NodeFlags flags, RareCaseProfilingSource source)
132 {
133     if (nodeMayOverflowInt32(flags, source))
134         return !bytecodeUsesAsNumber(flags);
135     
136     if (nodeMayNegZero(flags, source))
137         return bytecodeCanIgnoreNegativeZero(flags);
138     
139     return true;
140 }
141
142 static inline bool nodeCanSpeculateInt52(NodeFlags flags, RareCaseProfilingSource source)
143 {
144     if (nodeMayNegZero(flags, source))
145         return bytecodeCanIgnoreNegativeZero(flags);
146     
147     return true;
148 }
149
150 // FIXME: Get rid of this.
151 // https://bugs.webkit.org/show_bug.cgi?id=131689
152 static inline NodeFlags canonicalResultRepresentation(NodeFlags flags)
153 {
154     switch (flags) {
155     case NodeResultDouble:
156     case NodeResultInt52:
157     case NodeResultStorage:
158         return flags;
159     default:
160         return NodeResultJS;
161     }
162 }
163
164 void dumpNodeFlags(PrintStream&, NodeFlags);
165 MAKE_PRINT_ADAPTOR(NodeFlagsDump, NodeFlags, dumpNodeFlags);
166
167 } } // namespace JSC::DFG
168
169 #endif // ENABLE(DFG_JIT)
170
171 #endif // DFGNodeFlags_h
172