2 * Copyright (C) 2013 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef FTLAbbreviations_h
27 #define FTLAbbreviations_h
31 #include "FTLAbbreviatedTypes.h"
32 #include "FTLValueFromBlock.h"
36 namespace JSC
{ namespace FTL
{
38 // This file contains short-form calls into the LLVM C API. It is meant to
39 // save typing and make the lowering code clearer. If we ever call an LLVM C API
40 // function more than once in the FTL lowering code, we should add a shortcut for
44 #error "The FTL backend assumes that pointers are 64-bit."
47 static inline LType
voidType(LContext context
) { return llvm
->VoidTypeInContext(context
); }
48 static inline LType
int1Type(LContext context
) { return llvm
->Int1TypeInContext(context
); }
49 static inline LType
int8Type(LContext context
) { return llvm
->Int8TypeInContext(context
); }
50 static inline LType
int16Type(LContext context
) { return llvm
->Int16TypeInContext(context
); }
51 static inline LType
int32Type(LContext context
) { return llvm
->Int32TypeInContext(context
); }
52 static inline LType
int64Type(LContext context
) { return llvm
->Int64TypeInContext(context
); }
53 static inline LType
intPtrType(LContext context
) { return llvm
->Int64TypeInContext(context
); }
54 static inline LType
floatType(LContext context
) { return llvm
->FloatTypeInContext(context
); }
55 static inline LType
doubleType(LContext context
) { return llvm
->DoubleTypeInContext(context
); }
57 static inline LType
pointerType(LType type
) { return llvm
->PointerType(type
, 0); }
58 static inline LType
arrayType(LType type
, unsigned count
) { return llvm
->ArrayType(type
, count
); }
59 static inline LType
vectorType(LType type
, unsigned count
) { return llvm
->VectorType(type
, count
); }
61 enum PackingMode
{ NotPacked
, Packed
};
62 static inline LType
structType(LContext context
, LType
* elementTypes
, unsigned elementCount
, PackingMode packing
= NotPacked
)
64 return llvm
->StructTypeInContext(context
, elementTypes
, elementCount
, packing
== Packed
);
66 static inline LType
structType(LContext context
, PackingMode packing
= NotPacked
)
68 return structType(context
, 0, 0, packing
);
70 static inline LType
structType(LContext context
, LType element1
, PackingMode packing
= NotPacked
)
72 return structType(context
, &element1
, 1, packing
);
74 static inline LType
structType(LContext context
, LType element1
, LType element2
, PackingMode packing
= NotPacked
)
76 LType elements
[] = { element1
, element2
};
77 return structType(context
, elements
, 2, packing
);
80 enum Variadicity
{ NotVariadic
, Variadic
};
81 static inline LType
functionType(LType returnType
, const LType
* paramTypes
, unsigned paramCount
, Variadicity variadicity
)
83 return llvm
->FunctionType(returnType
, const_cast<LType
*>(paramTypes
), paramCount
, variadicity
== Variadic
);
85 template<typename VectorType
>
86 inline LType
functionType(LType returnType
, const VectorType
& vector
, Variadicity variadicity
= NotVariadic
)
88 return functionType(returnType
, vector
.begin(), vector
.size(), variadicity
);
90 static inline LType
functionType(LType returnType
, Variadicity variadicity
= NotVariadic
)
92 return functionType(returnType
, 0, 0, variadicity
);
94 static inline LType
functionType(LType returnType
, LType param1
, Variadicity variadicity
= NotVariadic
)
96 return functionType(returnType
, ¶m1
, 1, variadicity
);
98 static inline LType
functionType(LType returnType
, LType param1
, LType param2
, Variadicity variadicity
= NotVariadic
)
100 LType paramTypes
[] = { param1
, param2
};
101 return functionType(returnType
, paramTypes
, 2, variadicity
);
103 static inline LType
functionType(LType returnType
, LType param1
, LType param2
, LType param3
, Variadicity variadicity
= NotVariadic
)
105 LType paramTypes
[] = { param1
, param2
, param3
};
106 return functionType(returnType
, paramTypes
, 3, variadicity
);
108 static inline LType
functionType(LType returnType
, LType param1
, LType param2
, LType param3
, LType param4
, Variadicity variadicity
= NotVariadic
)
110 LType paramTypes
[] = { param1
, param2
, param3
, param4
};
111 return functionType(returnType
, paramTypes
, 4, variadicity
);
114 static inline LType
typeOf(LValue value
) { return llvm
->TypeOf(value
); }
116 static inline unsigned mdKindID(LContext context
, const char* string
) { return llvm
->GetMDKindIDInContext(context
, string
, std::strlen(string
)); }
117 static inline LValue
mdString(LContext context
, const char* string
, unsigned length
) { return llvm
->MDStringInContext(context
, string
, length
); }
118 static inline LValue
mdString(LContext context
, const char* string
) { return mdString(context
, string
, std::strlen(string
)); }
119 static inline LValue
mdNode(LContext context
, LValue
* args
, unsigned numArgs
) { return llvm
->MDNodeInContext(context
, args
, numArgs
); }
120 template<typename VectorType
>
121 static inline LValue
mdNode(LContext context
, const VectorType
& vector
) { return mdNode(context
, const_cast<LValue
*>(vector
.begin()), vector
.size()); }
122 static inline LValue
mdNode(LContext context
) { return mdNode(context
, 0, 0); }
123 static inline LValue
mdNode(LContext context
, LValue arg1
) { return mdNode(context
, &arg1
, 1); }
124 static inline LValue
mdNode(LContext context
, LValue arg1
, LValue arg2
)
126 LValue args
[] = { arg1
, arg2
};
127 return mdNode(context
, args
, 2);
129 static inline LValue
mdNode(LContext context
, LValue arg1
, LValue arg2
, LValue arg3
)
131 LValue args
[] = { arg1
, arg2
, arg3
};
132 return mdNode(context
, args
, 3);
135 static inline void setMetadata(LValue instruction
, unsigned kind
, LValue metadata
) { llvm
->SetMetadata(instruction
, kind
, metadata
); }
137 static inline LValue
addFunction(LModule
module, const char* name
, LType type
) { return llvm
->AddFunction(module, name
, type
); }
138 static inline void setLinkage(LValue global
, LLinkage linkage
) { llvm
->SetLinkage(global
, linkage
); }
139 static inline void setFunctionCallingConv(LValue function
, LCallConv convention
) { llvm
->SetFunctionCallConv(function
, convention
); }
140 static inline void addTargetDependentFunctionAttr(LValue function
, const char* key
, const char* value
) { llvm
->AddTargetDependentFunctionAttr(function
, key
, value
); }
142 static inline LValue
addExternFunction(LModule
module, const char* name
, LType type
)
144 LValue result
= addFunction(module, name
, type
);
145 setLinkage(result
, LLVMExternalLinkage
);
149 static inline LValue
getParam(LValue function
, unsigned index
) { return llvm
->GetParam(function
, index
); }
150 static inline LValue
getUndef(LType type
) { return llvm
->GetUndef(type
); }
152 enum BitExtension
{ ZeroExtend
, SignExtend
};
153 static inline LValue
constInt(LType type
, unsigned long long value
, BitExtension extension
= ZeroExtend
) { return llvm
->ConstInt(type
, value
, extension
== SignExtend
); }
154 static inline LValue
constReal(LType type
, double value
) { return llvm
->ConstReal(type
, value
); }
155 static inline LValue
constIntToPtr(LValue value
, LType type
) { return llvm
->ConstIntToPtr(value
, type
); }
156 static inline LValue
constNull(LType type
) { return llvm
->ConstNull(type
); }
157 static inline LValue
constBitCast(LValue value
, LType type
) { return llvm
->ConstBitCast(value
, type
); }
159 static inline LBasicBlock
appendBasicBlock(LContext context
, LValue function
, const char* name
= "") { return llvm
->AppendBasicBlockInContext(context
, function
, name
); }
160 static inline LBasicBlock
insertBasicBlock(LContext context
, LBasicBlock beforeBasicBlock
, const char* name
= "") { return llvm
->InsertBasicBlockInContext(context
, beforeBasicBlock
, name
); }
162 static inline LValue
buildPhi(LBuilder builder
, LType type
) { return llvm
->BuildPhi(builder
, type
, ""); }
163 static inline void addIncoming(LValue phi
, const LValue
* values
, const LBasicBlock
* blocks
, unsigned numPredecessors
)
165 llvm
->AddIncoming(phi
, const_cast<LValue
*>(values
), const_cast<LBasicBlock
*>(blocks
), numPredecessors
);
167 static inline void addIncoming(LValue phi
, ValueFromBlock value1
)
169 LValue value
= value1
.value();
170 LBasicBlock block
= value1
.block();
171 addIncoming(phi
, &value
, &block
, 1);
173 static inline void addIncoming(LValue phi
, ValueFromBlock value1
, ValueFromBlock value2
)
175 LValue values
[] = { value1
.value(), value2
.value() };
176 LBasicBlock blocks
[] = { value1
.block(), value2
.block() };
177 addIncoming(phi
, values
, blocks
, 2);
179 static inline LValue
buildPhi(LBuilder builder
, LType type
, ValueFromBlock value1
)
181 LValue result
= buildPhi(builder
, type
);
182 addIncoming(result
, value1
);
185 static inline LValue
buildPhi(
186 LBuilder builder
, LType type
, ValueFromBlock value1
, ValueFromBlock value2
)
188 LValue result
= buildPhi(builder
, type
);
189 addIncoming(result
, value1
, value2
);
193 static inline LValue
buildAlloca(LBuilder builder
, LType type
) { return llvm
->BuildAlloca(builder
, type
, ""); }
194 static inline LValue
buildAdd(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildAdd(builder
, left
, right
, ""); }
195 static inline LValue
buildSub(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildSub(builder
, left
, right
, ""); }
196 static inline LValue
buildMul(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildMul(builder
, left
, right
, ""); }
197 static inline LValue
buildDiv(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildSDiv(builder
, left
, right
, ""); }
198 static inline LValue
buildRem(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildSRem(builder
, left
, right
, ""); }
199 static inline LValue
buildNeg(LBuilder builder
, LValue value
) { return llvm
->BuildNeg(builder
, value
, ""); }
200 static inline LValue
buildFAdd(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildFAdd(builder
, left
, right
, ""); }
201 static inline LValue
buildFSub(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildFSub(builder
, left
, right
, ""); }
202 static inline LValue
buildFMul(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildFMul(builder
, left
, right
, ""); }
203 static inline LValue
buildFDiv(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildFDiv(builder
, left
, right
, ""); }
204 static inline LValue
buildFRem(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildFRem(builder
, left
, right
, ""); }
205 static inline LValue
buildFNeg(LBuilder builder
, LValue value
) { return llvm
->BuildFNeg(builder
, value
, ""); }
206 static inline LValue
buildAnd(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildAnd(builder
, left
, right
, ""); }
207 static inline LValue
buildOr(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildOr(builder
, left
, right
, ""); }
208 static inline LValue
buildXor(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildXor(builder
, left
, right
, ""); }
209 static inline LValue
buildShl(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildShl(builder
, left
, right
, ""); }
210 static inline LValue
buildAShr(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildAShr(builder
, left
, right
, ""); }
211 static inline LValue
buildLShr(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildLShr(builder
, left
, right
, ""); }
212 static inline LValue
buildNot(LBuilder builder
, LValue value
) { return llvm
->BuildNot(builder
, value
, ""); }
213 static inline LValue
buildLoad(LBuilder builder
, LValue pointer
) { return llvm
->BuildLoad(builder
, pointer
, ""); }
214 static inline LValue
buildStore(LBuilder builder
, LValue value
, LValue pointer
) { return llvm
->BuildStore(builder
, value
, pointer
); }
215 static inline LValue
buildSExt(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildSExt(builder
, value
, type
, ""); }
216 static inline LValue
buildZExt(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildZExt(builder
, value
, type
, ""); }
217 static inline LValue
buildFPToSI(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildFPToSI(builder
, value
, type
, ""); }
218 static inline LValue
buildFPToUI(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildFPToUI(builder
, value
, type
, ""); }
219 static inline LValue
buildSIToFP(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildSIToFP(builder
, value
, type
, ""); }
220 static inline LValue
buildUIToFP(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildUIToFP(builder
, value
, type
, ""); }
221 static inline LValue
buildIntCast(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildIntCast(builder
, value
, type
, ""); }
222 static inline LValue
buildFPCast(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildFPCast(builder
, value
, type
, ""); }
223 static inline LValue
buildIntToPtr(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildIntToPtr(builder
, value
, type
, ""); }
224 static inline LValue
buildPtrToInt(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildPtrToInt(builder
, value
, type
, ""); }
225 static inline LValue
buildBitCast(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildBitCast(builder
, value
, type
, ""); }
226 static inline LValue
buildICmp(LBuilder builder
, LIntPredicate cond
, LValue left
, LValue right
) { return llvm
->BuildICmp(builder
, cond
, left
, right
, ""); }
227 static inline LValue
buildFCmp(LBuilder builder
, LRealPredicate cond
, LValue left
, LValue right
) { return llvm
->BuildFCmp(builder
, cond
, left
, right
, ""); }
228 static inline LValue
buildInsertElement(LBuilder builder
, LValue vector
, LValue element
, LValue index
) { return llvm
->BuildInsertElement(builder
, vector
, element
, index
, ""); }
230 enum SynchronizationScope
{ SingleThread
, CrossThread
};
231 static inline LValue
buildFence(LBuilder builder
, LAtomicOrdering ordering
, SynchronizationScope scope
= CrossThread
)
233 return llvm
->BuildFence(builder
, ordering
, scope
== SingleThread
, "");
236 static inline LValue
buildCall(LBuilder builder
, LValue function
, const LValue
* args
, unsigned numArgs
)
238 return llvm
->BuildCall(builder
, function
, const_cast<LValue
*>(args
), numArgs
, "");
240 template<typename VectorType
>
241 inline LValue
buildCall(LBuilder builder
, LValue function
, const VectorType
& vector
)
243 return buildCall(builder
, function
, vector
.begin(), vector
.size());
245 static inline LValue
buildCall(LBuilder builder
, LValue function
)
247 return buildCall(builder
, function
, 0, 0);
249 static inline LValue
buildCall(LBuilder builder
, LValue function
, LValue arg1
)
251 return buildCall(builder
, function
, &arg1
, 1);
253 static inline LValue
buildCall(LBuilder builder
, LValue function
, LValue arg1
, LValue arg2
)
255 LValue args
[] = { arg1
, arg2
};
256 return buildCall(builder
, function
, args
, 2);
258 static inline LValue
buildCall(LBuilder builder
, LValue function
, LValue arg1
, LValue arg2
, LValue arg3
)
260 LValue args
[] = { arg1
, arg2
, arg3
};
261 return buildCall(builder
, function
, args
, 3);
263 static inline LValue
buildCall(LBuilder builder
, LValue function
, LValue arg1
, LValue arg2
, LValue arg3
, LValue arg4
)
265 LValue args
[] = { arg1
, arg2
, arg3
, arg4
};
266 return buildCall(builder
, function
, args
, 4);
268 static inline LValue
buildCall(LBuilder builder
, LValue function
, LValue arg1
, LValue arg2
, LValue arg3
, LValue arg4
, LValue arg5
)
270 LValue args
[] = { arg1
, arg2
, arg3
, arg4
, arg5
};
271 return buildCall(builder
, function
, args
, 5);
273 static inline LValue
buildCall(LBuilder builder
, LValue function
, LValue arg1
, LValue arg2
, LValue arg3
, LValue arg4
, LValue arg5
, LValue arg6
)
275 LValue args
[] = { arg1
, arg2
, arg3
, arg4
, arg5
, arg6
};
276 return buildCall(builder
, function
, args
, 6);
278 static inline LValue
buildCall(LBuilder builder
, LValue function
, LValue arg1
, LValue arg2
, LValue arg3
, LValue arg4
, LValue arg5
, LValue arg6
, LValue arg7
)
280 LValue args
[] = { arg1
, arg2
, arg3
, arg4
, arg5
, arg6
, arg7
};
281 return buildCall(builder
, function
, args
, 7);
283 static inline LValue
buildCall(LBuilder builder
, LValue function
, LValue arg1
, LValue arg2
, LValue arg3
, LValue arg4
, LValue arg5
, LValue arg6
, LValue arg7
, LValue arg8
)
285 LValue args
[] = { arg1
, arg2
, arg3
, arg4
, arg5
, arg6
, arg7
, arg8
};
286 return buildCall(builder
, function
, args
, 8);
288 static inline void setInstructionCallingConvention(LValue instruction
, LCallConv callingConvention
) { llvm
->SetInstructionCallConv(instruction
, callingConvention
); }
289 static inline LValue
buildExtractValue(LBuilder builder
, LValue aggVal
, unsigned index
) { return llvm
->BuildExtractValue(builder
, aggVal
, index
, ""); }
290 static inline LValue
buildSelect(LBuilder builder
, LValue condition
, LValue taken
, LValue notTaken
) { return llvm
->BuildSelect(builder
, condition
, taken
, notTaken
, ""); }
291 static inline LValue
buildBr(LBuilder builder
, LBasicBlock destination
) { return llvm
->BuildBr(builder
, destination
); }
292 static inline LValue
buildCondBr(LBuilder builder
, LValue condition
, LBasicBlock taken
, LBasicBlock notTaken
) { return llvm
->BuildCondBr(builder
, condition
, taken
, notTaken
); }
293 static inline LValue
buildSwitch(LBuilder builder
, LValue value
, LBasicBlock fallThrough
, unsigned numCases
) { return llvm
->BuildSwitch(builder
, value
, fallThrough
, numCases
); }
294 static inline void addCase(LValue switchInst
, LValue value
, LBasicBlock target
) { llvm
->AddCase(switchInst
, value
, target
); }
295 template<typename VectorType
>
296 static inline LValue
buildSwitch(LBuilder builder
, LValue value
, const VectorType
& cases
, LBasicBlock fallThrough
)
298 LValue result
= buildSwitch(builder
, value
, fallThrough
, cases
.size());
299 for (unsigned i
= 0; i
< cases
.size(); ++i
)
300 addCase(result
, cases
[i
].value(), cases
[i
].target());
303 static inline LValue
buildRet(LBuilder builder
, LValue value
) { return llvm
->BuildRet(builder
, value
); }
304 static inline LValue
buildUnreachable(LBuilder builder
) { return llvm
->BuildUnreachable(builder
); }
306 static inline void dumpModule(LModule
module) { llvm
->DumpModule(module); }
307 static inline void verifyModule(LModule
module)
310 llvm
->VerifyModule(module, LLVMAbortProcessAction
, &error
);
311 llvm
->DisposeMessage(error
);
314 } } // namespace JSC::FTL
316 #endif // ENABLE(FTL_JIT)
318 #endif // FTLAbbreviations_h