fourthTier: Landing the initial FTL logic in a single commit to avoid spurious
[WebKit-https.git] / Source / JavaScriptCore / ftl / FTLCapabilities.cpp
1 /*
2  * Copyright (C) 2013 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 #include "config.h"
27 #include "FTLCapabilities.h"
28
29 #if ENABLE(FTL_JIT)
30
31 namespace JSC { namespace FTL {
32
33 using namespace DFG;
34
35 bool canCompile(Graph& graph)
36 {
37     for (BlockIndex blockIndex = graph.m_blocks.size(); blockIndex--;) {
38         BasicBlock* block = graph.m_blocks[blockIndex].get();
39         if (!block)
40             continue;
41         
42         for (unsigned nodeIndex = block->size(); nodeIndex--;) {
43             Node* node = block->at(nodeIndex);
44             
45             for (unsigned childIndex = graph.numChildren(node); childIndex--;) {
46                 Edge edge = graph.child(node, childIndex);
47                 if (!edge)
48                     continue;
49                 switch (edge.useKind()) {
50                 case UntypedUse:
51                 case Int32Use:
52                 case KnownInt32Use:
53                 case BooleanUse:
54                 case CellUse:
55                 case KnownCellUse:
56                 case ObjectUse:
57                     // These are OK.
58                     break;
59                 default:
60                     // Don't know how to handle anything else.
61                     return false;
62                 }
63             }
64             
65             switch (node->op()) {
66             case JSConstant:
67             case WeakJSConstant:
68             case GetLocal:
69             case SetLocal:
70             case MovHintAndCheck:
71             case MovHint:
72             case ZombieHint:
73             case Phantom:
74             case Flush:
75             case PhantomLocal:
76             case SetArgument:
77             case Return:
78             case BitAnd:
79             case BitOr:
80             case BitXor:
81             case BitRShift:
82             case BitLShift:
83             case BitURShift:
84             case CheckStructure:
85             case StructureTransitionWatchpoint:
86             case PutStructure:
87             case PhantomPutStructure:
88             case GetButterfly:
89             case GetByOffset:
90             case PutByOffset:
91             case GetGlobalVar:
92             case PutGlobalVar:
93                 // These are OK.
94                 break;
95             case ValueAdd:
96             case ArithAdd:
97             case ArithSub:
98             case ArithMul:
99                 if (node->binaryUseKind() == Int32Use)
100                     break;
101                 return false;
102             case ArithNegate:
103                 if (node->child1().useKind() == Int32Use)
104                     break;
105                 return false;
106             case UInt32ToNumber:
107                 if (!nodeCanSpeculateInteger(node->arithNodeFlags()))
108                     return false;
109                 break;
110             case GetArrayLength:
111                 switch (node->arrayMode().type()) {
112                 case Array::Int32:
113                 case Array::Double:
114                 case Array::Contiguous:
115                     break;
116                 default:
117                     return false;
118                 }
119                 break;
120             case GetByVal:
121                 switch (node->arrayMode().type()) {
122                 case Array::Int32:
123                 case Array::Contiguous:
124                     break;
125                 default:
126                     return false;
127                 }
128                 switch (node->arrayMode().speculation()) {
129                 case Array::SaneChain:
130                 case Array::InBounds:
131                     break;
132                 default:
133                     return false;
134                 }
135                 break;
136             case CompareEq:
137                 if (node->isBinaryUseKind(Int32Use))
138                     break;
139                 if (node->isBinaryUseKind(ObjectUse))
140                     break;
141                 return false;
142             case CompareLess:
143                 if (node->isBinaryUseKind(Int32Use))
144                     break;
145                 return false;
146             case Branch:
147                 if (node->child1().useKind() == BooleanUse)
148                     break;
149                 return false;
150             default:
151                 // Don't know how to handle anything else.
152                 return false;
153             }
154         }
155     }
156     
157     return true;
158 }
159
160 } } // namespace JSC::FTL
161
162 #endif // ENABLE(FTL_JIT)
163