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 34namespace 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 NodeDoesNotExit 0x10000 // This flag is negated to make it natural for the default to be that a node does exit. 70 71#define NodeRelevantToOSR 0x20000 72 73#define NodeIsFlushed 0x40000 // Used by Graph::computeIsFlushed(), will tell you which local nodes are backwards-reachable from a Flush. 74 75typedef uint32_t NodeFlags; 76 77static inline bool bytecodeUsesAsNumber(NodeFlags flags) 78{ 79 return !!(flags & NodeBytecodeUsesAsNumber); 80} 81 82static inline bool bytecodeCanTruncateInteger(NodeFlags flags) 83{ 84 return !bytecodeUsesAsNumber(flags); 85} 86 87static inline bool bytecodeCanIgnoreNegativeZero(NodeFlags flags) 88{ 89 return !(flags & NodeBytecodeNeedsNegZero); 90} 91 92enum RareCaseProfilingSource { 93 BaselineRareCase, // Comes from slow case counting in the baseline JIT. 94 DFGRareCase, // Comes from OSR exit profiles. 95 AllRareCases 96}; 97 98static inline bool nodeMayOverflow(NodeFlags flags, RareCaseProfilingSource source) 99{ 100 NodeFlags mask; 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 115static inline bool nodeMayNegZero(NodeFlags flags, RareCaseProfilingSource source) 116{ 117 NodeFlags mask; 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 132static 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 143static 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 153static 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 165void dumpNodeFlags(PrintStream&, NodeFlags); 166MAKE_PRINT_ADAPTOR(NodeFlagsDump, NodeFlags, dumpNodeFlags); 167 168} } // namespace JSC::DFG 169 170#endif // ENABLE(DFG_JIT) 171 172#endif // DFGNodeFlags_h 173 174