[JSC] Add basic DFG/FTL support for Math.round
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGNode.h
1 /*
2  * Copyright (C) 2011-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 DFGNode_h
27 #define DFGNode_h
28
29 #if ENABLE(DFG_JIT)
30
31 #include "BasicBlockLocation.h"
32 #include "CodeBlock.h"
33 #include "DFGAbstractValue.h"
34 #include "DFGAdjacencyList.h"
35 #include "DFGArithMode.h"
36 #include "DFGArrayMode.h"
37 #include "DFGCommon.h"
38 #include "DFGEpoch.h"
39 #include "DFGLazyJSValue.h"
40 #include "DFGNodeFlags.h"
41 #include "DFGNodeOrigin.h"
42 #include "DFGNodeType.h"
43 #include "DFGObjectMaterializationData.h"
44 #include "DFGTransition.h"
45 #include "DFGUseKind.h"
46 #include "DFGVariableAccessData.h"
47 #include "GetByIdVariant.h"
48 #include "JSCJSValue.h"
49 #include "Operands.h"
50 #include "PutByIdVariant.h"
51 #include "SpeculatedType.h"
52 #include "StructureSet.h"
53 #include "TypeLocation.h"
54 #include "ValueProfile.h"
55 #include <wtf/ListDump.h>
56
57 namespace JSC { namespace DFG {
58
59 class Graph;
60 class PromotedLocationDescriptor;
61 struct BasicBlock;
62
63 struct StorageAccessData {
64     PropertyOffset offset;
65     unsigned identifierNumber;
66 };
67
68 struct MultiGetByOffsetData {
69     unsigned identifierNumber;
70     Vector<GetByIdVariant, 2> variants;
71 };
72
73 struct MultiPutByOffsetData {
74     unsigned identifierNumber;
75     Vector<PutByIdVariant, 2> variants;
76     
77     bool writesStructures() const;
78     bool reallocatesStorage() const;
79 };
80
81 struct NewArrayBufferData {
82     unsigned startConstant;
83     unsigned numConstants;
84     IndexingType indexingType;
85 };
86
87 struct BranchTarget {
88     BranchTarget()
89         : block(0)
90         , count(PNaN)
91     {
92     }
93     
94     explicit BranchTarget(BasicBlock* block)
95         : block(block)
96         , count(PNaN)
97     {
98     }
99     
100     void setBytecodeIndex(unsigned bytecodeIndex)
101     {
102         block = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(bytecodeIndex));
103     }
104     unsigned bytecodeIndex() const { return bitwise_cast<uintptr_t>(block); }
105     
106     void dump(PrintStream&) const;
107     
108     BasicBlock* block;
109     float count;
110 };
111
112 struct BranchData {
113     static BranchData withBytecodeIndices(
114         unsigned takenBytecodeIndex, unsigned notTakenBytecodeIndex)
115     {
116         BranchData result;
117         result.taken.block = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(takenBytecodeIndex));
118         result.notTaken.block = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(notTakenBytecodeIndex));
119         return result;
120     }
121     
122     unsigned takenBytecodeIndex() const { return taken.bytecodeIndex(); }
123     unsigned notTakenBytecodeIndex() const { return notTaken.bytecodeIndex(); }
124     
125     BasicBlock*& forCondition(bool condition)
126     {
127         if (condition)
128             return taken.block;
129         return notTaken.block;
130     }
131     
132     BranchTarget taken;
133     BranchTarget notTaken;
134 };
135
136 // The SwitchData and associated data structures duplicate the information in
137 // JumpTable. The DFG may ultimately end up using the JumpTable, though it may
138 // instead decide to do something different - this is entirely up to the DFG.
139 // These data structures give the DFG a higher-level semantic description of
140 // what is going on, which will allow it to make the right decision.
141 //
142 // Note that there will never be multiple SwitchCases in SwitchData::cases that
143 // have the same SwitchCase::value, since the bytecode's JumpTables never have
144 // duplicates - since the JumpTable maps a value to a target. It's a
145 // one-to-many mapping. So we may have duplicate targets, but never duplicate
146 // values.
147 struct SwitchCase {
148     SwitchCase()
149     {
150     }
151     
152     SwitchCase(LazyJSValue value, BasicBlock* target)
153         : value(value)
154         , target(target)
155     {
156     }
157     
158     static SwitchCase withBytecodeIndex(LazyJSValue value, unsigned bytecodeIndex)
159     {
160         SwitchCase result;
161         result.value = value;
162         result.target.setBytecodeIndex(bytecodeIndex);
163         return result;
164     }
165     
166     LazyJSValue value;
167     BranchTarget target;
168 };
169
170 struct SwitchData {
171     // Initializes most fields to obviously invalid values. Anyone
172     // constructing this should make sure to initialize everything they
173     // care about manually.
174     SwitchData()
175         : kind(static_cast<SwitchKind>(-1))
176         , switchTableIndex(UINT_MAX)
177         , didUseJumpTable(false)
178     {
179     }
180     
181     Vector<SwitchCase> cases;
182     BranchTarget fallThrough;
183     SwitchKind kind;
184     unsigned switchTableIndex;
185     bool didUseJumpTable;
186 };
187
188 struct CallVarargsData {
189     int firstVarArgOffset;
190 };
191
192 struct LoadVarargsData {
193     VirtualRegister start; // Local for the first element.
194     VirtualRegister count; // Local for the count.
195     VirtualRegister machineStart;
196     VirtualRegister machineCount;
197     unsigned offset; // Which array element to start with. Usually this is 0.
198     unsigned mandatoryMinimum; // The number of elements on the stack that must be initialized; if the array is too short then the missing elements must get undefined. Does not include "this".
199     unsigned limit; // Maximum number of elements to load. Includes "this".
200 };
201
202 struct StackAccessData {
203     StackAccessData()
204         : format(DeadFlush)
205     {
206     }
207     
208     StackAccessData(VirtualRegister local, FlushFormat format)
209         : local(local)
210         , format(format)
211     {
212     }
213     
214     VirtualRegister local;
215     VirtualRegister machineLocal;
216     FlushFormat format;
217     
218     FlushedAt flushedAt() { return FlushedAt(format, machineLocal); }
219 };
220
221 // This type used in passing an immediate argument to Node constructor;
222 // distinguishes an immediate value (typically an index into a CodeBlock data structure - 
223 // a constant index, argument, or identifier) from a Node*.
224 struct OpInfo {
225     OpInfo() : m_value(0) { }
226     explicit OpInfo(int32_t value) : m_value(static_cast<uintptr_t>(value)) { }
227     explicit OpInfo(uint32_t value) : m_value(static_cast<uintptr_t>(value)) { }
228 #if OS(DARWIN) || USE(JSVALUE64)
229     explicit OpInfo(size_t value) : m_value(static_cast<uintptr_t>(value)) { }
230 #endif
231     explicit OpInfo(void* value) : m_value(reinterpret_cast<uintptr_t>(value)) { }
232     uintptr_t m_value;
233 };
234
235 // === Node ===
236 //
237 // Node represents a single operation in the data flow graph.
238 struct Node {
239     enum VarArgTag { VarArg };
240     
241     Node() { }
242     
243     Node(NodeType op, NodeOrigin nodeOrigin, const AdjacencyList& children)
244         : origin(nodeOrigin)
245         , children(children)
246         , m_virtualRegister(VirtualRegister())
247         , m_refCount(1)
248         , m_prediction(SpecNone)
249         , owner(nullptr)
250     {
251         m_misc.replacement = nullptr;
252         setOpAndDefaultFlags(op);
253     }
254     
255     // Construct a node with up to 3 children, no immediate value.
256     Node(NodeType op, NodeOrigin nodeOrigin, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
257         : origin(nodeOrigin)
258         , children(AdjacencyList::Fixed, child1, child2, child3)
259         , m_virtualRegister(VirtualRegister())
260         , m_refCount(1)
261         , m_prediction(SpecNone)
262         , m_opInfo(0)
263         , m_opInfo2(0)
264         , owner(nullptr)
265     {
266         m_misc.replacement = nullptr;
267         setOpAndDefaultFlags(op);
268         ASSERT(!(m_flags & NodeHasVarArgs));
269     }
270
271     // Construct a node with up to 3 children, no immediate value.
272     Node(NodeFlags result, NodeType op, NodeOrigin nodeOrigin, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
273         : origin(nodeOrigin)
274         , children(AdjacencyList::Fixed, child1, child2, child3)
275         , m_virtualRegister(VirtualRegister())
276         , m_refCount(1)
277         , m_prediction(SpecNone)
278         , m_opInfo(0)
279         , m_opInfo2(0)
280         , owner(nullptr)
281     {
282         m_misc.replacement = nullptr;
283         setOpAndDefaultFlags(op);
284         setResult(result);
285         ASSERT(!(m_flags & NodeHasVarArgs));
286     }
287
288     // Construct a node with up to 3 children and an immediate value.
289     Node(NodeType op, NodeOrigin nodeOrigin, OpInfo imm, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
290         : origin(nodeOrigin)
291         , children(AdjacencyList::Fixed, child1, child2, child3)
292         , m_virtualRegister(VirtualRegister())
293         , m_refCount(1)
294         , m_prediction(SpecNone)
295         , m_opInfo(imm.m_value)
296         , m_opInfo2(0)
297         , owner(nullptr)
298     {
299         m_misc.replacement = nullptr;
300         setOpAndDefaultFlags(op);
301         ASSERT(!(m_flags & NodeHasVarArgs));
302     }
303
304     // Construct a node with up to 3 children and an immediate value.
305     Node(NodeFlags result, NodeType op, NodeOrigin nodeOrigin, OpInfo imm, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
306         : origin(nodeOrigin)
307         , children(AdjacencyList::Fixed, child1, child2, child3)
308         , m_virtualRegister(VirtualRegister())
309         , m_refCount(1)
310         , m_prediction(SpecNone)
311         , m_opInfo(imm.m_value)
312         , m_opInfo2(0)
313         , owner(nullptr)
314     {
315         m_misc.replacement = nullptr;
316         setOpAndDefaultFlags(op);
317         setResult(result);
318         ASSERT(!(m_flags & NodeHasVarArgs));
319     }
320
321     // Construct a node with up to 3 children and two immediate values.
322     Node(NodeType op, NodeOrigin nodeOrigin, OpInfo imm1, OpInfo imm2, Edge child1 = Edge(), Edge child2 = Edge(), Edge child3 = Edge())
323         : origin(nodeOrigin)
324         , children(AdjacencyList::Fixed, child1, child2, child3)
325         , m_virtualRegister(VirtualRegister())
326         , m_refCount(1)
327         , m_prediction(SpecNone)
328         , m_opInfo(imm1.m_value)
329         , m_opInfo2(imm2.m_value)
330         , owner(nullptr)
331     {
332         m_misc.replacement = nullptr;
333         setOpAndDefaultFlags(op);
334         ASSERT(!(m_flags & NodeHasVarArgs));
335     }
336     
337     // Construct a node with a variable number of children and two immediate values.
338     Node(VarArgTag, NodeType op, NodeOrigin nodeOrigin, OpInfo imm1, OpInfo imm2, unsigned firstChild, unsigned numChildren)
339         : origin(nodeOrigin)
340         , children(AdjacencyList::Variable, firstChild, numChildren)
341         , m_virtualRegister(VirtualRegister())
342         , m_refCount(1)
343         , m_prediction(SpecNone)
344         , m_opInfo(imm1.m_value)
345         , m_opInfo2(imm2.m_value)
346         , owner(nullptr)
347     {
348         m_misc.replacement = nullptr;
349         setOpAndDefaultFlags(op);
350         ASSERT(m_flags & NodeHasVarArgs);
351     }
352     
353     NodeType op() const { return static_cast<NodeType>(m_op); }
354     NodeFlags flags() const { return m_flags; }
355     
356     // This is not a fast method.
357     unsigned index() const;
358     
359     void setOp(NodeType op)
360     {
361         m_op = op;
362     }
363     
364     void setFlags(NodeFlags flags)
365     {
366         m_flags = flags;
367     }
368     
369     bool mergeFlags(NodeFlags flags)
370     {
371         NodeFlags newFlags = m_flags | flags;
372         if (newFlags == m_flags)
373             return false;
374         m_flags = newFlags;
375         return true;
376     }
377     
378     bool filterFlags(NodeFlags flags)
379     {
380         NodeFlags newFlags = m_flags & flags;
381         if (newFlags == m_flags)
382             return false;
383         m_flags = newFlags;
384         return true;
385     }
386     
387     bool clearFlags(NodeFlags flags)
388     {
389         return filterFlags(~flags);
390     }
391     
392     void setResult(NodeFlags result)
393     {
394         ASSERT(!(result & ~NodeResultMask));
395         clearFlags(NodeResultMask);
396         mergeFlags(result);
397     }
398     
399     NodeFlags result() const
400     {
401         return flags() & NodeResultMask;
402     }
403     
404     void setOpAndDefaultFlags(NodeType op)
405     {
406         m_op = op;
407         m_flags = defaultFlags(op);
408     }
409
410     void remove();
411
412     void convertToCheckStructure(StructureSet* set)
413     {
414         setOpAndDefaultFlags(CheckStructure);
415         m_opInfo = bitwise_cast<uintptr_t>(set); 
416     }
417
418     void convertToCheckStructureImmediate(Node* structure)
419     {
420         ASSERT(op() == CheckStructure);
421         m_op = CheckStructureImmediate;
422         children.setChild1(Edge(structure, CellUse));
423     }
424     
425     void replaceWith(Node* other)
426     {
427         remove();
428         setReplacement(other);
429     }
430
431     void convertToIdentity();
432     void convertToIdentityOn(Node*);
433
434     bool mustGenerate()
435     {
436         return m_flags & NodeMustGenerate;
437     }
438     
439     bool isConstant()
440     {
441         switch (op()) {
442         case JSConstant:
443         case DoubleConstant:
444         case Int52Constant:
445             return true;
446         default:
447             return false;
448         }
449     }
450     
451     bool hasConstant()
452     {
453         switch (op()) {
454         case JSConstant:
455         case DoubleConstant:
456         case Int52Constant:
457             return true;
458             
459         case PhantomDirectArguments:
460         case PhantomClonedArguments:
461             // These pretend to be the empty value constant for the benefit of the DFG backend, which
462             // otherwise wouldn't take kindly to a node that doesn't compute a value.
463             return true;
464             
465         default:
466             return false;
467         }
468     }
469
470     FrozenValue* constant()
471     {
472         ASSERT(hasConstant());
473         
474         if (op() == PhantomDirectArguments || op() == PhantomClonedArguments) {
475             // These pretend to be the empty value constant for the benefit of the DFG backend, which
476             // otherwise wouldn't take kindly to a node that doesn't compute a value.
477             return FrozenValue::emptySingleton();
478         }
479         
480         return bitwise_cast<FrozenValue*>(m_opInfo);
481     }
482     
483     // Don't call this directly - use Graph::convertToConstant() instead!
484     void convertToConstant(FrozenValue* value)
485     {
486         if (hasDoubleResult())
487             m_op = DoubleConstant;
488         else if (hasInt52Result())
489             m_op = Int52Constant;
490         else
491             m_op = JSConstant;
492         m_flags &= ~NodeMustGenerate;
493         m_opInfo = bitwise_cast<uintptr_t>(value);
494         children.reset();
495     }
496     
497     void convertToConstantStoragePointer(void* pointer)
498     {
499         ASSERT(op() == GetIndexedPropertyStorage);
500         m_op = ConstantStoragePointer;
501         m_opInfo = bitwise_cast<uintptr_t>(pointer);
502         children.reset();
503     }
504     
505     void convertToGetLocalUnlinked(VirtualRegister local)
506     {
507         m_op = GetLocalUnlinked;
508         m_flags &= ~NodeMustGenerate;
509         m_opInfo = local.offset();
510         m_opInfo2 = VirtualRegister().offset();
511         children.reset();
512     }
513     
514     void convertToPutStack(StackAccessData* data)
515     {
516         m_op = PutStack;
517         m_flags |= NodeMustGenerate;
518         m_opInfo = bitwise_cast<uintptr_t>(data);
519         m_opInfo2 = 0;
520     }
521     
522     void convertToGetStack(StackAccessData* data)
523     {
524         m_op = GetStack;
525         m_flags &= ~NodeMustGenerate;
526         m_opInfo = bitwise_cast<uintptr_t>(data);
527         m_opInfo2 = 0;
528         children.reset();
529     }
530     
531     void convertToGetByOffset(StorageAccessData& data, Edge storage)
532     {
533         ASSERT(m_op == GetById || m_op == GetByIdFlush || m_op == MultiGetByOffset);
534         m_opInfo = bitwise_cast<uintptr_t>(&data);
535         children.setChild2(children.child1());
536         children.child2().setUseKind(KnownCellUse);
537         children.setChild1(storage);
538         m_op = GetByOffset;
539         m_flags &= ~NodeMustGenerate;
540     }
541     
542     void convertToMultiGetByOffset(MultiGetByOffsetData* data)
543     {
544         ASSERT(m_op == GetById || m_op == GetByIdFlush);
545         m_opInfo = bitwise_cast<intptr_t>(data);
546         child1().setUseKind(CellUse);
547         m_op = MultiGetByOffset;
548         ASSERT(m_flags & NodeMustGenerate);
549     }
550     
551     void convertToPutByOffset(StorageAccessData& data, Edge storage)
552     {
553         ASSERT(m_op == PutById || m_op == PutByIdDirect || m_op == PutByIdFlush || m_op == MultiPutByOffset);
554         m_opInfo = bitwise_cast<uintptr_t>(&data);
555         children.setChild3(children.child2());
556         children.setChild2(children.child1());
557         children.setChild1(storage);
558         m_op = PutByOffset;
559     }
560     
561     void convertToMultiPutByOffset(MultiPutByOffsetData* data)
562     {
563         ASSERT(m_op == PutById || m_op == PutByIdDirect || m_op == PutByIdFlush);
564         m_opInfo = bitwise_cast<intptr_t>(data);
565         m_op = MultiPutByOffset;
566     }
567     
568     void convertToPutHint(const PromotedLocationDescriptor&, Node* base, Node* value);
569     
570     void convertToPutByOffsetHint();
571     void convertToPutStructureHint(Node* structure);
572     void convertToPutClosureVarHint();
573     
574     void convertToPhantomNewObject()
575     {
576         ASSERT(m_op == NewObject || m_op == MaterializeNewObject);
577         m_op = PhantomNewObject;
578         m_flags &= ~NodeHasVarArgs;
579         m_flags |= NodeMustGenerate;
580         m_opInfo = 0;
581         m_opInfo2 = 0;
582         children = AdjacencyList();
583     }
584
585     void convertToPhantomNewFunction()
586     {
587         ASSERT(m_op == NewFunction);
588         m_op = PhantomNewFunction;
589         m_flags |= NodeMustGenerate;
590         m_opInfo = 0;
591         m_opInfo2 = 0;
592         children = AdjacencyList();
593     }
594
595     void convertToPhantomCreateActivation()
596     {
597         ASSERT(m_op == CreateActivation || m_op == MaterializeCreateActivation);
598         m_op = PhantomCreateActivation;
599         m_flags &= ~NodeHasVarArgs;
600         m_flags |= NodeMustGenerate;
601         m_opInfo = 0;
602         m_opInfo2 = 0;
603         children = AdjacencyList();
604     }
605
606     void convertPhantomToPhantomLocal()
607     {
608         ASSERT(m_op == Phantom && (child1()->op() == Phi || child1()->op() == SetLocal || child1()->op() == SetArgument));
609         m_op = PhantomLocal;
610         m_opInfo = child1()->m_opInfo; // Copy the variableAccessData.
611         children.setChild1(Edge());
612     }
613     
614     void convertFlushToPhantomLocal()
615     {
616         ASSERT(m_op == Flush);
617         m_op = PhantomLocal;
618         children = AdjacencyList();
619     }
620     
621     void convertToGetLocal(VariableAccessData* variable, Node* phi)
622     {
623         ASSERT(m_op == GetLocalUnlinked);
624         m_op = GetLocal;
625         m_opInfo = bitwise_cast<uintptr_t>(variable);
626         m_opInfo2 = 0;
627         children.setChild1(Edge(phi));
628     }
629     
630     void convertToToString()
631     {
632         ASSERT(m_op == ToPrimitive);
633         m_op = ToString;
634     }
635
636     void convertToArithSqrt()
637     {
638         ASSERT(m_op == ArithPow);
639         child2() = Edge();
640         m_op = ArithSqrt;
641     }
642     
643     JSValue asJSValue()
644     {
645         return constant()->value();
646     }
647      
648     bool isInt32Constant()
649     {
650         return isConstant() && constant()->value().isInt32();
651     }
652      
653     int32_t asInt32()
654     {
655         return asJSValue().asInt32();
656     }
657      
658     uint32_t asUInt32()
659     {
660         return asInt32();
661     }
662      
663     bool isDoubleConstant()
664     {
665         return isConstant() && constant()->value().isDouble();
666     }
667      
668     bool isNumberConstant()
669     {
670         return isConstant() && constant()->value().isNumber();
671     }
672     
673     double asNumber()
674     {
675         return asJSValue().asNumber();
676     }
677      
678     bool isMachineIntConstant()
679     {
680         return isConstant() && constant()->value().isMachineInt();
681     }
682      
683     int64_t asMachineInt()
684     {
685         return asJSValue().asMachineInt();
686     }
687      
688     bool isBooleanConstant()
689     {
690         return isConstant() && constant()->value().isBoolean();
691     }
692      
693     bool asBoolean()
694     {
695         return constant()->value().asBoolean();
696     }
697      
698     bool isCellConstant()
699     {
700         return isConstant() && constant()->value() && constant()->value().isCell();
701     }
702      
703     JSCell* asCell()
704     {
705         return constant()->value().asCell();
706     }
707      
708     template<typename T>
709     T dynamicCastConstant()
710     {
711         if (!isCellConstant())
712             return nullptr;
713         return jsDynamicCast<T>(asCell());
714     }
715     
716     template<typename T>
717     T castConstant()
718     {
719         T result = dynamicCastConstant<T>();
720         RELEASE_ASSERT(result);
721         return result;
722     }
723      
724     bool containsMovHint()
725     {
726         switch (op()) {
727         case MovHint:
728         case ZombieHint:
729             return true;
730         default:
731             return false;
732         }
733     }
734     
735     bool hasVariableAccessData(Graph&);
736     bool hasLocal(Graph& graph)
737     {
738         return hasVariableAccessData(graph);
739     }
740     
741     // This is useful for debugging code, where a node that should have a variable
742     // access data doesn't have one because it hasn't been initialized yet.
743     VariableAccessData* tryGetVariableAccessData()
744     {
745         VariableAccessData* result = reinterpret_cast<VariableAccessData*>(m_opInfo);
746         if (!result)
747             return 0;
748         return result->find();
749     }
750     
751     VariableAccessData* variableAccessData()
752     {
753         return reinterpret_cast<VariableAccessData*>(m_opInfo)->find();
754     }
755     
756     VirtualRegister local()
757     {
758         return variableAccessData()->local();
759     }
760     
761     VirtualRegister machineLocal()
762     {
763         return variableAccessData()->machineLocal();
764     }
765     
766     bool hasUnlinkedLocal()
767     {
768         switch (op()) {
769         case GetLocalUnlinked:
770         case ExtractOSREntryLocal:
771         case MovHint:
772         case ZombieHint:
773         case KillStack:
774             return true;
775         default:
776             return false;
777         }
778     }
779     
780     VirtualRegister unlinkedLocal()
781     {
782         ASSERT(hasUnlinkedLocal());
783         return static_cast<VirtualRegister>(m_opInfo);
784     }
785     
786     bool hasUnlinkedMachineLocal()
787     {
788         return op() == GetLocalUnlinked;
789     }
790     
791     void setUnlinkedMachineLocal(VirtualRegister reg)
792     {
793         ASSERT(hasUnlinkedMachineLocal());
794         m_opInfo2 = reg.offset();
795     }
796     
797     VirtualRegister unlinkedMachineLocal()
798     {
799         ASSERT(hasUnlinkedMachineLocal());
800         return VirtualRegister(m_opInfo2);
801     }
802     
803     bool hasStackAccessData()
804     {
805         switch (op()) {
806         case PutStack:
807         case GetStack:
808             return true;
809         default:
810             return false;
811         }
812     }
813     
814     StackAccessData* stackAccessData()
815     {
816         ASSERT(hasStackAccessData());
817         return bitwise_cast<StackAccessData*>(m_opInfo);
818     }
819     
820     bool hasPhi()
821     {
822         return op() == Upsilon;
823     }
824     
825     Node* phi()
826     {
827         ASSERT(hasPhi());
828         return bitwise_cast<Node*>(m_opInfo);
829     }
830
831     bool isStoreBarrier()
832     {
833         switch (op()) {
834         case StoreBarrier:
835         case StoreBarrierWithNullCheck:
836             return true;
837         default:
838             return false;
839         }
840     }
841
842     bool hasIdentifier()
843     {
844         switch (op()) {
845         case GetById:
846         case GetByIdFlush:
847         case PutById:
848         case PutByIdFlush:
849         case PutByIdDirect:
850             return true;
851         default:
852             return false;
853         }
854     }
855
856     unsigned identifierNumber()
857     {
858         ASSERT(hasIdentifier());
859         return m_opInfo;
860     }
861     
862     bool hasPromotedLocationDescriptor()
863     {
864         return op() == PutHint;
865     }
866     
867     PromotedLocationDescriptor promotedLocationDescriptor();
868     
869     // This corrects the arithmetic node flags, so that irrelevant bits are
870     // ignored. In particular, anything other than ArithMul does not need
871     // to know if it can speculate on negative zero.
872     NodeFlags arithNodeFlags()
873     {
874         NodeFlags result = m_flags & NodeArithFlagsMask;
875         if (op() == ArithMul || op() == ArithDiv || op() == ArithMod || op() == ArithNegate || op() == ArithPow || op() == ArithRound || op() == DoubleAsInt32)
876             return result;
877         return result & ~NodeBytecodeNeedsNegZero;
878     }
879     
880     bool hasConstantBuffer()
881     {
882         return op() == NewArrayBuffer;
883     }
884     
885     NewArrayBufferData* newArrayBufferData()
886     {
887         ASSERT(hasConstantBuffer());
888         return reinterpret_cast<NewArrayBufferData*>(m_opInfo);
889     }
890     
891     unsigned startConstant()
892     {
893         return newArrayBufferData()->startConstant;
894     }
895     
896     unsigned numConstants()
897     {
898         return newArrayBufferData()->numConstants;
899     }
900     
901     bool hasIndexingType()
902     {
903         switch (op()) {
904         case NewArray:
905         case NewArrayWithSize:
906         case NewArrayBuffer:
907             return true;
908         default:
909             return false;
910         }
911     }
912     
913     IndexingType indexingType()
914     {
915         ASSERT(hasIndexingType());
916         if (op() == NewArrayBuffer)
917             return newArrayBufferData()->indexingType;
918         return m_opInfo;
919     }
920     
921     bool hasTypedArrayType()
922     {
923         switch (op()) {
924         case NewTypedArray:
925             return true;
926         default:
927             return false;
928         }
929     }
930     
931     TypedArrayType typedArrayType()
932     {
933         ASSERT(hasTypedArrayType());
934         TypedArrayType result = static_cast<TypedArrayType>(m_opInfo);
935         ASSERT(isTypedView(result));
936         return result;
937     }
938     
939     bool hasInlineCapacity()
940     {
941         return op() == CreateThis;
942     }
943
944     unsigned inlineCapacity()
945     {
946         ASSERT(hasInlineCapacity());
947         return m_opInfo;
948     }
949
950     void setIndexingType(IndexingType indexingType)
951     {
952         ASSERT(hasIndexingType());
953         m_opInfo = indexingType;
954     }
955     
956     bool hasRegexpIndex()
957     {
958         return op() == NewRegexp;
959     }
960     
961     unsigned regexpIndex()
962     {
963         ASSERT(hasRegexpIndex());
964         return m_opInfo;
965     }
966     
967     bool hasScopeOffset()
968     {
969         return op() == GetClosureVar || op() == PutClosureVar;
970     }
971
972     ScopeOffset scopeOffset()
973     {
974         ASSERT(hasScopeOffset());
975         return ScopeOffset(m_opInfo);
976     }
977     
978     bool hasDirectArgumentsOffset()
979     {
980         return op() == GetFromArguments || op() == PutToArguments;
981     }
982     
983     DirectArgumentsOffset capturedArgumentsOffset()
984     {
985         ASSERT(hasDirectArgumentsOffset());
986         return DirectArgumentsOffset(m_opInfo);
987     }
988     
989     bool hasRegisterPointer()
990     {
991         return op() == GetGlobalVar || op() == PutGlobalVar;
992     }
993     
994     WriteBarrier<Unknown>* variablePointer()
995     {
996         return bitwise_cast<WriteBarrier<Unknown>*>(m_opInfo);
997     }
998     
999     bool hasCallVarargsData()
1000     {
1001         switch (op()) {
1002         case CallVarargs:
1003         case CallForwardVarargs:
1004         case ConstructVarargs:
1005         case ConstructForwardVarargs:
1006             return true;
1007         default:
1008             return false;
1009         }
1010     }
1011     
1012     CallVarargsData* callVarargsData()
1013     {
1014         ASSERT(hasCallVarargsData());
1015         return bitwise_cast<CallVarargsData*>(m_opInfo);
1016     }
1017     
1018     bool hasLoadVarargsData()
1019     {
1020         return op() == LoadVarargs || op() == ForwardVarargs;
1021     }
1022     
1023     LoadVarargsData* loadVarargsData()
1024     {
1025         ASSERT(hasLoadVarargsData());
1026         return bitwise_cast<LoadVarargsData*>(m_opInfo);
1027     }
1028     
1029     bool hasResult()
1030     {
1031         return !!result();
1032     }
1033
1034     bool hasInt32Result()
1035     {
1036         return result() == NodeResultInt32;
1037     }
1038     
1039     bool hasInt52Result()
1040     {
1041         return result() == NodeResultInt52;
1042     }
1043     
1044     bool hasNumberResult()
1045     {
1046         return result() == NodeResultNumber;
1047     }
1048     
1049     bool hasDoubleResult()
1050     {
1051         return result() == NodeResultDouble;
1052     }
1053     
1054     bool hasJSResult()
1055     {
1056         return result() == NodeResultJS;
1057     }
1058     
1059     bool hasBooleanResult()
1060     {
1061         return result() == NodeResultBoolean;
1062     }
1063
1064     bool hasStorageResult()
1065     {
1066         return result() == NodeResultStorage;
1067     }
1068     
1069     UseKind defaultUseKind()
1070     {
1071         return useKindForResult(result());
1072     }
1073     
1074     Edge defaultEdge()
1075     {
1076         return Edge(this, defaultUseKind());
1077     }
1078
1079     bool isJump()
1080     {
1081         return op() == Jump;
1082     }
1083
1084     bool isBranch()
1085     {
1086         return op() == Branch;
1087     }
1088     
1089     bool isSwitch()
1090     {
1091         return op() == Switch;
1092     }
1093
1094     bool isTerminal()
1095     {
1096         switch (op()) {
1097         case Jump:
1098         case Branch:
1099         case Switch:
1100         case Return:
1101         case Unreachable:
1102             return true;
1103         default:
1104             return false;
1105         }
1106     }
1107
1108     unsigned targetBytecodeOffsetDuringParsing()
1109     {
1110         ASSERT(isJump());
1111         return m_opInfo;
1112     }
1113
1114     BasicBlock*& targetBlock()
1115     {
1116         ASSERT(isJump());
1117         return *bitwise_cast<BasicBlock**>(&m_opInfo);
1118     }
1119     
1120     BranchData* branchData()
1121     {
1122         ASSERT(isBranch());
1123         return bitwise_cast<BranchData*>(m_opInfo);
1124     }
1125     
1126     SwitchData* switchData()
1127     {
1128         ASSERT(isSwitch());
1129         return bitwise_cast<SwitchData*>(m_opInfo);
1130     }
1131     
1132     unsigned numSuccessors()
1133     {
1134         switch (op()) {
1135         case Jump:
1136             return 1;
1137         case Branch:
1138             return 2;
1139         case Switch:
1140             return switchData()->cases.size() + 1;
1141         default:
1142             return 0;
1143         }
1144     }
1145     
1146     BasicBlock*& successor(unsigned index)
1147     {
1148         if (isSwitch()) {
1149             if (index < switchData()->cases.size())
1150                 return switchData()->cases[index].target.block;
1151             RELEASE_ASSERT(index == switchData()->cases.size());
1152             return switchData()->fallThrough.block;
1153         }
1154         switch (index) {
1155         case 0:
1156             if (isJump())
1157                 return targetBlock();
1158             return branchData()->taken.block;
1159         case 1:
1160             return branchData()->notTaken.block;
1161         default:
1162             RELEASE_ASSERT_NOT_REACHED();
1163             return targetBlock();
1164         }
1165     }
1166     
1167     class SuccessorsIterable {
1168     public:
1169         SuccessorsIterable()
1170             : m_terminal(nullptr)
1171         {
1172         }
1173         
1174         SuccessorsIterable(Node* terminal)
1175             : m_terminal(terminal)
1176         {
1177         }
1178         
1179         class iterator {
1180         public:
1181             iterator()
1182                 : m_terminal(nullptr)
1183                 , m_index(UINT_MAX)
1184             {
1185             }
1186             
1187             iterator(Node* terminal, unsigned index)
1188                 : m_terminal(terminal)
1189                 , m_index(index)
1190             {
1191             }
1192             
1193             BasicBlock* operator*()
1194             {
1195                 return m_terminal->successor(m_index);
1196             }
1197             
1198             iterator& operator++()
1199             {
1200                 m_index++;
1201                 return *this;
1202             }
1203             
1204             bool operator==(const iterator& other) const
1205             {
1206                 return m_index == other.m_index;
1207             }
1208             
1209             bool operator!=(const iterator& other) const
1210             {
1211                 return !(*this == other);
1212             }
1213         private:
1214             Node* m_terminal;
1215             unsigned m_index;
1216         };
1217         
1218         iterator begin()
1219         {
1220             return iterator(m_terminal, 0);
1221         }
1222         
1223         iterator end()
1224         {
1225             return iterator(m_terminal, m_terminal->numSuccessors());
1226         }
1227         
1228     private:
1229         Node* m_terminal;
1230     };
1231     
1232     SuccessorsIterable successors()
1233     {
1234         return SuccessorsIterable(this);
1235     }
1236     
1237     BasicBlock*& successorForCondition(bool condition)
1238     {
1239         return branchData()->forCondition(condition);
1240     }
1241     
1242     bool hasHeapPrediction()
1243     {
1244         switch (op()) {
1245         case ArithRound:
1246         case GetDirectPname:
1247         case GetById:
1248         case GetByIdFlush:
1249         case GetByVal:
1250         case Call:
1251         case Construct:
1252         case CallVarargs:
1253         case ConstructVarargs:
1254         case CallForwardVarargs:
1255         case NativeCall:
1256         case NativeConstruct:
1257         case GetByOffset:
1258         case MultiGetByOffset:
1259         case GetClosureVar:
1260         case GetFromArguments:
1261         case ArrayPop:
1262         case ArrayPush:
1263         case RegExpExec:
1264         case RegExpTest:
1265         case GetGlobalVar:
1266             return true;
1267         default:
1268             return false;
1269         }
1270     }
1271     
1272     SpeculatedType getHeapPrediction()
1273     {
1274         ASSERT(hasHeapPrediction());
1275         return static_cast<SpeculatedType>(m_opInfo2);
1276     }
1277
1278     void setHeapPrediction(SpeculatedType prediction)
1279     {
1280         ASSERT(hasHeapPrediction());
1281         m_opInfo2 = prediction;
1282     }
1283     
1284     bool hasCellOperand()
1285     {
1286         switch (op()) {
1287         case CheckCell:
1288         case NativeConstruct:
1289         case NativeCall:
1290         case NewFunction:
1291             return true;
1292         default:
1293             return false;
1294         }
1295     }
1296
1297     FrozenValue* cellOperand()
1298     {
1299         ASSERT(hasCellOperand());
1300         return reinterpret_cast<FrozenValue*>(m_opInfo);
1301     }
1302     
1303     template<typename T>
1304     T castOperand()
1305     {
1306         return cellOperand()->cast<T>();
1307     }
1308     
1309     void setCellOperand(FrozenValue* value)
1310     {
1311         ASSERT(hasCellOperand());
1312         m_opInfo = bitwise_cast<uintptr_t>(value);
1313     }
1314     
1315     bool hasWatchpointSet()
1316     {
1317         return op() == NotifyWrite;
1318     }
1319     
1320     WatchpointSet* watchpointSet()
1321     {
1322         return reinterpret_cast<WatchpointSet*>(m_opInfo);
1323     }
1324     
1325     bool hasStoragePointer()
1326     {
1327         return op() == ConstantStoragePointer;
1328     }
1329     
1330     void* storagePointer()
1331     {
1332         return reinterpret_cast<void*>(m_opInfo);
1333     }
1334
1335     bool hasTransition()
1336     {
1337         switch (op()) {
1338         case PutStructure:
1339         case AllocatePropertyStorage:
1340         case ReallocatePropertyStorage:
1341             return true;
1342         default:
1343             return false;
1344         }
1345     }
1346     
1347     Transition* transition()
1348     {
1349         ASSERT(hasTransition());
1350         return reinterpret_cast<Transition*>(m_opInfo);
1351     }
1352     
1353     bool hasStructureSet()
1354     {
1355         switch (op()) {
1356         case CheckStructure:
1357         case CheckStructureImmediate:
1358             return true;
1359         default:
1360             return false;
1361         }
1362     }
1363     
1364     StructureSet& structureSet()
1365     {
1366         ASSERT(hasStructureSet());
1367         return *reinterpret_cast<StructureSet*>(m_opInfo);
1368     }
1369     
1370     bool hasStructure()
1371     {
1372         switch (op()) {
1373         case ArrayifyToStructure:
1374         case NewObject:
1375         case NewStringObject:
1376             return true;
1377         default:
1378             return false;
1379         }
1380     }
1381     
1382     Structure* structure()
1383     {
1384         ASSERT(hasStructure());
1385         return reinterpret_cast<Structure*>(m_opInfo);
1386     }
1387     
1388     bool hasStorageAccessData()
1389     {
1390         switch (op()) {
1391         case GetByOffset:
1392         case PutByOffset:
1393         case GetGetterSetterByOffset:
1394             return true;
1395         default:
1396             return false;
1397         }
1398     }
1399     
1400     StorageAccessData& storageAccessData()
1401     {
1402         ASSERT(hasStorageAccessData());
1403         return *bitwise_cast<StorageAccessData*>(m_opInfo);
1404     }
1405     
1406     bool hasMultiGetByOffsetData()
1407     {
1408         return op() == MultiGetByOffset;
1409     }
1410     
1411     MultiGetByOffsetData& multiGetByOffsetData()
1412     {
1413         return *reinterpret_cast<MultiGetByOffsetData*>(m_opInfo);
1414     }
1415     
1416     bool hasMultiPutByOffsetData()
1417     {
1418         return op() == MultiPutByOffset;
1419     }
1420     
1421     MultiPutByOffsetData& multiPutByOffsetData()
1422     {
1423         return *reinterpret_cast<MultiPutByOffsetData*>(m_opInfo);
1424     }
1425     
1426     bool hasObjectMaterializationData()
1427     {
1428         switch (op()) {
1429         case MaterializeNewObject:
1430         case MaterializeCreateActivation:
1431             return true;
1432
1433         default:
1434             return false;
1435         }
1436     }
1437     
1438     ObjectMaterializationData& objectMaterializationData()
1439     {
1440         ASSERT(hasObjectMaterializationData());
1441         return *reinterpret_cast<ObjectMaterializationData*>(m_opInfo);
1442     }
1443
1444     bool isObjectAllocation()
1445     {
1446         switch (op()) {
1447         case NewObject:
1448         case MaterializeNewObject:
1449             return true;
1450         default:
1451             return false;
1452         }
1453     }
1454     
1455     bool isPhantomObjectAllocation()
1456     {
1457         switch (op()) {
1458         case PhantomNewObject:
1459             return true;
1460         default:
1461             return false;
1462         }
1463     }
1464     
1465     bool isActivationAllocation()
1466     {
1467         switch (op()) {
1468         case CreateActivation:
1469         case MaterializeCreateActivation:
1470             return true;
1471         default:
1472             return false;
1473         }
1474     }
1475
1476     bool isPhantomActivationAllocation()
1477     {
1478         switch (op()) {
1479         case PhantomCreateActivation:
1480             return true;
1481         default:
1482             return false;
1483         }
1484     }
1485
1486     bool isPhantomAllocation()
1487     {
1488         switch (op()) {
1489         case PhantomNewObject:
1490         case PhantomDirectArguments:
1491         case PhantomClonedArguments:
1492         case PhantomNewFunction:
1493         case PhantomCreateActivation:
1494             return true;
1495         default:
1496             return false;
1497         }
1498     }
1499     
1500     bool hasArrayMode()
1501     {
1502         switch (op()) {
1503         case GetIndexedPropertyStorage:
1504         case GetArrayLength:
1505         case PutByValDirect:
1506         case PutByVal:
1507         case PutByValAlias:
1508         case GetByVal:
1509         case StringCharAt:
1510         case StringCharCodeAt:
1511         case CheckArray:
1512         case Arrayify:
1513         case ArrayifyToStructure:
1514         case ArrayPush:
1515         case ArrayPop:
1516         case HasIndexedProperty:
1517             return true;
1518         default:
1519             return false;
1520         }
1521     }
1522     
1523     ArrayMode arrayMode()
1524     {
1525         ASSERT(hasArrayMode());
1526         if (op() == ArrayifyToStructure)
1527             return ArrayMode::fromWord(m_opInfo2);
1528         return ArrayMode::fromWord(m_opInfo);
1529     }
1530     
1531     bool setArrayMode(ArrayMode arrayMode)
1532     {
1533         ASSERT(hasArrayMode());
1534         if (this->arrayMode() == arrayMode)
1535             return false;
1536         m_opInfo = arrayMode.asWord();
1537         return true;
1538     }
1539     
1540     bool hasArithMode()
1541     {
1542         switch (op()) {
1543         case ArithAdd:
1544         case ArithSub:
1545         case ArithNegate:
1546         case ArithMul:
1547         case ArithDiv:
1548         case ArithMod:
1549         case UInt32ToNumber:
1550         case DoubleAsInt32:
1551             return true;
1552         default:
1553             return false;
1554         }
1555     }
1556
1557     Arith::Mode arithMode()
1558     {
1559         ASSERT(hasArithMode());
1560         return static_cast<Arith::Mode>(m_opInfo);
1561     }
1562     
1563     void setArithMode(Arith::Mode mode)
1564     {
1565         m_opInfo = mode;
1566     }
1567
1568     bool hasArithRoundingMode()
1569     {
1570         return op() == ArithRound;
1571     }
1572
1573     Arith::RoundingMode arithRoundingMode()
1574     {
1575         ASSERT(hasArithRoundingMode());
1576         return static_cast<Arith::RoundingMode>(m_opInfo);
1577     }
1578
1579     void setArithRoundingMode(Arith::RoundingMode mode)
1580     {
1581         ASSERT(hasArithRoundingMode());
1582         m_opInfo = static_cast<uintptr_t>(mode);
1583     }
1584     
1585     bool hasVirtualRegister()
1586     {
1587         return m_virtualRegister.isValid();
1588     }
1589     
1590     VirtualRegister virtualRegister()
1591     {
1592         ASSERT(hasResult());
1593         ASSERT(m_virtualRegister.isValid());
1594         return m_virtualRegister;
1595     }
1596     
1597     void setVirtualRegister(VirtualRegister virtualRegister)
1598     {
1599         ASSERT(hasResult());
1600         ASSERT(!m_virtualRegister.isValid());
1601         m_virtualRegister = virtualRegister;
1602     }
1603     
1604     bool hasExecutionCounter()
1605     {
1606         return op() == CountExecution;
1607     }
1608     
1609     Profiler::ExecutionCounter* executionCounter()
1610     {
1611         return bitwise_cast<Profiler::ExecutionCounter*>(m_opInfo);
1612     }
1613
1614     bool shouldGenerate()
1615     {
1616         return m_refCount;
1617     }
1618     
1619     bool isSemanticallySkippable()
1620     {
1621         return op() == CountExecution;
1622     }
1623
1624     unsigned refCount()
1625     {
1626         return m_refCount;
1627     }
1628
1629     unsigned postfixRef()
1630     {
1631         return m_refCount++;
1632     }
1633
1634     unsigned adjustedRefCount()
1635     {
1636         return mustGenerate() ? m_refCount - 1 : m_refCount;
1637     }
1638     
1639     void setRefCount(unsigned refCount)
1640     {
1641         m_refCount = refCount;
1642     }
1643     
1644     Edge& child1()
1645     {
1646         ASSERT(!(m_flags & NodeHasVarArgs));
1647         return children.child1();
1648     }
1649     
1650     // This is useful if you want to do a fast check on the first child
1651     // before also doing a check on the opcode. Use this with care and
1652     // avoid it if possible.
1653     Edge child1Unchecked()
1654     {
1655         return children.child1Unchecked();
1656     }
1657
1658     Edge& child2()
1659     {
1660         ASSERT(!(m_flags & NodeHasVarArgs));
1661         return children.child2();
1662     }
1663
1664     Edge& child3()
1665     {
1666         ASSERT(!(m_flags & NodeHasVarArgs));
1667         return children.child3();
1668     }
1669     
1670     unsigned firstChild()
1671     {
1672         ASSERT(m_flags & NodeHasVarArgs);
1673         return children.firstChild();
1674     }
1675     
1676     unsigned numChildren()
1677     {
1678         ASSERT(m_flags & NodeHasVarArgs);
1679         return children.numChildren();
1680     }
1681     
1682     UseKind binaryUseKind()
1683     {
1684         ASSERT(child1().useKind() == child2().useKind());
1685         return child1().useKind();
1686     }
1687     
1688     bool isBinaryUseKind(UseKind left, UseKind right)
1689     {
1690         return child1().useKind() == left && child2().useKind() == right;
1691     }
1692     
1693     bool isBinaryUseKind(UseKind useKind)
1694     {
1695         return isBinaryUseKind(useKind, useKind);
1696     }
1697     
1698     Edge childFor(UseKind useKind)
1699     {
1700         if (child1().useKind() == useKind)
1701             return child1();
1702         if (child2().useKind() == useKind)
1703             return child2();
1704         if (child3().useKind() == useKind)
1705             return child3();
1706         return Edge();
1707     }
1708     
1709     SpeculatedType prediction()
1710     {
1711         return m_prediction;
1712     }
1713     
1714     bool predict(SpeculatedType prediction)
1715     {
1716         return mergeSpeculation(m_prediction, prediction);
1717     }
1718     
1719     bool shouldSpeculateInt32()
1720     {
1721         return isInt32Speculation(prediction());
1722     }
1723     
1724     bool sawBooleans()
1725     {
1726         return !!(prediction() & SpecBoolean);
1727     }
1728     
1729     bool shouldSpeculateInt32OrBoolean()
1730     {
1731         return isInt32OrBooleanSpeculation(prediction());
1732     }
1733     
1734     bool shouldSpeculateInt32ForArithmetic()
1735     {
1736         return isInt32SpeculationForArithmetic(prediction());
1737     }
1738     
1739     bool shouldSpeculateInt32OrBooleanForArithmetic()
1740     {
1741         return isInt32OrBooleanSpeculationForArithmetic(prediction());
1742     }
1743     
1744     bool shouldSpeculateInt32OrBooleanExpectingDefined()
1745     {
1746         return isInt32OrBooleanSpeculationExpectingDefined(prediction());
1747     }
1748     
1749     bool shouldSpeculateMachineInt()
1750     {
1751         return isMachineIntSpeculation(prediction());
1752     }
1753     
1754     bool shouldSpeculateDouble()
1755     {
1756         return isDoubleSpeculation(prediction());
1757     }
1758     
1759     bool shouldSpeculateNumber()
1760     {
1761         return isFullNumberSpeculation(prediction());
1762     }
1763     
1764     bool shouldSpeculateNumberOrBoolean()
1765     {
1766         return isFullNumberOrBooleanSpeculation(prediction());
1767     }
1768     
1769     bool shouldSpeculateNumberOrBooleanExpectingDefined()
1770     {
1771         return isFullNumberOrBooleanSpeculationExpectingDefined(prediction());
1772     }
1773     
1774     bool shouldSpeculateBoolean()
1775     {
1776         return isBooleanSpeculation(prediction());
1777     }
1778     
1779     bool shouldSpeculateOther()
1780     {
1781         return isOtherSpeculation(prediction());
1782     }
1783     
1784     bool shouldSpeculateMisc()
1785     {
1786         return isMiscSpeculation(prediction());
1787     }
1788    
1789     bool shouldSpeculateStringIdent()
1790     {
1791         return isStringIdentSpeculation(prediction());
1792     }
1793     
1794     bool shouldSpeculateNotStringVar()
1795     {
1796         return isNotStringVarSpeculation(prediction());
1797     }
1798  
1799     bool shouldSpeculateString()
1800     {
1801         return isStringSpeculation(prediction());
1802     }
1803  
1804     bool shouldSpeculateStringObject()
1805     {
1806         return isStringObjectSpeculation(prediction());
1807     }
1808     
1809     bool shouldSpeculateStringOrStringObject()
1810     {
1811         return isStringOrStringObjectSpeculation(prediction());
1812     }
1813     
1814     bool shouldSpeculateFinalObject()
1815     {
1816         return isFinalObjectSpeculation(prediction());
1817     }
1818     
1819     bool shouldSpeculateFinalObjectOrOther()
1820     {
1821         return isFinalObjectOrOtherSpeculation(prediction());
1822     }
1823     
1824     bool shouldSpeculateArray()
1825     {
1826         return isArraySpeculation(prediction());
1827     }
1828     
1829     bool shouldSpeculateDirectArguments()
1830     {
1831         return isDirectArgumentsSpeculation(prediction());
1832     }
1833     
1834     bool shouldSpeculateScopedArguments()
1835     {
1836         return isScopedArgumentsSpeculation(prediction());
1837     }
1838     
1839     bool shouldSpeculateInt8Array()
1840     {
1841         return isInt8ArraySpeculation(prediction());
1842     }
1843     
1844     bool shouldSpeculateInt16Array()
1845     {
1846         return isInt16ArraySpeculation(prediction());
1847     }
1848     
1849     bool shouldSpeculateInt32Array()
1850     {
1851         return isInt32ArraySpeculation(prediction());
1852     }
1853     
1854     bool shouldSpeculateUint8Array()
1855     {
1856         return isUint8ArraySpeculation(prediction());
1857     }
1858
1859     bool shouldSpeculateUint8ClampedArray()
1860     {
1861         return isUint8ClampedArraySpeculation(prediction());
1862     }
1863     
1864     bool shouldSpeculateUint16Array()
1865     {
1866         return isUint16ArraySpeculation(prediction());
1867     }
1868     
1869     bool shouldSpeculateUint32Array()
1870     {
1871         return isUint32ArraySpeculation(prediction());
1872     }
1873     
1874     bool shouldSpeculateFloat32Array()
1875     {
1876         return isFloat32ArraySpeculation(prediction());
1877     }
1878     
1879     bool shouldSpeculateFloat64Array()
1880     {
1881         return isFloat64ArraySpeculation(prediction());
1882     }
1883     
1884     bool shouldSpeculateArrayOrOther()
1885     {
1886         return isArrayOrOtherSpeculation(prediction());
1887     }
1888     
1889     bool shouldSpeculateObject()
1890     {
1891         return isObjectSpeculation(prediction());
1892     }
1893     
1894     bool shouldSpeculateObjectOrOther()
1895     {
1896         return isObjectOrOtherSpeculation(prediction());
1897     }
1898
1899     bool shouldSpeculateCell()
1900     {
1901         return isCellSpeculation(prediction());
1902     }
1903     
1904     bool shouldSpeculateNotCell()
1905     {
1906         return isNotCellSpeculation(prediction());
1907     }
1908     
1909     static bool shouldSpeculateBoolean(Node* op1, Node* op2)
1910     {
1911         return op1->shouldSpeculateBoolean() && op2->shouldSpeculateBoolean();
1912     }
1913     
1914     static bool shouldSpeculateInt32(Node* op1, Node* op2)
1915     {
1916         return op1->shouldSpeculateInt32() && op2->shouldSpeculateInt32();
1917     }
1918     
1919     static bool shouldSpeculateInt32OrBoolean(Node* op1, Node* op2)
1920     {
1921         return op1->shouldSpeculateInt32OrBoolean()
1922             && op2->shouldSpeculateInt32OrBoolean();
1923     }
1924     
1925     static bool shouldSpeculateInt32OrBooleanForArithmetic(Node* op1, Node* op2)
1926     {
1927         return op1->shouldSpeculateInt32OrBooleanForArithmetic()
1928             && op2->shouldSpeculateInt32OrBooleanForArithmetic();
1929     }
1930     
1931     static bool shouldSpeculateInt32OrBooleanExpectingDefined(Node* op1, Node* op2)
1932     {
1933         return op1->shouldSpeculateInt32OrBooleanExpectingDefined()
1934             && op2->shouldSpeculateInt32OrBooleanExpectingDefined();
1935     }
1936     
1937     static bool shouldSpeculateMachineInt(Node* op1, Node* op2)
1938     {
1939         return op1->shouldSpeculateMachineInt() && op2->shouldSpeculateMachineInt();
1940     }
1941     
1942     static bool shouldSpeculateNumber(Node* op1, Node* op2)
1943     {
1944         return op1->shouldSpeculateNumber() && op2->shouldSpeculateNumber();
1945     }
1946     
1947     static bool shouldSpeculateNumberOrBoolean(Node* op1, Node* op2)
1948     {
1949         return op1->shouldSpeculateNumberOrBoolean()
1950             && op2->shouldSpeculateNumberOrBoolean();
1951     }
1952     
1953     static bool shouldSpeculateNumberOrBooleanExpectingDefined(Node* op1, Node* op2)
1954     {
1955         return op1->shouldSpeculateNumberOrBooleanExpectingDefined()
1956             && op2->shouldSpeculateNumberOrBooleanExpectingDefined();
1957     }
1958     
1959     static bool shouldSpeculateFinalObject(Node* op1, Node* op2)
1960     {
1961         return op1->shouldSpeculateFinalObject() && op2->shouldSpeculateFinalObject();
1962     }
1963
1964     static bool shouldSpeculateArray(Node* op1, Node* op2)
1965     {
1966         return op1->shouldSpeculateArray() && op2->shouldSpeculateArray();
1967     }
1968     
1969     bool canSpeculateInt32(RareCaseProfilingSource source)
1970     {
1971         return nodeCanSpeculateInt32(arithNodeFlags(), source);
1972     }
1973     
1974     bool canSpeculateInt52(RareCaseProfilingSource source)
1975     {
1976         return nodeCanSpeculateInt52(arithNodeFlags(), source);
1977     }
1978     
1979     RareCaseProfilingSource sourceFor(PredictionPass pass)
1980     {
1981         if (pass == PrimaryPass || child1()->sawBooleans() || (child2() && child2()->sawBooleans()))
1982             return DFGRareCase;
1983         return AllRareCases;
1984     }
1985     
1986     bool canSpeculateInt32(PredictionPass pass)
1987     {
1988         return canSpeculateInt32(sourceFor(pass));
1989     }
1990     
1991     bool canSpeculateInt52(PredictionPass pass)
1992     {
1993         return canSpeculateInt52(sourceFor(pass));
1994     }
1995
1996     TypeLocation* typeLocation()
1997     {
1998         return reinterpret_cast<TypeLocation*>(m_opInfo);
1999     }
2000
2001     BasicBlockLocation* basicBlockLocation()
2002     {
2003         return reinterpret_cast<BasicBlockLocation*>(m_opInfo);
2004     }
2005     
2006     Node* replacement() const
2007     {
2008         return m_misc.replacement;
2009     }
2010     
2011     void setReplacement(Node* replacement)
2012     {
2013         m_misc.replacement = replacement;
2014     }
2015     
2016     Epoch epoch() const
2017     {
2018         return Epoch::fromUnsigned(m_misc.epoch);
2019     }
2020     
2021     void setEpoch(Epoch epoch)
2022     {
2023         m_misc.epoch = epoch.toUnsigned();
2024     }
2025     
2026     void dumpChildren(PrintStream& out)
2027     {
2028         if (!child1())
2029             return;
2030         out.printf("@%u", child1()->index());
2031         if (!child2())
2032             return;
2033         out.printf(", @%u", child2()->index());
2034         if (!child3())
2035             return;
2036         out.printf(", @%u", child3()->index());
2037     }
2038     
2039     // NB. This class must have a trivial destructor.
2040
2041     NodeOrigin origin;
2042
2043     // References to up to 3 children, or links to a variable length set of children.
2044     AdjacencyList children;
2045
2046 private:
2047     unsigned m_op : 10; // real type is NodeType
2048     unsigned m_flags : 22;
2049     // The virtual register number (spill location) associated with this .
2050     VirtualRegister m_virtualRegister;
2051     // The number of uses of the result of this operation (+1 for 'must generate' nodes, which have side-effects).
2052     unsigned m_refCount;
2053     // The prediction ascribed to this node after propagation.
2054     SpeculatedType m_prediction;
2055     // Immediate values, accesses type-checked via accessors above. The first one is
2056     // big enough to store a pointer.
2057     uintptr_t m_opInfo;
2058     uintptr_t m_opInfo2;
2059
2060 public:
2061     // Fields used by various analyses.
2062     AbstractValue value;
2063     
2064     // Miscellaneous data that is usually meaningless, but can hold some analysis results
2065     // if you ask right. For example, if you do Graph::initializeNodeOwners(), Node::owner
2066     // will tell you which basic block a node belongs to. You cannot rely on this persisting
2067     // across transformations unless you do the maintenance work yourself. Other phases use
2068     // Node::replacement, but they do so manually: first you do Graph::clearReplacements()
2069     // and then you set, and use, replacement's yourself. Same thing for epoch.
2070     //
2071     // Bottom line: don't use these fields unless you initialize them yourself, or by
2072     // calling some appropriate methods that initialize them the way you want. Otherwise,
2073     // these fields are meaningless.
2074 private:
2075     union {
2076         Node* replacement;
2077         unsigned epoch;
2078     } m_misc;
2079 public:
2080     BasicBlock* owner;
2081 };
2082
2083 inline bool nodeComparator(Node* a, Node* b)
2084 {
2085     return a->index() < b->index();
2086 }
2087
2088 template<typename T>
2089 CString nodeListDump(const T& nodeList)
2090 {
2091     return sortedListDump(nodeList, nodeComparator);
2092 }
2093
2094 template<typename T>
2095 CString nodeMapDump(const T& nodeMap, DumpContext* context = 0)
2096 {
2097     Vector<typename T::KeyType> keys;
2098     for (
2099         typename T::const_iterator iter = nodeMap.begin();
2100         iter != nodeMap.end(); ++iter)
2101         keys.append(iter->key);
2102     std::sort(keys.begin(), keys.end(), nodeComparator);
2103     StringPrintStream out;
2104     CommaPrinter comma;
2105     for(unsigned i = 0; i < keys.size(); ++i)
2106         out.print(comma, keys[i], "=>", inContext(nodeMap.get(keys[i]), context));
2107     return out.toCString();
2108 }
2109
2110 } } // namespace JSC::DFG
2111
2112 namespace WTF {
2113
2114 void printInternal(PrintStream&, JSC::DFG::SwitchKind);
2115 void printInternal(PrintStream&, JSC::DFG::Node*);
2116
2117 inline JSC::DFG::Node* inContext(JSC::DFG::Node* node, JSC::DumpContext*) { return node; }
2118
2119 } // namespace WTF
2120
2121 using WTF::inContext;
2122
2123 #endif
2124 #endif