Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

EOS VM OC: Support LLVM 11 - 2.0 #9894

Merged
merged 1 commit into from
Jan 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32)
# EOS VM OC requires LLVM, but move the check up here to a central location so that the EosioTester.cmakes
# can be created with the exact version found
find_package(LLVM REQUIRED CONFIG)
if(LLVM_VERSION_MAJOR VERSION_LESS 7 OR LLVM_VERSION_MAJOR VERSION_GREATER 10)
message(FATAL_ERROR "EOSIO requires an LLVM version 7.0 to 10.0")
if(LLVM_VERSION_MAJOR VERSION_LESS 7 OR LLVM_VERSION_MAJOR VERSION_GREATER_EQUAL 12)
message(FATAL_ERROR "EOSIO requires an LLVM version 7 through 11")
endif()
endif()
endif()
Expand Down
31 changes: 20 additions & 11 deletions libraries/chain/webassembly/eos-vm-oc/LLVMEmitIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,13 @@ namespace LLVMJIT
"eosvmoc_internal.div0_or_overflow",FunctionType::get(),{});
}

//llvm11 removed inferring the function type automatically, plumb CreateCalls through here as done for 10 & earlier
llvm::CallInst* createCall(llvm::Value* Callee, llvm::ArrayRef<llvm::Value*> Args) {
auto* PTy = llvm::cast<llvm::PointerType>(Callee->getType());
auto* FTy = llvm::cast<llvm::FunctionType>(PTy->getElementType());
return irBuilder.CreateCall(FTy, Callee, Args);
}

llvm::Value* getLLVMIntrinsic(const std::initializer_list<llvm::Type*>& argTypes,llvm::Intrinsic::ID id)
{
return llvm::Intrinsic::getDeclaration(moduleContext.llvmModule,id,llvm::ArrayRef<llvm::Type*>(argTypes.begin(),argTypes.end()));
Expand All @@ -356,7 +363,7 @@ namespace LLVMJIT
const eosio::chain::eosvmoc::intrinsic_entry& ie = eosio::chain::eosvmoc::get_intrinsic_map().at(intrinsicName);
llvm::Value* ic = irBuilder.CreateLoad( emitLiteralPointer((void*)(OFFSET_OF_FIRST_INTRINSIC-ie.ordinal*8), llvmI64Type->getPointerTo(256)) );
llvm::Value* itp = irBuilder.CreateIntToPtr(ic, asLLVMType(ie.type)->getPointerTo());
return irBuilder.CreateCall(itp,llvm::ArrayRef<llvm::Value*>(args.begin(),args.end()));
return createCall(itp,llvm::ArrayRef<llvm::Value*>(args.begin(),args.end()));
}

// A helper function to emit a conditional call to a non-returning intrinsic function.
Expand Down Expand Up @@ -707,7 +714,7 @@ namespace LLVMJIT
popMultiple(llvmArgs,calleeType->parameters.size());

