fourthTier: FTL should support Switch
[WebKit-https.git] / Source / JavaScriptCore / ftl / FTLAbbreviations.h
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 #ifndef FTLAbbreviations_h
27 #define FTLAbbreviations_h
28
29 #include <wtf/Platform.h>
30
31 #if ENABLE(FTL_JIT)
32
33 #include "FTLAbbreviatedTypes.h"
34 #include "FTLSwitchCase.h"
35 #include "FTLValueFromBlock.h"
36
37 namespace JSC { namespace FTL {
38
39 // This file contains short-form calls into the LLVM C API. It is meant to
40 // save typing and make the lowering code clearer. If we ever call an LLVM C API
41 // function more than once in the FTL lowering code, we should add a shortcut for
42 // it here.
43
44 #if USE(JSVALUE32_64)
45 #error "The FTL backend assumes that pointers are 64-bit."
46 #endif
47
48 static inline LType voidType(LContext context) { return LLVMVoidTypeInContext(context); }
49 static inline LType int1Type(LContext context) { return LLVMInt1TypeInContext(context); }
50 static inline LType int8Type(LContext context) { return LLVMInt8TypeInContext(context); }
51 static inline LType int32Type(LContext context) { return LLVMInt32TypeInContext(context); }
52 static inline LType int64Type(LContext context) { return LLVMInt64TypeInContext(context); }
53 static inline LType intPtrType(LContext context) { return LLVMInt64TypeInContext(context); }
54 static inline LType doubleType(LContext context) { return LLVMDoubleTypeInContext(context); }
55
56 static inline LType pointerType(LType type) { return LLVMPointerType(type, 0); }
57
58 enum PackingMode { NotPacked, Packed };
59 static inline LType structType(LContext context, LType* elementTypes, unsigned elementCount, PackingMode packing = NotPacked)
60 {
61     return LLVMStructTypeInContext(context, elementTypes, elementCount, packing == Packed);
62 }
63 static inline LType structType(LContext context, PackingMode packing = NotPacked)
64 {
65     return structType(context, 0, 0, packing);
66 }
67 static inline LType structType(LContext context, LType element1, PackingMode packing = NotPacked)
68 {
69     return structType(context, &element1, 1, packing);
70 }
71 static inline LType structType(LContext context, LType element1, LType element2, PackingMode packing = NotPacked)
72 {
73     LType elements[] = { element1, element2 };
74     return structType(context, elements, 2, packing);
75 }
76
77 enum Variadicity { NotVariadic, Variadic };
78 static inline LType functionType(LType returnType, const LType* paramTypes, unsigned paramCount, Variadicity variadicity)
79 {
80     return LLVMFunctionType(returnType, const_cast<LType*>(paramTypes), paramCount, variadicity == Variadic);
81 }
82 template<typename VectorType>
83 inline LType functionType(LType returnType, const VectorType& vector, Variadicity variadicity = NotVariadic)
84 {
85     return functionType(returnType, vector.begin(), vector.size(), variadicity);
86 }
87 static inline LType functionType(LType returnType, Variadicity variadicity = NotVariadic)
88 {
89     return functionType(returnType, 0, 0, variadicity);
90 }
91 static inline LType functionType(LType returnType, LType param1, Variadicity variadicity = NotVariadic)
92 {
93     return functionType(returnType, &param1, 1, variadicity);
94 }
95 static inline LType functionType(LType returnType, LType param1, LType param2, Variadicity variadicity = NotVariadic)
96 {
97     LType paramTypes[] = { param1, param2 };
98     return functionType(returnType, paramTypes, 2, variadicity);
99 }
100
101 static inline LType typeOf(LValue value) { return LLVMTypeOf(value); }
102
103 static inline unsigned mdKindID(LContext context, const char* string) { return LLVMGetMDKindIDInContext(context, string, strlen(string)); }
104 static inline LValue mdString(LContext context, const char* string, unsigned length) { return LLVMMDStringInContext(context, string, length); }
105 static inline LValue mdString(LContext context, const char* string) { return mdString(context, string, strlen(string)); }
106 static inline LValue mdNode(LContext context, LValue* args, unsigned numArgs) { return LLVMMDNodeInContext(context, args, numArgs); }
107 static inline LValue mdNode(LContext context) { return mdNode(context, 0, 0); }
108 static inline LValue mdNode(LContext context, LValue arg1) { return mdNode(context, &arg1, 1); }
109 static inline LValue mdNode(LContext context, LValue arg1, LValue arg2)
110 {
111     LValue args[] = { arg1, arg2 };
112     return mdNode(context, args, 2);
113 }
114
115 static inline void setMetadata(LValue instruction, unsigned kind, LValue metadata) { LLVMSetMetadata(instruction, kind, metadata); }
116
117 static inline LValue addFunction(LModule module, const char* name, LType type) { return LLVMAddFunction(module, name, type); }
118 static inline void setLinkage(LValue global, LLinkage linkage) { LLVMSetLinkage(global, linkage); }
119 static inline void setFunctionCallingConv(LValue function, LCallConv convention) { LLVMSetFunctionCallConv(function, convention); }
120
121 static inline LValue addExternFunction(LModule module, const char* name, LType type)
122 {
123     LValue result = addFunction(module, name, type);
124     setLinkage(result, LLVMExternalLinkage);
125     return result;
126 }
127
128 static inline LValue getParam(LValue function, unsigned index) { return LLVMGetParam(function, index); }
129
130 enum BitExtension { ZeroExtend, SignExtend };
131 static inline LValue constInt(LType type, unsigned long long value, BitExtension extension) { return LLVMConstInt(type, value, extension == SignExtend); }
132 static inline LValue constReal(LType type, double value) { return LLVMConstReal(type, value); }
133 static inline LValue constIntToPtr(LValue value, LType type) { return LLVMConstIntToPtr(value, type); }
134 static inline LValue constBitCast(LValue value, LType type) { return LLVMConstBitCast(value, type); }
135
136 static inline LBasicBlock appendBasicBlock(LContext context, LValue function, const char* name = "") { return LLVMAppendBasicBlockInContext(context, function, name); }
137 static inline LBasicBlock insertBasicBlock(LContext context, LBasicBlock beforeBasicBlock, const char* name = "") { return LLVMInsertBasicBlockInContext(context, beforeBasicBlock, name); }
138
139 static inline LValue buildPhi(LBuilder builder, LType type) { return LLVMBuildPhi(builder, type, ""); }
140 static inline void addIncoming(LValue phi, const LValue* values, const LBasicBlock* blocks, unsigned numPredecessors)
141 {
142     LLVMAddIncoming(phi, const_cast<LValue*>(values), const_cast<LBasicBlock*>(blocks), numPredecessors);
143 }
144 static inline void addIncoming(LValue phi, ValueFromBlock value1)
145 {
146     LValue value = value1.value();
147     LBasicBlock block = value1.block();
148     addIncoming(phi, &value, &block, 1);
149 }
150 static inline void addIncoming(LValue phi, ValueFromBlock value1, ValueFromBlock value2)
151 {
152     LValue values[] = { value1.value(), value2.value() };
153     LBasicBlock blocks[] = { value1.block(), value2.block() };
154     addIncoming(phi, values, blocks, 2);
155 }
156 static inline LValue buildPhi(LBuilder builder, LType type, ValueFromBlock value1)
157 {
158     LValue result = buildPhi(builder, type);
159     addIncoming(result, value1);
160     return result;
161 }
162 static inline LValue buildPhi(
163     LBuilder builder, LType type, ValueFromBlock value1, ValueFromBlock value2)
164 {
165     LValue result = buildPhi(builder, type);
166     addIncoming(result, value1, value2);
167     return result;
168 }
169
170 static inline LValue buildAlloca(LBuilder builder, LType type) { return LLVMBuildAlloca(builder, type, ""); }
171 static inline LValue buildAdd(LBuilder builder, LValue left, LValue right) { return LLVMBuildAdd(builder, left, right, ""); }
172 static inline LValue buildSub(LBuilder builder, LValue left, LValue right) { return LLVMBuildSub(builder, left, right, ""); }
173 static inline LValue buildMul(LBuilder builder, LValue left, LValue right) { return LLVMBuildMul(builder, left, right, ""); }
174 static inline LValue buildDiv(LBuilder builder, LValue left, LValue right) { return LLVMBuildSDiv(builder, left, right, ""); }
175 static inline LValue buildRem(LBuilder builder, LValue left, LValue right) { return LLVMBuildSRem(builder, left, right, ""); }
176 static inline LValue buildNeg(LBuilder builder, LValue value) { return LLVMBuildNeg(builder, value, ""); }
177 static inline LValue buildFAdd(LBuilder builder, LValue left, LValue right) { return LLVMBuildFAdd(builder, left, right, ""); }
178 static inline LValue buildFSub(LBuilder builder, LValue left, LValue right) { return LLVMBuildFSub(builder, left, right, ""); }
179 static inline LValue buildFMul(LBuilder builder, LValue left, LValue right) { return LLVMBuildFMul(builder, left, right, ""); }
180 static inline LValue buildFDiv(LBuilder builder, LValue left, LValue right) { return LLVMBuildFDiv(builder, left, right, ""); }
181 static inline LValue buildFRem(LBuilder builder, LValue left, LValue right) { return LLVMBuildFRem(builder, left, right, ""); }
182 static inline LValue buildFNeg(LBuilder builder, LValue value) { return LLVMBuildFNeg(builder, value, ""); }
183 static inline LValue buildAnd(LBuilder builder, LValue left, LValue right) { return LLVMBuildAnd(builder, left, right, ""); }
184 static inline LValue buildOr(LBuilder builder, LValue left, LValue right) { return LLVMBuildOr(builder, left, right, ""); }
185 static inline LValue buildXor(LBuilder builder, LValue left, LValue right) { return LLVMBuildXor(builder, left, right, ""); }
186 static inline LValue buildShl(LBuilder builder, LValue left, LValue right) { return LLVMBuildShl(builder, left, right, ""); }
187 static inline LValue buildAShr(LBuilder builder, LValue left, LValue right) { return LLVMBuildAShr(builder, left, right, ""); }
188 static inline LValue buildLShr(LBuilder builder, LValue left, LValue right) { return LLVMBuildLShr(builder, left, right, ""); }
189 static inline LValue buildNot(LBuilder builder, LValue value) { return LLVMBuildNot(builder, value, ""); }
190 static inline LValue buildLoad(LBuilder builder, LValue pointer) { return LLVMBuildLoad(builder, pointer, ""); }
191 static inline LValue buildStore(LBuilder builder, LValue value, LValue pointer) { return LLVMBuildStore(builder, value, pointer); }
192 static inline LValue buildZExt(LBuilder builder, LValue value, LType type) { return LLVMBuildZExt(builder, value, type, ""); }
193 static inline LValue buildFPToSI(LBuilder builder, LValue value, LType type) { return LLVMBuildFPToSI(builder, value, type, ""); }
194 static inline LValue buildSIToFP(LBuilder builder, LValue value, LType type) { return LLVMBuildSIToFP(builder, value, type, ""); }
195 static inline LValue buildUIToFP(LBuilder builder, LValue value, LType type) { return LLVMBuildUIToFP(builder, value, type, ""); }
196 static inline LValue buildIntCast(LBuilder builder, LValue value, LType type) { return LLVMBuildIntCast(builder, value, type, ""); }
197 static inline LValue buildIntToPtr(LBuilder builder, LValue value, LType type) { return LLVMBuildIntToPtr(builder, value, type, ""); }
198 static inline LValue buildPtrToInt(LBuilder builder, LValue value, LType type) { return LLVMBuildPtrToInt(builder, value, type, ""); }
199 static inline LValue buildBitCast(LBuilder builder, LValue value, LType type) { return LLVMBuildBitCast(builder, value, type, ""); }
200 static inline LValue buildICmp(LBuilder builder, LIntPredicate cond, LValue left, LValue right) { return LLVMBuildICmp(builder, cond, left, right, ""); }
201 static inline LValue buildFCmp(LBuilder builder, LRealPredicate cond, LValue left, LValue right) { return LLVMBuildFCmp(builder, cond, left, right, ""); }
202 static inline LValue buildCall(LBuilder builder, LValue function, const LValue* args, unsigned numArgs)
203 {
204     return LLVMBuildCall(builder, function, const_cast<LValue*>(args), numArgs, "");
205 }
206 template<typename VectorType>
207 inline LValue buildCall(LBuilder builder, LValue function, const VectorType& vector)
208 {
209     return buildCall(builder, function, vector.begin(), vector.size());
210 }
211 static inline LValue buildCall(LBuilder builder, LValue function)
212 {
213     return buildCall(builder, function, 0, 0);
214 }
215 static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1)
216 {
217     return buildCall(builder, function, &arg1, 1);
218 }
219 static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2)
220 {
221     LValue args[] = { arg1, arg2 };
222     return buildCall(builder, function, args, 2);
223 }
224 enum TailCallMode { IsNotTailCall, IsTailCall };
225 static inline void setTailCall(LValue call, TailCallMode mode) { LLVMSetTailCall(call, mode == IsTailCall); }
226 static inline LValue buildExtractValue(LBuilder builder, LValue aggVal, unsigned index) { return LLVMBuildExtractValue(builder, aggVal, index, ""); }
227 static inline LValue buildSelect(LBuilder builder, LValue condition, LValue taken, LValue notTaken) { return LLVMBuildSelect(builder, condition, taken, notTaken, ""); }
228 static inline LValue buildBr(LBuilder builder, LBasicBlock destination) { return LLVMBuildBr(builder, destination); }
229 static inline LValue buildCondBr(LBuilder builder, LValue condition, LBasicBlock taken, LBasicBlock notTaken) { return LLVMBuildCondBr(builder, condition, taken, notTaken); }
230 static inline LValue buildSwitch(LBuilder builder, LValue value, LBasicBlock fallThrough, unsigned numCases) { return LLVMBuildSwitch(builder, value, fallThrough, numCases); }
231 static inline void addCase(LValue switchInst, LValue value, LBasicBlock target) { LLVMAddCase(switchInst, value, target); }
232 template<typename VectorType>
233 static inline LValue buildSwitch(LBuilder builder, LValue value, const VectorType& cases, LBasicBlock fallThrough)
234 {
235     LValue result = buildSwitch(builder, value, fallThrough, cases.size());
236     for (unsigned i = 0; i < cases.size(); ++i)
237         addCase(result, cases[i].value(), cases[i].target());
238     return result;
239 }
240 static inline LValue buildRet(LBuilder builder, LValue value) { return LLVMBuildRet(builder, value); }
241 static inline LValue buildUnreachable(LBuilder builder) { return LLVMBuildUnreachable(builder); }
242
243 static inline void dumpModule(LModule module) { LLVMDumpModule(module); }
244 static inline void verifyModule(LModule module)
245 {
246     char* error = 0;
247     LLVMVerifyModule(module, LLVMAbortProcessAction, &error);
248     LLVMDisposeMessage(error);
249 }
250
251 } } // namespace JSC::FTL
252
253 #endif // ENABLE(FTL_JIT)
254
255 #endif // FTLAbbreviations_h
256