36 changed files with 296 additions and 345 deletions
@ -1,51 +1,47 @@ |
|||||
|
#include "CompilerHelper.h" |
||||
#include "CompilerHelper.h" |
#include "RuntimeManager.h" |
||||
|
#include <llvm/IR/Module.h> |
||||
#include <llvm/IR/Function.h> |
|
||||
#include <llvm/IR/Module.h> |
namespace dev |
||||
|
{ |
||||
#include "RuntimeManager.h" |
namespace eth |
||||
|
{ |
||||
namespace dev |
namespace jit |
||||
{ |
{ |
||||
namespace eth |
|
||||
{ |
CompilerHelper::CompilerHelper(llvm::IRBuilder<>& _builder) : |
||||
namespace jit |
m_builder(_builder) |
||||
{ |
{} |
||||
|
|
||||
CompilerHelper::CompilerHelper(llvm::IRBuilder<>& _builder) : |
llvm::Module* CompilerHelper::getModule() |
||||
m_builder(_builder) |
{ |
||||
{} |
assert(m_builder.GetInsertBlock()); |
||||
|
assert(m_builder.GetInsertBlock()->getParent()); // BB must be in a function
|
||||
llvm::Module* CompilerHelper::getModule() |
return m_builder.GetInsertBlock()->getParent()->getParent(); |
||||
{ |
} |
||||
assert(m_builder.GetInsertBlock()); |
|
||||
assert(m_builder.GetInsertBlock()->getParent()); // BB must be in a function
|
llvm::Function* CompilerHelper::getMainFunction() |
||||
return m_builder.GetInsertBlock()->getParent()->getParent(); |
{ |
||||
} |
// TODO: Rename or change semantics of getMainFunction() function
|
||||
|
assert(m_builder.GetInsertBlock()); |
||||
llvm::Function* CompilerHelper::getMainFunction() |
auto mainFunc = m_builder.GetInsertBlock()->getParent(); |
||||
{ |
assert(mainFunc); |
||||
// TODO: Rename or change semantics of getMainFunction() function
|
if (mainFunc == &mainFunc->getParent()->getFunctionList().front()) // Main function is the first one in module
|
||||
assert(m_builder.GetInsertBlock()); |
return mainFunc; |
||||
auto mainFunc = m_builder.GetInsertBlock()->getParent(); |
return nullptr; |
||||
assert(mainFunc); |
} |
||||
if (mainFunc == &mainFunc->getParent()->getFunctionList().front()) // Main function is the first one in module
|
|
||||
return mainFunc; |
llvm::CallInst* CompilerHelper::createCall(llvm::Function* _func, std::initializer_list<llvm::Value*> const& _args) |
||||
return nullptr; |
{ |
||||
} |
return getBuilder().CreateCall(_func, {_args.begin(), _args.size()}); |
||||
|
} |
||||
llvm::CallInst* CompilerHelper::createCall(llvm::Function* _func, std::initializer_list<llvm::Value*> const& _args) |
|
||||
{ |
|
||||
return getBuilder().CreateCall(_func, {_args.begin(), _args.size()}); |
RuntimeHelper::RuntimeHelper(RuntimeManager& _runtimeManager): |
||||
} |
CompilerHelper(_runtimeManager.getBuilder()), |
||||
|
m_runtimeManager(_runtimeManager) |
||||
|
{} |
||||
RuntimeHelper::RuntimeHelper(RuntimeManager& _runtimeManager): |
|
||||
CompilerHelper(_runtimeManager.getBuilder()), |
} |
||||
m_runtimeManager(_runtimeManager) |
} |
||||
{} |
} |
||||
|
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
@ -1,78 +1,79 @@ |
|||||
|
#pragma once |
||||
|
|
||||
#pragma once |
#include "preprocessor/llvm_includes_start.h" |
||||
|
|
||||
#include <llvm/IR/IRBuilder.h> |
#include <llvm/IR/IRBuilder.h> |
||||
|
#include "preprocessor/llvm_includes_end.h" |
||||
|
|
||||
namespace dev |
|
||||
{ |
namespace dev |
||||
namespace eth |
{ |
||||
{ |
namespace eth |
||||
namespace jit |
{ |
||||
{ |
namespace jit |
||||
class RuntimeManager; |
{ |
||||
|
class RuntimeManager; |
||||
/// Base class for compiler helpers like Memory, GasMeter, etc.
|
|
||||
class CompilerHelper |
/// Base class for compiler helpers like Memory, GasMeter, etc.
|
||||
{ |
class CompilerHelper |
||||
protected: |
{ |
||||
CompilerHelper(llvm::IRBuilder<>& _builder); |
protected: |
||||
|
CompilerHelper(llvm::IRBuilder<>& _builder); |
||||
CompilerHelper(const CompilerHelper&) = delete; |
|
||||
void operator=(CompilerHelper) = delete; |
CompilerHelper(const CompilerHelper&) = delete; |
||||
|
CompilerHelper& operator=(CompilerHelper) = delete; |
||||
/// Reference to the IR module being compiled
|
|
||||
llvm::Module* getModule(); |
/// Reference to the IR module being compiled
|
||||
|
llvm::Module* getModule(); |
||||
/// Reference to the main module function
|
|
||||
llvm::Function* getMainFunction(); |
/// Reference to the main module function
|
||||
|
llvm::Function* getMainFunction(); |
||||
/// Reference to parent compiler IR builder
|
|
||||
llvm::IRBuilder<>& m_builder; |
/// Reference to parent compiler IR builder
|
||||
llvm::IRBuilder<>& getBuilder() { return m_builder; } |
llvm::IRBuilder<>& m_builder; |
||||
|
llvm::IRBuilder<>& getBuilder() { return m_builder; } |
||||
llvm::CallInst* createCall(llvm::Function* _func, std::initializer_list<llvm::Value*> const& _args); |
|
||||
|
llvm::CallInst* createCall(llvm::Function* _func, std::initializer_list<llvm::Value*> const& _args); |
||||
friend class RuntimeHelper; |
|
||||
}; |
friend class RuntimeHelper; |
||||
|
}; |
||||
|
|
||||
/// Compiler helper that depends on runtime data
|
|
||||
class RuntimeHelper : public CompilerHelper |
/// Compiler helper that depends on runtime data
|
||||
{ |
class RuntimeHelper : public CompilerHelper |
||||
protected: |
{ |
||||
RuntimeHelper(RuntimeManager& _runtimeManager); |
protected: |
||||
|
RuntimeHelper(RuntimeManager& _runtimeManager); |
||||
RuntimeManager& getRuntimeManager() { return m_runtimeManager; } |
|
||||
|
RuntimeManager& getRuntimeManager() { return m_runtimeManager; } |
||||
private: |
|
||||
RuntimeManager& m_runtimeManager; |
private: |
||||
}; |
RuntimeManager& m_runtimeManager; |
||||
|
}; |
||||
|
|
||||
/// Saves the insert point of the IR builder and restores it when destructed
|
|
||||
struct InsertPointGuard |
/// Saves the insert point of the IR builder and restores it when destructed
|
||||
{ |
struct InsertPointGuard |
||||
InsertPointGuard(llvm::IRBuilder<>& _builder) : |
{ |
||||
m_builder(_builder), |
InsertPointGuard(llvm::IRBuilder<>& _builder) : |
||||
m_insertBB(m_builder.GetInsertBlock()), |
m_builder(_builder), |
||||
m_insertPt(m_builder.GetInsertPoint()) |
m_insertBB(m_builder.GetInsertBlock()), |
||||
{} |
m_insertPt(m_builder.GetInsertPoint()) |
||||
|
{} |
||||
InsertPointGuard(const InsertPointGuard&) = delete; |
|
||||
void operator=(InsertPointGuard) = delete; |
InsertPointGuard(const InsertPointGuard&) = delete; |
||||
|
void operator=(InsertPointGuard) = delete; |
||||
~InsertPointGuard() |
|
||||
{ |
~InsertPointGuard() |
||||
m_builder.SetInsertPoint(m_insertBB, m_insertPt); |
{ |
||||
} |
m_builder.SetInsertPoint(m_insertBB, m_insertPt); |
||||
|
} |
||||
private: |
|
||||
llvm::IRBuilder<>& m_builder; |
private: |
||||
llvm::BasicBlock* m_insertBB; |
llvm::IRBuilder<>& m_builder; |
||||
llvm::BasicBlock::iterator m_insertPt; |
llvm::BasicBlock* m_insertBB; |
||||
}; |
llvm::BasicBlock::iterator m_insertPt; |
||||
|
}; |
||||
} |
|
||||
} |
} |
||||
} |
} |
||||
|
} |
||||
|
@ -1,38 +1,38 @@ |
|||||
|
#include "Endianness.h" |
||||
#include "Endianness.h" |
#include "Type.h" |
||||
|
|
||||
#include <llvm/IR/IntrinsicInst.h> |
#include "preprocessor/llvm_includes_start.h" |
||||
|
#include <llvm/IR/IntrinsicInst.h> |
||||
#include "Type.h" |
#include "preprocessor/llvm_includes_end.h" |
||||
|
|
||||
namespace dev |
namespace dev |
||||
{ |
{ |
||||
namespace eth |
namespace eth |
||||
{ |
{ |
||||
namespace jit |
namespace jit |
||||
{ |
{ |
||||
|
|
||||
llvm::Value* Endianness::bswapIfLE(llvm::IRBuilder<>& _builder, llvm::Value* _word) |
llvm::Value* Endianness::bswapIfLE(llvm::IRBuilder<>& _builder, llvm::Value* _word) |
||||
{ |
{ |
||||
union tester |
union tester |
||||
{ |
{ |
||||
unsigned int x; |
unsigned int x; |
||||
unsigned char isLE; |
unsigned char isLE; |
||||
}; |
}; |
||||
|
|
||||
if (tester{1}.isLE) |
if (tester{1}.isLE) |
||||
{ |
{ |
||||
// FIXME: Disabled because of problems with BYTE
|
// FIXME: Disabled because of problems with BYTE
|
||||
//if (auto constant = llvm::dyn_cast<llvm::ConstantInt>(_word))
|
//if (auto constant = llvm::dyn_cast<llvm::ConstantInt>(_word))
|
||||
// return _builder.getInt(constant->getValue().byteSwap());
|
// return _builder.getInt(constant->getValue().byteSwap());
|
||||
|
|
||||
// OPT: Cache func declaration?
|
// OPT: Cache func declaration?
|
||||
auto bswapFunc = llvm::Intrinsic::getDeclaration(_builder.GetInsertBlock()->getParent()->getParent(), llvm::Intrinsic::bswap, Type::Word); |
auto bswapFunc = llvm::Intrinsic::getDeclaration(_builder.GetInsertBlock()->getParent()->getParent(), llvm::Intrinsic::bswap, Type::Word); |
||||
return _builder.CreateCall(bswapFunc, _word); |
return _builder.CreateCall(bswapFunc, _word); |
||||
} |
} |
||||
return _word; |
return _word; |
||||
} |
} |
||||
|
|
||||
} |
} |
||||
} |
} |
||||
} |
} |
||||
|
@ -1,24 +1,25 @@ |
|||||
|
#pragma once |
||||
#pragma once |
|
||||
|
#include "preprocessor/llvm_includes_start.h" |
||||
#include <llvm/IR/IRBuilder.h> |
#include <llvm/IR/IRBuilder.h> |
||||
|
#include "preprocessor/llvm_includes_end.h" |
||||
namespace dev |
|
||||
{ |
namespace dev |
||||
namespace eth |
{ |
||||
{ |
namespace eth |
||||
namespace jit |
{ |
||||
{ |
namespace jit |
||||
|
{ |
||||
struct Endianness |
|
||||
{ |
struct Endianness |
||||
static llvm::Value* toBE(llvm::IRBuilder<>& _builder, llvm::Value* _word) { return bswapIfLE(_builder, _word); } |
{ |
||||
static llvm::Value* toNative(llvm::IRBuilder<>& _builder, llvm::Value* _word) { return bswapIfLE(_builder, _word); } |
static llvm::Value* toBE(llvm::IRBuilder<>& _builder, llvm::Value* _word) { return bswapIfLE(_builder, _word); } |
||||
|
static llvm::Value* toNative(llvm::IRBuilder<>& _builder, llvm::Value* _word) { return bswapIfLE(_builder, _word); } |
||||
private: |
|
||||
static llvm::Value* bswapIfLE(llvm::IRBuilder<>& _builder, llvm::Value* _word); |
private: |
||||
}; |
static llvm::Value* bswapIfLE(llvm::IRBuilder<>& _builder, llvm::Value* _word); |
||||
|
}; |
||||
} |
|
||||
} |
} |
||||
} |
} |
||||
|
} |
||||
|
@ -1,43 +1,40 @@ |
|||||
#pragma once |
#pragma once |
||||
|
#include "CompilerHelper.h" |
||||
#include "CompilerHelper.h" |
|
||||
|
namespace dev |
||||
#include <llvm/IR/Module.h> |
{ |
||||
|
namespace eth |
||||
namespace dev |
{ |
||||
{ |
namespace jit |
||||
namespace eth |
{ |
||||
{ |
class RuntimeManager; |
||||
namespace jit |
|
||||
{ |
class Stack : public CompilerHelper |
||||
class RuntimeManager; |
{ |
||||
|
public: |
||||
class Stack : public CompilerHelper |
Stack(llvm::IRBuilder<>& builder, RuntimeManager& runtimeManager); |
||||
{ |
|
||||
public: |
llvm::Value* get(size_t _index); |
||||
Stack(llvm::IRBuilder<>& builder, RuntimeManager& runtimeManager); |
void set(size_t _index, llvm::Value* _value); |
||||
|
void pop(size_t _count); |
||||
llvm::Value* get(size_t _index); |
void push(llvm::Value* _value); |
||||
void set(size_t _index, llvm::Value* _value); |
|
||||
void pop(size_t _count); |
static size_t maxStackSize; |
||||
void push(llvm::Value* _value); |
|
||||
|
private: |
||||
static size_t maxStackSize; |
RuntimeManager& m_runtimeManager; |
||||
|
|
||||
private: |
llvm::Function* m_push; |
||||
RuntimeManager& m_runtimeManager; |
llvm::Function* m_pop; |
||||
|
llvm::Function* m_get; |
||||
llvm::Function* m_push; |
llvm::Function* m_set; |
||||
llvm::Function* m_pop; |
|
||||
llvm::Function* m_get; |
llvm::Value* m_arg; |
||||
llvm::Function* m_set; |
}; |
||||
|
|
||||
llvm::Value* m_arg; |
|
||||
}; |
} |
||||
|
} |
||||
|
} |
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
@ -1,4 +1,5 @@ |
|||||
|
|
||||
#pragma warning(push) |
#pragma warning(push) |
||||
|
#pragma warning(disable: 4267 4244 4800) |
||||
#pragma GCC diagnostic push |
#pragma GCC diagnostic push |
||||
#pragma GCC diagnostic ignored "-Wunused-parameter" |
#pragma GCC diagnostic ignored "-Wunused-parameter" |
||||
|
Loading…
Reference in new issue