// Call the function.
auto result = irBuilder.CreateCall(callee,llvm::ArrayRef<llvm::Value*>(llvmArgs,calleeType->parameters.size()));
auto result = createCall(callee,llvm::ArrayRef<llvm::Value*>(llvmArgs,calleeType->parameters.size()));
if(isExit) {
irBuilder.CreateUnreachable();
enterUnreachable();
Expand Down Expand Up @@ -758,7 +765,7 @@ namespace LLVMJIT
llvm::Value* running_code_start = irBuilder.CreateLoad(emitLiteralPointer((void*)OFFSET_OF_CONTROL_BLOCK_MEMBER(running_code_base), llvmI64Type->getPointerTo(256)));
llvm::Value* offset_from_start = irBuilder.CreateAdd(running_code_start, functionInfo);
llvm::Value* ptr_cast = irBuilder.CreateIntToPtr(offset_from_start, functionPointerType);
auto result = irBuilder.CreateCall(ptr_cast,llvm::ArrayRef<llvm::Value*>(llvmArgs,calleeType->parameters.size()));
auto result = createCall(ptr_cast,llvm::ArrayRef<llvm::Value*>(llvmArgs,calleeType->parameters.size()));

// Push the result on the operand stack.
if(calleeType->ret != ResultType::none) { push(result); }
Expand Down Expand Up @@ -795,7 +802,7 @@ namespace LLVMJIT
PN->addIncoming(offset_from_start, is_code_offset_block);

llvm::Value* ptr_cast = irBuilder.CreateIntToPtr(PN, functionPointerType);
auto result = irBuilder.CreateCall(ptr_cast,llvm::ArrayRef<llvm::Value*>(llvmArgs,calleeType->parameters.size()));
auto result = createCall(ptr_cast,llvm::ArrayRef<llvm::Value*>(llvmArgs,calleeType->parameters.size()));

// Push the result on the operand stack.
if(calleeType->ret != ResultType::none) { push(result); }
Expand Down Expand Up @@ -900,8 +907,10 @@ namespace LLVMJIT

#if LLVM_VERSION_MAJOR < 10
#define LOAD_STORE_ALIGNMENT_PARAM 1
#else
#elif LLVM_VERSION_MAJOR == 10
#define LOAD_STORE_ALIGNMENT_PARAM llvm::MaybeAlign(1)
#else
#define LOAD_STORE_ALIGNMENT_PARAM llvm::Align(1)
#endif

EMIT_LOAD_OP(i32,load8_s,llvmI8Type,0,irBuilder.CreateSExt,LOAD_STORE_ALIGNMENT_PARAM) EMIT_LOAD_OP(i32,load8_u,llvmI8Type,0,irBuilder.CreateZExt,LOAD_STORE_ALIGNMENT_PARAM)
Expand Down Expand Up @@ -1072,9 +1081,9 @@ namespace LLVMJIT
EMIT_INT_BINARY_OP(ge_u, coerceBoolToI32(irBuilder.CreateICmpUGE(left, right)))
#endif

EMIT_INT_UNARY_OP(clz,irBuilder.CreateCall(getLLVMIntrinsic({operand->getType()},llvm::Intrinsic::ctlz),llvm::ArrayRef<llvm::Value*>({operand,emitLiteral(false)})))
EMIT_INT_UNARY_OP(ctz,irBuilder.CreateCall(getLLVMIntrinsic({operand->getType()},llvm::Intrinsic::cttz),llvm::ArrayRef<llvm::Value*>({operand,emitLiteral(false)})))
EMIT_INT_UNARY_OP(popcnt,irBuilder.CreateCall(getLLVMIntrinsic({operand->getType()},llvm::Intrinsic::ctpop),llvm::ArrayRef<llvm::Value*>({operand})))
EMIT_INT_UNARY_OP(clz,createCall(getLLVMIntrinsic({operand->getType()},llvm::Intrinsic::ctlz),llvm::ArrayRef<llvm::Value*>({operand,emitLiteral(false)})))
EMIT_INT_UNARY_OP(ctz,createCall(getLLVMIntrinsic({operand->getType()},llvm::Intrinsic::cttz),llvm::ArrayRef<llvm::Value*>({operand,emitLiteral(false)})))
EMIT_INT_UNARY_OP(popcnt,createCall(getLLVMIntrinsic({operand->getType()},llvm::Intrinsic::ctpop),llvm::ArrayRef<llvm::Value*>({operand})))
EMIT_INT_UNARY_OP(eqz,coerceBoolToI32(irBuilder.CreateICmpEQ(operand,typedZeroConstants[(Uptr)type])))

//
Expand All @@ -1085,11 +1094,11 @@ namespace LLVMJIT
EMIT_FP_BINARY_OP(sub,irBuilder.CreateFSub(left,right))
EMIT_FP_BINARY_OP(mul,irBuilder.CreateFMul(left,right))
EMIT_FP_BINARY_OP(div,irBuilder.CreateFDiv(left,right))
EMIT_FP_BINARY_OP(copysign,irBuilder.CreateCall(getLLVMIntrinsic({left->getType()},llvm::Intrinsic::copysign),llvm::ArrayRef<llvm::Value*>({left,right})))
EMIT_FP_BINARY_OP(copysign,createCall(getLLVMIntrinsic({left->getType()},llvm::Intrinsic::copysign),llvm::ArrayRef<llvm::Value*>({left,right})))

EMIT_FP_UNARY_OP(neg,irBuilder.CreateFNeg(operand))
EMIT_FP_UNARY_OP(abs,irBuilder.CreateCall(getLLVMIntrinsic({operand->getType()},llvm::Intrinsic::fabs),llvm::ArrayRef<llvm::Value*>({operand})))
EMIT_FP_UNARY_OP(sqrt,irBuilder.CreateCall(getLLVMIntrinsic({operand->getType()},llvm::Intrinsic::sqrt),llvm::ArrayRef<llvm::Value*>({operand})))
EMIT_FP_UNARY_OP(abs,createCall(getLLVMIntrinsic({operand->getType()},llvm::Intrinsic::fabs),llvm::ArrayRef<llvm::Value*>({operand})))
EMIT_FP_UNARY_OP(sqrt,createCall(getLLVMIntrinsic({operand->getType()},llvm::Intrinsic::sqrt),llvm::ArrayRef<llvm::Value*>({operand})))

EMIT_FP_BINARY_OP(eq,coerceBoolToI32(irBuilder.CreateFCmpOEQ(left,right)))
EMIT_FP_BINARY_OP(ne,coerceBoolToI32(irBuilder.CreateFCmpUNE(left,right)))
Expand Down
1 change: 1 addition & 0 deletions libraries/chain/webassembly/eos-vm-oc/LLVMJIT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
#include "llvm/Object/SymbolSize.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/DynamicLibrary.h"
Expand Down