Merge r169628 from ftlopt.
[WebKit-https.git] / Source / JavaScriptCore / ftl / FTLAbbreviations.h
index dca9abc..addbed7 100644 (file)
 #ifndef FTLAbbreviations_h
 #define FTLAbbreviations_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(FTL_JIT)
 
-#include "FTLLLVMHeaders.h"
+#include "FTLAbbreviatedTypes.h"
+#include "FTLValueFromBlock.h"
+#include "LLVMAPI.h"
+#include <cstring>
 
 namespace JSC { namespace FTL {
 
@@ -43,49 +44,43 @@ namespace JSC { namespace FTL {
 #error "The FTL backend assumes that pointers are 64-bit."
 #endif
 
-typedef LLVMBasicBlockRef LBasicBlock;
-typedef LLVMBuilderRef LBuilder;
-typedef LLVMCallConv LCallConv;
-typedef LLVMIntPredicate LIntPredicate;
-typedef LLVMRealPredicate LRealPredicate;
-typedef LLVMLinkage LLinkage;
-typedef LLVMModuleRef LModule;
-typedef LLVMTypeRef LType;
-typedef LLVMValueRef LValue;
-
-static inline LType voidType() { return LLVMVoidType(); }
-static inline LType int1Type() { return LLVMInt1Type(); }
-static inline LType int8Type() { return LLVMInt8Type(); }
-static inline LType int32Type() { return LLVMInt32Type(); }
-static inline LType int64Type() { return LLVMInt64Type(); }
-static inline LType intPtrType() { return LLVMInt64Type(); }
-static inline LType doubleType() { return LLVMDoubleType(); }
-
-static inline LType pointerType(LType type) { return LLVMPointerType(type, 0); }
+static inline LType voidType(LContext context) { return llvm->VoidTypeInContext(context); }
+static inline LType int1Type(LContext context) { return llvm->Int1TypeInContext(context); }
+static inline LType int8Type(LContext context) { return llvm->Int8TypeInContext(context); }
+static inline LType int16Type(LContext context) { return llvm->Int16TypeInContext(context); }
+static inline LType int32Type(LContext context) { return llvm->Int32TypeInContext(context); }
+static inline LType int64Type(LContext context) { return llvm->Int64TypeInContext(context); }
+static inline LType intPtrType(LContext context) { return llvm->Int64TypeInContext(context); }
+static inline LType floatType(LContext context) { return llvm->FloatTypeInContext(context); }
+static inline LType doubleType(LContext context) { return llvm->DoubleTypeInContext(context); }
+
+static inline LType pointerType(LType type) { return llvm->PointerType(type, 0); }
+static inline LType arrayType(LType type, unsigned count) { return llvm->ArrayType(type, count); }
+static inline LType vectorType(LType type, unsigned count) { return llvm->VectorType(type, count); }
 
 enum PackingMode { NotPacked, Packed };
-static inline LType structType(LType* elementTypes, unsigned elementCount, PackingMode packing = NotPacked)
+static inline LType structType(LContext context, LType* elementTypes, unsigned elementCount, PackingMode packing = NotPacked)
 {
-    return LLVMStructType(elementTypes, elementCount, packing == Packed);
+    return llvm->StructTypeInContext(context, elementTypes, elementCount, packing == Packed);
 }
-static inline LType structType(PackingMode packing = NotPacked)
+static inline LType structType(LContext context, PackingMode packing = NotPacked)
 {
-    return structType(0, 0, packing);
+    return structType(context, 0, 0, packing);
 }
-static inline LType structType(LType element1, PackingMode packing = NotPacked)
+static inline LType structType(LContext context, LType element1, PackingMode packing = NotPacked)
 {
-    return structType(&element1, 1, packing);
+    return structType(context, &element1, 1, packing);
 }
-static inline LType structType(LType element1, LType element2, PackingMode packing = NotPacked)
+static inline LType structType(LContext context, LType element1, LType element2, PackingMode packing = NotPacked)
 {
     LType elements[] = { element1, element2 };
-    return structType(elements, 2, packing);
+    return structType(context, elements, 2, packing);
 }
 
 enum Variadicity { NotVariadic, Variadic };
 static inline LType functionType(LType returnType, const LType* paramTypes, unsigned paramCount, Variadicity variadicity)
 {
-    return LLVMFunctionType(returnType, const_cast<LType*>(paramTypes), paramCount, variadicity == Variadic);
+    return llvm->FunctionType(returnType, const_cast<LType*>(paramTypes), paramCount, variadicity == Variadic);
 }
 template<typename VectorType>
 inline LType functionType(LType returnType, const VectorType& vector, Variadicity variadicity = NotVariadic)
@@ -105,26 +100,72 @@ static inline LType functionType(LType returnType, LType param1, LType param2, V
     LType paramTypes[] = { param1, param2 };
     return functionType(returnType, paramTypes, 2, variadicity);
 }
+static inline LType functionType(LType returnType, LType param1, LType param2, LType param3, Variadicity variadicity = NotVariadic)
+{
+    LType paramTypes[] = { param1, param2, param3 };
+    return functionType(returnType, paramTypes, 3, variadicity);
+}
+static inline LType functionType(LType returnType, LType param1, LType param2, LType param3, LType param4, Variadicity variadicity = NotVariadic)
+{
+    LType paramTypes[] = { param1, param2, param3, param4 };
+    return functionType(returnType, paramTypes, 4, variadicity);
+}
+
+static inline LType typeOf(LValue value) { return llvm->TypeOf(value); }
 
-static inline LType typeOf(LValue value) { return LLVMTypeOf(value); }
+static inline LType getElementType(LType value) { return llvm->GetElementType(value); }
 
-static inline unsigned mdKindID(const char* string) { return LLVMGetMDKindID(string, strlen(string)); }
-static inline LValue mdString(const char* string, unsigned length) { return LLVMMDString(string, length); }
-static inline LValue mdString(const char* string) { return mdString(string, strlen(string)); }
-static inline LValue mdNode(LValue* args, unsigned numArgs) { return LLVMMDNode(args, numArgs); }
-static inline LValue mdNode() { return mdNode(0, 0); }
-static inline LValue mdNode(LValue arg1) { return mdNode(&arg1, 1); }
-static inline LValue mdNode(LValue arg1, LValue arg2)
+static inline unsigned mdKindID(LContext context, const char* string) { return llvm->GetMDKindIDInContext(context, string, std::strlen(string)); }
+static inline LValue mdString(LContext context, const char* string, unsigned length) { return llvm->MDStringInContext(context, string, length); }
+static inline LValue mdString(LContext context, const char* string) { return mdString(context, string, std::strlen(string)); }
+static inline LValue mdNode(LContext context, LValue* args, unsigned numArgs) { return llvm->MDNodeInContext(context, args, numArgs); }
+template<typename VectorType>
+static inline LValue mdNode(LContext context, const VectorType& vector) { return mdNode(context, const_cast<LValue*>(vector.begin()), vector.size()); }
+static inline LValue mdNode(LContext context) { return mdNode(context, 0, 0); }
+static inline LValue mdNode(LContext context, LValue arg1) { return mdNode(context, &arg1, 1); }
+static inline LValue mdNode(LContext context, LValue arg1, LValue arg2)
 {
     LValue args[] = { arg1, arg2 };
-    return mdNode(args, 2);
+    return mdNode(context, args, 2);
+}
+static inline LValue mdNode(LContext context, LValue arg1, LValue arg2, LValue arg3)
+{
+    LValue args[] = { arg1, arg2, arg3 };
+    return mdNode(context, args, 3);
 }
 
-static inline void setMetadata(LValue instruction, unsigned kind, LValue metadata) { LLVMSetMetadata(instruction, kind, metadata); }
+static inline void setMetadata(LValue instruction, unsigned kind, LValue metadata) { llvm->SetMetadata(instruction, kind, metadata); }
+
+static inline LValue getFirstInstruction(LBasicBlock block) { return llvm->GetFirstInstruction(block); }
+static inline LValue getNextInstruction(LValue instruction) { return llvm->GetNextInstruction(instruction); }
+
+
+static inline LValue addFunction(LModule module, const char* name, LType type) { return llvm->AddFunction(module, name, type); }
+static inline LValue getNamedFunction(LModule module, const char* name) { return llvm->GetNamedFunction(module, name); }
+static inline LValue getFirstFunction(LModule module) { return llvm->GetFirstFunction(module); }
+static inline LValue getNextFunction(LValue function) { return llvm->GetNextFunction(function); }
+
+static inline void setFunctionCallingConv(LValue function, LCallConv convention) { llvm->SetFunctionCallConv(function, convention); }
+static inline void addTargetDependentFunctionAttr(LValue function, const char* key, const char* value) { llvm->AddTargetDependentFunctionAttr(function, key, value); }
+static inline void removeFunctionAttr(LValue function, LLVMAttribute pa) { llvm->RemoveFunctionAttr(function, pa); }
+
+
+
+static inline void setLinkage(LValue global, LLVMLinkage linkage) { llvm->SetLinkage(global, linkage); }
+static inline void setVisibility(LValue global, LLVMVisibility viz) { llvm->SetVisibility(global, viz); }
+static inline LLVMBool isDeclaration(LValue global) { return llvm->IsDeclaration(global); }
+
+static inline LLVMBool linkModules(LModule dest, LModule str, LLVMLinkerMode mode, char** outMessage) { return llvm->LinkModules(dest, str, mode, outMessage); }
+
+static inline const char * getValueName(LValue global) { return llvm->GetValueName(global); }
+
+static inline LValue getNamedGlobal(LModule module, const char* name) { return llvm->GetNamedGlobal(module, name); }
+static inline LValue getFirstGlobal(LModule module) { return llvm->GetFirstGlobal(module); }
+static inline LValue getNextGlobal(LValue global) { return llvm->GetNextGlobal(global); }
+
+
+
 
-static inline LValue addFunction(LModule module, const char* name, LType type) { return LLVMAddFunction(module, name, type); }
-static inline void setLinkage(LValue global, LLinkage linkage) { LLVMSetLinkage(global, linkage); }
-static inline void setFunctionCallingConv(LValue function, LCallConv convention) { LLVMSetFunctionCallConv(function, convention); }
 
 static inline LValue addExternFunction(LModule module, const char* name, LType type)
 {
@@ -133,83 +174,119 @@ static inline LValue addExternFunction(LModule module, const char* name, LType t
     return result;
 }
 
-static inline LValue getParam(LValue function, unsigned index) { return LLVMGetParam(function, index); }
+static inline LLVMBool createMemoryBufferWithContentsOfFile(const char* path, LLVMMemoryBufferRef* outMemBuf, char** outMessage) 
+{ 
+    return llvm->CreateMemoryBufferWithContentsOfFile(path, outMemBuf, outMessage); 
+}
+
+
+static inline LLVMBool parseBitcodeInContext(LLVMContextRef contextRef, LLVMMemoryBufferRef memBuf, LModule *outModule, char **outMessage)
+{ 
+    return llvm->ParseBitcodeInContext(contextRef, memBuf, outModule, outMessage); 
+}
+
+
+static inline void disposeMemoryBuffer(LLVMMemoryBufferRef memBuf){ llvm->DisposeMemoryBuffer(memBuf); }
+
+
+static inline LModule moduleCreateWithNameInContext(const char* moduleID, LContext context){ return llvm->ModuleCreateWithNameInContext(moduleID, context); }
+static inline void disposeModule(LModule m){ llvm->DisposeModule(m); }
+
+static inline LValue getParam(LValue function, unsigned index) { return llvm->GetParam(function, index); }
+
+static inline void getParamTypes(LType function, LType* dest) { return llvm->GetParamTypes(function, dest); }
+static inline LValue getUndef(LType type) { return llvm->GetUndef(type); }
 
 enum BitExtension { ZeroExtend, SignExtend };
-static inline LValue constInt(LType type, unsigned long long value, BitExtension extension) { return LLVMConstInt(type, value, extension == SignExtend); }
-static inline LValue constReal(LType type, double value) { return LLVMConstReal(type, value); }
-static inline LValue constIntToPtr(LValue value, LType type) { return LLVMConstIntToPtr(value, type); }
-static inline LValue constBitCast(LValue value, LType type) { return LLVMConstBitCast(value, type); }
+static inline LValue constInt(LType type, unsigned long long value, BitExtension extension = ZeroExtend) { return llvm->ConstInt(type, value, extension == SignExtend); }
+static inline LValue constReal(LType type, double value) { return llvm->ConstReal(type, value); }
+static inline LValue constIntToPtr(LValue value, LType type) { return llvm->ConstIntToPtr(value, type); }
+static inline LValue constNull(LType type) { return llvm->ConstNull(type); }
+static inline LValue constBitCast(LValue value, LType type) { return llvm->ConstBitCast(value, type); }
+
+static inline LBasicBlock getFirstBasicBlock(LValue function) { return llvm->GetFirstBasicBlock(function); }
+static inline LBasicBlock getNextBasicBlock(LBasicBlock block) { return llvm->GetNextBasicBlock(block); }
 
-static inline LBasicBlock appendBasicBlock(LValue function, const char* name = "") { return LLVMAppendBasicBlock(function, name); }
-static inline LBasicBlock insertBasicBlock(LBasicBlock beforeBasicBlock, const char* name = "") { return LLVMInsertBasicBlock(beforeBasicBlock, name); }
+static inline LBasicBlock appendBasicBlock(LContext context, LValue function, const char* name = "") { return llvm->AppendBasicBlockInContext(context, function, name); }
+static inline LBasicBlock insertBasicBlock(LContext context, LBasicBlock beforeBasicBlock, const char* name = "") { return llvm->InsertBasicBlockInContext(context, beforeBasicBlock, name); }
 
-static inline LValue buildPhi(LBuilder builder, LType type) { return LLVMBuildPhi(builder, type, ""); }
+static inline LValue buildPhi(LBuilder builder, LType type) { return llvm->BuildPhi(builder, type, ""); }
 static inline void addIncoming(LValue phi, const LValue* values, const LBasicBlock* blocks, unsigned numPredecessors)
 {
-    LLVMAddIncoming(phi, const_cast<LValue*>(values), const_cast<LBasicBlock*>(blocks), numPredecessors);
-}
-template<typename ValueVectorType, typename BlockVectorType>
-static inline void addIncoming(LValue phi, const ValueVectorType& values, const BlockVectorType& blocks)
-{
-    ASSERT(values.size() == blocks.size());
-    addIncoming(phi, values.begin(), blocks.begin(), values.size());
+    llvm->AddIncoming(phi, const_cast<LValue*>(values), const_cast<LBasicBlock*>(blocks), numPredecessors);
 }
-static inline void addIncoming(LValue phi, LValue value1, LBasicBlock block1)
+static inline void addIncoming(LValue phi, ValueFromBlock value1)
 {
-    addIncoming(phi, &value1, &block1, 1);
+    LValue value = value1.value();
+    LBasicBlock block = value1.block();
+    addIncoming(phi, &value, &block, 1);
 }
-static inline void addIncoming(LValue phi, LValue value1, LBasicBlock block1, LValue value2, LBasicBlock block2)
+static inline void addIncoming(LValue phi, ValueFromBlock value1, ValueFromBlock value2)
 {
-    LValue values[] = { value1, value2 };
-    LBasicBlock blocks[] = { block1, block2 };
+    LValue values[] = { value1.value(), value2.value() };
+    LBasicBlock blocks[] = { value1.block(), value2.block() };
     addIncoming(phi, values, blocks, 2);
 }
-static inline LValue buildPhi(LBuilder builder, LType type, LValue value1, LBasicBlock block1)
+static inline LValue buildPhi(LBuilder builder, LType type, ValueFromBlock value1)
 {
     LValue result = buildPhi(builder, type);
-    addIncoming(result, value1, block1);
+    addIncoming(result, value1);
     return result;
 }
 static inline LValue buildPhi(
-    LBuilder builder, LType type, LValue value1, LBasicBlock block1, LValue value2,
-    LBasicBlock block2)
+    LBuilder builder, LType type, ValueFromBlock value1, ValueFromBlock value2)
 {
     LValue result = buildPhi(builder, type);
-    addIncoming(result, value1, block1, value2, block2);
+    addIncoming(result, value1, value2);
     return result;
 }
 
-static inline LValue buildAlloca(LBuilder builder, LType type) { return LLVMBuildAlloca(builder, type, ""); }
-static inline LValue buildAdd(LBuilder builder, LValue left, LValue right) { return LLVMBuildAdd(builder, left, right, ""); }
-static inline LValue buildSub(LBuilder builder, LValue left, LValue right) { return LLVMBuildSub(builder, left, right, ""); }
-static inline LValue buildMul(LBuilder builder, LValue left, LValue right) { return LLVMBuildMul(builder, left, right, ""); }
-static inline LValue buildNeg(LBuilder builder, LValue value) { return LLVMBuildNeg(builder, value, ""); }
-static inline LValue buildFAdd(LBuilder builder, LValue left, LValue right) { return LLVMBuildFAdd(builder, left, right, ""); }
-static inline LValue buildFSub(LBuilder builder, LValue left, LValue right) { return LLVMBuildFSub(builder, left, right, ""); }
-static inline LValue buildFMul(LBuilder builder, LValue left, LValue right) { return LLVMBuildFMul(builder, left, right, ""); }
-static inline LValue buildFNeg(LBuilder builder, LValue value) { return LLVMBuildFNeg(builder, value, ""); }
-static inline LValue buildAnd(LBuilder builder, LValue left, LValue right) { return LLVMBuildAnd(builder, left, right, ""); }
-static inline LValue buildOr(LBuilder builder, LValue left, LValue right) { return LLVMBuildOr(builder, left, right, ""); }
-static inline LValue buildXor(LBuilder builder, LValue left, LValue right) { return LLVMBuildXor(builder, left, right, ""); }
-static inline LValue buildShl(LBuilder builder, LValue left, LValue right) { return LLVMBuildShl(builder, left, right, ""); }
-static inline LValue buildAShr(LBuilder builder, LValue left, LValue right) { return LLVMBuildAShr(builder, left, right, ""); }
-static inline LValue buildLShr(LBuilder builder, LValue left, LValue right) { return LLVMBuildLShr(builder, left, right, ""); }
-static inline LValue buildNot(LBuilder builder, LValue value) { return LLVMBuildNot(builder, value, ""); }
-static inline LValue buildLoad(LBuilder builder, LValue pointer) { return LLVMBuildLoad(builder, pointer, ""); }
-static inline LValue buildStore(LBuilder builder, LValue value, LValue pointer) { return LLVMBuildStore(builder, value, pointer); }
-static inline LValue buildZExt(LBuilder builder, LValue value, LType type) { return LLVMBuildZExt(builder, value, type, ""); }
-static inline LValue buildSIToFP(LBuilder builder, LValue value, LType type) { return LLVMBuildSIToFP(builder, value, type, ""); }
-static inline LValue buildUIToFP(LBuilder builder, LValue value, LType type) { return LLVMBuildUIToFP(builder, value, type, ""); }
-static inline LValue buildIntCast(LBuilder builder, LValue value, LType type) { return LLVMBuildIntCast(builder, value, type, ""); }
-static inline LValue buildIntToPtr(LBuilder builder, LValue value, LType type) { return LLVMBuildIntToPtr(builder, value, type, ""); }
-static inline LValue buildPtrToInt(LBuilder builder, LValue value, LType type) { return LLVMBuildPtrToInt(builder, value, type, ""); }
-static inline LValue buildBitCast(LBuilder builder, LValue value, LType type) { return LLVMBuildBitCast(builder, value, type, ""); }
-static inline LValue buildICmp(LBuilder builder, LIntPredicate cond, LValue left, LValue right) { return LLVMBuildICmp(builder, cond, left, right, ""); }
-static inline LValue buildFCmp(LBuilder builder, LRealPredicate cond, LValue left, LValue right) { return LLVMBuildFCmp(builder, cond, left, right, ""); }
+static inline LValue buildAlloca(LBuilder builder, LType type) { return llvm->BuildAlloca(builder, type, ""); }
+static inline LValue buildAdd(LBuilder builder, LValue left, LValue right) { return llvm->BuildAdd(builder, left, right, ""); }
+static inline LValue buildSub(LBuilder builder, LValue left, LValue right) { return llvm->BuildSub(builder, left, right, ""); }
+static inline LValue buildMul(LBuilder builder, LValue left, LValue right) { return llvm->BuildMul(builder, left, right, ""); }
+static inline LValue buildDiv(LBuilder builder, LValue left, LValue right) { return llvm->BuildSDiv(builder, left, right, ""); }
+static inline LValue buildRem(LBuilder builder, LValue left, LValue right) { return llvm->BuildSRem(builder, left, right, ""); }
+static inline LValue buildNeg(LBuilder builder, LValue value) { return llvm->BuildNeg(builder, value, ""); }
+static inline LValue buildFAdd(LBuilder builder, LValue left, LValue right) { return llvm->BuildFAdd(builder, left, right, ""); }
+static inline LValue buildFSub(LBuilder builder, LValue left, LValue right) { return llvm->BuildFSub(builder, left, right, ""); }
+static inline LValue buildFMul(LBuilder builder, LValue left, LValue right) { return llvm->BuildFMul(builder, left, right, ""); }
+static inline LValue buildFDiv(LBuilder builder, LValue left, LValue right) { return llvm->BuildFDiv(builder, left, right, ""); }
+static inline LValue buildFRem(LBuilder builder, LValue left, LValue right) { return llvm->BuildFRem(builder, left, right, ""); }
+static inline LValue buildFNeg(LBuilder builder, LValue value) { return llvm->BuildFNeg(builder, value, ""); }
+static inline LValue buildAnd(LBuilder builder, LValue left, LValue right) { return llvm->BuildAnd(builder, left, right, ""); }
+static inline LValue buildOr(LBuilder builder, LValue left, LValue right) { return llvm->BuildOr(builder, left, right, ""); }
+static inline LValue buildXor(LBuilder builder, LValue left, LValue right) { return llvm->BuildXor(builder, left, right, ""); }
+static inline LValue buildShl(LBuilder builder, LValue left, LValue right) { return llvm->BuildShl(builder, left, right, ""); }
+static inline LValue buildAShr(LBuilder builder, LValue left, LValue right) { return llvm->BuildAShr(builder, left, right, ""); }
+static inline LValue buildLShr(LBuilder builder, LValue left, LValue right) { return llvm->BuildLShr(builder, left, right, ""); }
+static inline LValue buildNot(LBuilder builder, LValue value) { return llvm->BuildNot(builder, value, ""); }
+static inline LValue buildLoad(LBuilder builder, LValue pointer) { return llvm->BuildLoad(builder, pointer, ""); }
+static inline LValue buildStore(LBuilder builder, LValue value, LValue pointer) { return llvm->BuildStore(builder, value, pointer); }
+static inline LValue buildSExt(LBuilder builder, LValue value, LType type) { return llvm->BuildSExt(builder, value, type, ""); }
+static inline LValue buildZExt(LBuilder builder, LValue value, LType type) { return llvm->BuildZExt(builder, value, type, ""); }
+static inline LValue buildFPToSI(LBuilder builder, LValue value, LType type) { return llvm->BuildFPToSI(builder, value, type, ""); }
+static inline LValue buildFPToUI(LBuilder builder, LValue value, LType type) { return llvm->BuildFPToUI(builder, value, type, ""); }
+static inline LValue buildSIToFP(LBuilder builder, LValue value, LType type) { return llvm->BuildSIToFP(builder, value, type, ""); }
+static inline LValue buildUIToFP(LBuilder builder, LValue value, LType type) { return llvm->BuildUIToFP(builder, value, type, ""); }
+static inline LValue buildIntCast(LBuilder builder, LValue value, LType type) { return llvm->BuildIntCast(builder, value, type, ""); }
+static inline LValue buildFPCast(LBuilder builder, LValue value, LType type) { return llvm->BuildFPCast(builder, value, type, ""); }
+static inline LValue buildIntToPtr(LBuilder builder, LValue value, LType type) { return llvm->BuildIntToPtr(builder, value, type, ""); }
+static inline LValue buildPtrToInt(LBuilder builder, LValue value, LType type) { return llvm->BuildPtrToInt(builder, value, type, ""); }
+static inline LValue buildBitCast(LBuilder builder, LValue value, LType type) { return llvm->BuildBitCast(builder, value, type, ""); }
+static inline LValue buildICmp(LBuilder builder, LIntPredicate cond, LValue left, LValue right) { return llvm->BuildICmp(builder, cond, left, right, ""); }
+static inline LValue buildFCmp(LBuilder builder, LRealPredicate cond, LValue left, LValue right) { return llvm->BuildFCmp(builder, cond, left, right, ""); }
+static inline LValue buildInsertElement(LBuilder builder, LValue vector, LValue element, LValue index) { return llvm->BuildInsertElement(builder, vector, element, index, ""); }
+
+enum SynchronizationScope { SingleThread, CrossThread };
+static inline LValue buildFence(LBuilder builder, LAtomicOrdering ordering, SynchronizationScope scope = CrossThread)
+{
+    return llvm->BuildFence(builder, ordering, scope == SingleThread, "");
+}
+
 static inline LValue buildCall(LBuilder builder, LValue function, const LValue* args, unsigned numArgs)
 {
-    return LLVMBuildCall(builder, function, const_cast<LValue*>(args), numArgs, "");
+    return llvm->BuildCall(builder, function, const_cast<LValue*>(args), numArgs, "");
 }
 template<typename VectorType>
 inline LValue buildCall(LBuilder builder, LValue function, const VectorType& vector)
@@ -229,21 +306,60 @@ static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, L
     LValue args[] = { arg1, arg2 };
     return buildCall(builder, function, args, 2);
 }
-enum TailCallMode { IsNotTailCall, IsTailCall };
-static inline void setTailCall(LValue call, TailCallMode mode) { LLVMSetTailCall(call, mode == IsTailCall); }
-static inline LValue buildExtractValue(LBuilder builder, LValue aggVal, unsigned index) { return LLVMBuildExtractValue(builder, aggVal, index, ""); }
-static inline LValue buildSelect(LBuilder builder, LValue condition, LValue taken, LValue notTaken) { return LLVMBuildSelect(builder, condition, taken, notTaken, ""); }
-static inline LValue buildBr(LBuilder builder, LBasicBlock destination) { return LLVMBuildBr(builder, destination); }
-static inline LValue buildCondBr(LBuilder builder, LValue condition, LBasicBlock taken, LBasicBlock notTaken) { return LLVMBuildCondBr(builder, condition, taken, notTaken); }
-static inline LValue buildRet(LBuilder builder, LValue value) { return LLVMBuildRet(builder, value); }
-static inline LValue buildUnreachable(LBuilder builder) { return LLVMBuildUnreachable(builder); }
+static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3)
+{
+    LValue args[] = { arg1, arg2, arg3 };
+    return buildCall(builder, function, args, 3);
+}
+static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4)
+{
+    LValue args[] = { arg1, arg2, arg3, arg4 };
+    return buildCall(builder, function, args, 4);
+}
+static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5)
+{
+    LValue args[] = { arg1, arg2, arg3, arg4, arg5 };
+    return buildCall(builder, function, args, 5);
+}
+static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6)
+{
+    LValue args[] = { arg1, arg2, arg3, arg4, arg5, arg6 };
+    return buildCall(builder, function, args, 6);
+}
+static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6, LValue arg7)
+{
+    LValue args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7 };
+    return buildCall(builder, function, args, 7);
+}
+static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6, LValue arg7, LValue arg8)
+{
+    LValue args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 };
+    return buildCall(builder, function, args, 8);
+}
+static inline void setInstructionCallingConvention(LValue instruction, LCallConv callingConvention) { llvm->SetInstructionCallConv(instruction, callingConvention); }
+static inline LValue buildExtractValue(LBuilder builder, LValue aggVal, unsigned index) { return llvm->BuildExtractValue(builder, aggVal, index, ""); }
+static inline LValue buildSelect(LBuilder builder, LValue condition, LValue taken, LValue notTaken) { return llvm->BuildSelect(builder, condition, taken, notTaken, ""); }
+static inline LValue buildBr(LBuilder builder, LBasicBlock destination) { return llvm->BuildBr(builder, destination); }
+static inline LValue buildCondBr(LBuilder builder, LValue condition, LBasicBlock taken, LBasicBlock notTaken) { return llvm->BuildCondBr(builder, condition, taken, notTaken); }
+static inline LValue buildSwitch(LBuilder builder, LValue value, LBasicBlock fallThrough, unsigned numCases) { return llvm->BuildSwitch(builder, value, fallThrough, numCases); }
+static inline void addCase(LValue switchInst, LValue value, LBasicBlock target) { llvm->AddCase(switchInst, value, target); }
+template<typename VectorType>
+static inline LValue buildSwitch(LBuilder builder, LValue value, const VectorType& cases, LBasicBlock fallThrough)
+{
+    LValue result = buildSwitch(builder, value, fallThrough, cases.size());
+    for (unsigned i = 0; i < cases.size(); ++i)
+        addCase(result, cases[i].value(), cases[i].target());
+    return result;
+}
+static inline LValue buildRet(LBuilder builder, LValue value) { return llvm->BuildRet(builder, value); }
+static inline LValue buildUnreachable(LBuilder builder) { return llvm->BuildUnreachable(builder); }
 
-static inline void dumpModule(LModule module) { LLVMDumpModule(module); }
+static inline void dumpModule(LModule module) { llvm->DumpModule(module); }
 static inline void verifyModule(LModule module)
 {
     char* error = 0;
-    LLVMVerifyModule(module, LLVMAbortProcessAction, &error);
-    LLVMDisposeMessage(error);
+    llvm->VerifyModule(module, LLVMAbortProcessAction, &error);
+    llvm->DisposeMessage(error);
 }
 
 } } // namespace JSC::FTL