2 * Copyright (C) 2013, 2015 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 // FIXME: Make the Variadicity argument not be the last argument to functionType() so that this function
81 // can use C++11 variadic templates
82 // https://bugs.webkit.org/show_bug.cgi?id=141575
83 enum Variadicity
{ NotVariadic
, Variadic
};
84 static inline LType
functionType(LType returnType
, const LType
* paramTypes
, unsigned paramCount
, Variadicity variadicity
)
86 return llvm
->FunctionType(returnType
, const_cast<LType
*>(paramTypes
), paramCount
, variadicity
== Variadic
);
88 template<typename VectorType
>
89 inline LType
functionType(LType returnType
, const VectorType
& vector
, Variadicity variadicity
= NotVariadic
)
91 return functionType(returnType
, vector
.begin(), vector
.size(), variadicity
);
93 static inline LType
functionType(LType returnType
, Variadicity variadicity
= NotVariadic
)
95 return functionType(returnType
, 0, 0, variadicity
);
97 static inline LType
functionType(LType returnType
, LType param1
, Variadicity variadicity
= NotVariadic
)
99 return functionType(returnType
, ¶m1
, 1, variadicity
);
101 static inline LType
functionType(LType returnType
, LType param1
, LType param2
, Variadicity variadicity
= NotVariadic
)
103 LType paramTypes
[] = { param1
, param2
};
104 return functionType(returnType
, paramTypes
, 2, variadicity
);
106 static inline LType
functionType(LType returnType
, LType param1
, LType param2
, LType param3
, Variadicity variadicity
= NotVariadic
)
108 LType paramTypes
[] = { param1
, param2
, param3
};
109 return functionType(returnType
, paramTypes
, 3, variadicity
);
111 static inline LType
functionType(LType returnType
, LType param1
, LType param2
, LType param3
, LType param4
, Variadicity variadicity
= NotVariadic
)
113 LType paramTypes
[] = { param1
, param2
, param3
, param4
};
114 return functionType(returnType
, paramTypes
, 4, variadicity
);
116 static inline LType
functionType(LType returnType
, LType param1
, LType param2
, LType param3
, LType param4
, LType param5
, Variadicity variadicity
= NotVariadic
)
118 LType paramTypes
[] = { param1
, param2
, param3
, param4
, param5
};
119 return functionType(returnType
, paramTypes
, 5, variadicity
);
121 static inline LType
functionType(LType returnType
, LType param1
, LType param2
, LType param3
, LType param4
, LType param5
, LType param6
, Variadicity variadicity
= NotVariadic
)
123 LType paramTypes
[] = { param1
, param2
, param3
, param4
, param5
, param6
};
124 return functionType(returnType
, paramTypes
, 6, variadicity
);
127 static inline LType
typeOf(LValue value
) { return llvm
->TypeOf(value
); }
129 static inline LType
getElementType(LType value
) { return llvm
->GetElementType(value
); }
131 static inline unsigned mdKindID(LContext context
, const char* string
) { return llvm
->GetMDKindIDInContext(context
, string
, std::strlen(string
)); }
132 static inline LValue
mdString(LContext context
, const char* string
, unsigned length
) { return llvm
->MDStringInContext(context
, string
, length
); }
133 static inline LValue
mdString(LContext context
, const char* string
) { return mdString(context
, string
, std::strlen(string
)); }
134 static inline LValue
mdNode(LContext context
, LValue
* args
, unsigned numArgs
) { return llvm
->MDNodeInContext(context
, args
, numArgs
); }
135 template<typename VectorType
>
136 static inline LValue
mdNode(LContext context
, const VectorType
& vector
) { return mdNode(context
, const_cast<LValue
*>(vector
.begin()), vector
.size()); }
137 static inline LValue
mdNode(LContext context
) { return mdNode(context
, 0, 0); }
138 static inline LValue
mdNode(LContext context
, LValue arg1
) { return mdNode(context
, &arg1
, 1); }
139 static inline LValue
mdNode(LContext context
, LValue arg1
, LValue arg2
)
141 LValue args
[] = { arg1
, arg2
};
142 return mdNode(context
, args
, 2);
144 static inline LValue
mdNode(LContext context
, LValue arg1
, LValue arg2
, LValue arg3
)
146 LValue args
[] = { arg1
, arg2
, arg3
};
147 return mdNode(context
, args
, 3);
150 static inline void setMetadata(LValue instruction
, unsigned kind
, LValue metadata
) { llvm
->SetMetadata(instruction
, kind
, metadata
); }
152 static inline LValue
getFirstInstruction(LBasicBlock block
) { return llvm
->GetFirstInstruction(block
); }
153 static inline LValue
getNextInstruction(LValue instruction
) { return llvm
->GetNextInstruction(instruction
); }
156 static inline LValue
addFunction(LModule
module, const char* name
, LType type
) { return llvm
->AddFunction(module, name
, type
); }
157 static inline LValue
getNamedFunction(LModule
module, const char* name
) { return llvm
->GetNamedFunction(module, name
); }
158 static inline LValue
getFirstFunction(LModule
module) { return llvm
->GetFirstFunction(module); }
159 static inline LValue
getNextFunction(LValue function
) { return llvm
->GetNextFunction(function
); }
161 static inline void setFunctionCallingConv(LValue function
, LCallConv convention
) { llvm
->SetFunctionCallConv(function
, convention
); }
162 static inline void addTargetDependentFunctionAttr(LValue function
, const char* key
, const char* value
) { llvm
->AddTargetDependentFunctionAttr(function
, key
, value
); }
163 static inline void removeFunctionAttr(LValue function
, LLVMAttribute pa
) { llvm
->RemoveFunctionAttr(function
, pa
); }
165 static inline LLVMLinkage
getLinkage(LValue global
) { return llvm
->GetLinkage(global
); }
166 static inline void setLinkage(LValue global
, LLVMLinkage linkage
) { llvm
->SetLinkage(global
, linkage
); }
167 static inline void setVisibility(LValue global
, LLVMVisibility viz
) { llvm
->SetVisibility(global
, viz
); }
168 static inline LLVMBool
isDeclaration(LValue global
) { return llvm
->IsDeclaration(global
); }
170 static inline LLVMBool
linkModules(LModule dest
, LModule str
, LLVMLinkerMode mode
, char** outMessage
) { return llvm
->LinkModules(dest
, str
, mode
, outMessage
); }
172 static inline const char * getValueName(LValue global
) { return llvm
->GetValueName(global
); }
174 static inline LValue
getNamedGlobal(LModule
module, const char* name
) { return llvm
->GetNamedGlobal(module, name
); }
175 static inline LValue
getFirstGlobal(LModule
module) { return llvm
->GetFirstGlobal(module); }
176 static inline LValue
getNextGlobal(LValue global
) { return llvm
->GetNextGlobal(global
); }
178 static inline LValue
addExternFunction(LModule
module, const char* name
, LType type
)
180 LValue result
= addFunction(module, name
, type
);
181 setLinkage(result
, LLVMExternalLinkage
);
185 static inline LLVMBool
createMemoryBufferWithContentsOfFile(const char* path
, LLVMMemoryBufferRef
* outMemBuf
, char** outMessage
)
187 return llvm
->CreateMemoryBufferWithContentsOfFile(path
, outMemBuf
, outMessage
);
191 static inline LLVMBool
parseBitcodeInContext(LLVMContextRef contextRef
, LLVMMemoryBufferRef memBuf
, LModule
*outModule
, char **outMessage
)
193 return llvm
->ParseBitcodeInContext(contextRef
, memBuf
, outModule
, outMessage
);
197 static inline void disposeMemoryBuffer(LLVMMemoryBufferRef memBuf
){ llvm
->DisposeMemoryBuffer(memBuf
); }
200 static inline LModule
moduleCreateWithNameInContext(const char* moduleID
, LContext context
){ return llvm
->ModuleCreateWithNameInContext(moduleID
, context
); }
201 static inline void disposeModule(LModule m
){ llvm
->DisposeModule(m
); }
203 static inline void disposeMessage(char* outMsg
) { llvm
->DisposeMessage(outMsg
); }
205 static inline LValue
getParam(LValue function
, unsigned index
) { return llvm
->GetParam(function
, index
); }
207 static inline void getParamTypes(LType function
, LType
* dest
) { return llvm
->GetParamTypes(function
, dest
); }
208 static inline LValue
getUndef(LType type
) { return llvm
->GetUndef(type
); }
210 enum BitExtension
{ ZeroExtend
, SignExtend
};
211 static inline LValue
constInt(LType type
, unsigned long long value
, BitExtension extension
= ZeroExtend
) { return llvm
->ConstInt(type
, value
, extension
== SignExtend
); }
212 static inline LValue
constReal(LType type
, double value
) { return llvm
->ConstReal(type
, value
); }
213 static inline LValue
constIntToPtr(LValue value
, LType type
) { return llvm
->ConstIntToPtr(value
, type
); }
214 static inline LValue
constNull(LType type
) { return llvm
->ConstNull(type
); }
215 static inline LValue
constBitCast(LValue value
, LType type
) { return llvm
->ConstBitCast(value
, type
); }
217 static inline LBasicBlock
getFirstBasicBlock(LValue function
) { return llvm
->GetFirstBasicBlock(function
); }
218 static inline LBasicBlock
getNextBasicBlock(LBasicBlock block
) { return llvm
->GetNextBasicBlock(block
); }
220 static inline LBasicBlock
appendBasicBlock(LContext context
, LValue function
, const char* name
= "") { return llvm
->AppendBasicBlockInContext(context
, function
, name
); }
221 static inline LBasicBlock
insertBasicBlock(LContext context
, LBasicBlock beforeBasicBlock
, const char* name
= "") { return llvm
->InsertBasicBlockInContext(context
, beforeBasicBlock
, name
); }
223 static inline LValue
buildPhi(LBuilder builder
, LType type
) { return llvm
->BuildPhi(builder
, type
, ""); }
224 static inline void addIncoming(LValue phi
, const LValue
* values
, const LBasicBlock
* blocks
, unsigned numPredecessors
)
226 llvm
->AddIncoming(phi
, const_cast<LValue
*>(values
), const_cast<LBasicBlock
*>(blocks
), numPredecessors
);
228 static inline void addIncoming(LValue phi
, ValueFromBlock value1
)
230 LValue value
= value1
.value();
231 LBasicBlock block
= value1
.block();
232 addIncoming(phi
, &value
, &block
, 1);
234 static inline void addIncoming(LValue phi
, ValueFromBlock value1
, ValueFromBlock value2
)
236 LValue values
[] = { value1
.value(), value2
.value() };
237 LBasicBlock blocks
[] = { value1
.block(), value2
.block() };
238 addIncoming(phi
, values
, blocks
, 2);
240 static inline LValue
buildPhi(LBuilder builder
, LType type
, ValueFromBlock value1
)
242 LValue result
= buildPhi(builder
, type
);
243 addIncoming(result
, value1
);
246 static inline LValue
buildPhi(
247 LBuilder builder
, LType type
, ValueFromBlock value1
, ValueFromBlock value2
)
249 LValue result
= buildPhi(builder
, type
);
250 addIncoming(result
, value1
, value2
);
254 static inline LValue
buildAlloca(LBuilder builder
, LType type
) { return llvm
->BuildAlloca(builder
, type
, ""); }
255 static inline LValue
buildAdd(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildAdd(builder
, left
, right
, ""); }
256 static inline LValue
buildSub(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildSub(builder
, left
, right
, ""); }
257 static inline LValue
buildMul(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildMul(builder
, left
, right
, ""); }
258 static inline LValue
buildDiv(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildSDiv(builder
, left
, right
, ""); }
259 static inline LValue
buildRem(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildSRem(builder
, left
, right
, ""); }
260 static inline LValue
buildNeg(LBuilder builder
, LValue value
) { return llvm
->BuildNeg(builder
, value
, ""); }
261 static inline LValue
buildFAdd(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildFAdd(builder
, left
, right
, ""); }
262 static inline LValue
buildFSub(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildFSub(builder
, left
, right
, ""); }
263 static inline LValue
buildFMul(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildFMul(builder
, left
, right
, ""); }
264 static inline LValue
buildFDiv(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildFDiv(builder
, left
, right
, ""); }
265 static inline LValue
buildFRem(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildFRem(builder
, left
, right
, ""); }
266 static inline LValue
buildFNeg(LBuilder builder
, LValue value
) { return llvm
->BuildFNeg(builder
, value
, ""); }
267 static inline LValue
buildAnd(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildAnd(builder
, left
, right
, ""); }
268 static inline LValue
buildOr(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildOr(builder
, left
, right
, ""); }
269 static inline LValue
buildXor(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildXor(builder
, left
, right
, ""); }
270 static inline LValue
buildShl(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildShl(builder
, left
, right
, ""); }
271 static inline LValue
buildAShr(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildAShr(builder
, left
, right
, ""); }
272 static inline LValue
buildLShr(LBuilder builder
, LValue left
, LValue right
) { return llvm
->BuildLShr(builder
, left
, right
, ""); }
273 static inline LValue
buildNot(LBuilder builder
, LValue value
) { return llvm
->BuildNot(builder
, value
, ""); }
274 static inline LValue
buildLoad(LBuilder builder
, LValue pointer
) { return llvm
->BuildLoad(builder
, pointer
, ""); }
275 static inline LValue
buildStore(LBuilder builder
, LValue value
, LValue pointer
) { return llvm
->BuildStore(builder
, value
, pointer
); }
276 static inline LValue
buildSExt(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildSExt(builder
, value
, type
, ""); }
277 static inline LValue
buildZExt(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildZExt(builder
, value
, type
, ""); }
278 static inline LValue
buildFPToSI(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildFPToSI(builder
, value
, type
, ""); }
279 static inline LValue
buildFPToUI(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildFPToUI(builder
, value
, type
, ""); }
280 static inline LValue
buildSIToFP(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildSIToFP(builder
, value
, type
, ""); }
281 static inline LValue
buildUIToFP(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildUIToFP(builder
, value
, type
, ""); }
282 static inline LValue
buildIntCast(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildIntCast(builder
, value
, type
, ""); }
283 static inline LValue
buildFPCast(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildFPCast(builder
, value
, type
, ""); }
284 static inline LValue
buildIntToPtr(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildIntToPtr(builder
, value
, type
, ""); }
285 static inline LValue
buildPtrToInt(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildPtrToInt(builder
, value
, type
, ""); }
286 static inline LValue
buildBitCast(LBuilder builder
, LValue value
, LType type
) { return llvm
->BuildBitCast(builder
, value
, type
, ""); }
287 static inline LValue
buildICmp(LBuilder builder
, LIntPredicate cond
, LValue left
, LValue right
) { return llvm
->BuildICmp(builder
, cond
, left
, right
, ""); }
288 static inline LValue
buildFCmp(LBuilder builder
, LRealPredicate cond
, LValue left
, LValue right
) { return llvm
->BuildFCmp(builder
, cond
, left
, right
, ""); }
289 static inline LValue
buildInsertElement(LBuilder builder
, LValue vector
, LValue element
, LValue index
) { return llvm
->BuildInsertElement(builder
, vector
, element
, index
, ""); }
291 enum SynchronizationScope
{ SingleThread
, CrossThread
};
292 static inline LValue
buildFence(LBuilder builder
, LAtomicOrdering ordering
, SynchronizationScope scope
= CrossThread
)
294 return llvm
->BuildFence(builder
, ordering
, scope
== SingleThread
, "");
297 static inline LValue
buildCall(LBuilder builder
, LValue function
, const LValue
* args
, unsigned numArgs
)
299 return llvm
->BuildCall(builder
, function
, const_cast<LValue
*>(args
), numArgs
, "");
301 template<typename VectorType
>
302 inline LValue
buildCall(LBuilder builder
, LValue function
, const VectorType
& vector
)
304 return buildCall(builder
, function
, vector
.begin(), vector
.size());
306 static inline LValue
buildCall(LBuilder builder
, LValue function
)
308 return buildCall(builder
, function
, 0, 0);
310 static inline LValue
buildCall(LBuilder builder
, LValue function
, LValue arg1
)
312 return buildCall(builder
, function
, &arg1
, 1);
314 template<typename
... Args
>
315 LValue
buildCall(LBuilder builder
, LValue function
, LValue arg1
, Args
... args
)
317 LValue argsArray
[] = { arg1
, args
... };
318 return buildCall(builder
, function
, argsArray
, sizeof(argsArray
) / sizeof(LValue
));
321 static inline void setInstructionCallingConvention(LValue instruction
, LCallConv callingConvention
) { llvm
->SetInstructionCallConv(instruction
, callingConvention
); }
322 static inline LValue
buildExtractValue(LBuilder builder
, LValue aggVal
, unsigned index
) { return llvm
->BuildExtractValue(builder
, aggVal
, index
, ""); }
323 static inline LValue
buildSelect(LBuilder builder
, LValue condition
, LValue taken
, LValue notTaken
) { return llvm
->BuildSelect(builder
, condition
, taken
, notTaken
, ""); }
324 static inline LValue
buildBr(LBuilder builder
, LBasicBlock destination
) { return llvm
->BuildBr(builder
, destination
); }
325 static inline LValue
buildCondBr(LBuilder builder
, LValue condition
, LBasicBlock taken
, LBasicBlock notTaken
) { return llvm
->BuildCondBr(builder
, condition
, taken
, notTaken
); }
326 static inline LValue
buildSwitch(LBuilder builder
, LValue value
, LBasicBlock fallThrough
, unsigned numCases
) { return llvm
->BuildSwitch(builder
, value
, fallThrough
, numCases
); }
327 static inline void addCase(LValue switchInst
, LValue value
, LBasicBlock target
) { llvm
->AddCase(switchInst
, value
, target
); }
328 template<typename VectorType
>
329 static inline LValue
buildSwitch(LBuilder builder
, LValue value
, const VectorType
& cases
, LBasicBlock fallThrough
)
331 LValue result
= buildSwitch(builder
, value
, fallThrough
, cases
.size());
332 for (unsigned i
= 0; i
< cases
.size(); ++i
)
333 addCase(result
, cases
[i
].value(), cases
[i
].target());
336 static inline LValue
buildRet(LBuilder builder
, LValue value
) { return llvm
->BuildRet(builder
, value
); }
337 static inline LValue
buildUnreachable(LBuilder builder
) { return llvm
->BuildUnreachable(builder
); }
339 static inline void dumpModule(LModule
module) { llvm
->DumpModule(module); }
340 static inline void verifyModule(LModule
module)
343 llvm
->VerifyModule(module, LLVMAbortProcessAction
, &error
);
344 llvm
->DisposeMessage(error
);
347 } } // namespace JSC::FTL
349 #endif // ENABLE(FTL_JIT)
351 #endif // FTLAbbreviations_h