You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
2.1 KiB

#include "Optimizer.h"
#include "preprocessor/llvm_includes_start.h"
#include <llvm/IR/BasicBlock.h>
#include <llvm/IR/Function.h>
10 years ago
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/Transforms/Scalar.h>
#include <llvm/Transforms/IPO.h>
#include "preprocessor/llvm_includes_end.h"
#include "Arith256.h"
#include "Type.h"
namespace dev
{
namespace eth
{
namespace jit
{
bool optimize(llvm::Module& _module)
{
10 years ago
auto pm = llvm::legacy::PassManager{};
//pm.add(llvm::createFunctionInliningPass(2, 2)); // Problem with APInt value bigger than 64bit
pm.add(llvm::createCFGSimplificationPass());
pm.add(llvm::createInstructionCombiningPass());
pm.add(llvm::createAggressiveDCEPass());
pm.add(llvm::createLowerSwitchPass());
return pm.run(_module);
}
namespace
{
class LowerEVMPass : public llvm::BasicBlockPass
{
static char ID;
bool m_mulFuncNeeded = false;
public:
LowerEVMPass():
llvm::BasicBlockPass(ID)
{}
virtual bool runOnBasicBlock(llvm::BasicBlock& _bb) override;
virtual bool doFinalization(llvm::Module& _module) override;
};
char LowerEVMPass::ID = 0;
bool LowerEVMPass::runOnBasicBlock(llvm::BasicBlock& _bb)
{
auto modified = false;
auto module = _bb.getParent()->getParent();
for (auto&& inst : _bb)
{
if (inst.getOpcode() == llvm::Instruction::Mul)
{
if (inst.getType() == Type::Word)
{
auto call = llvm::CallInst::Create(Arith256::getMulFunc(*module), {inst.getOperand(0), inst.getOperand(1)}, "", &inst);
inst.replaceAllUsesWith(call);
modified = true;
}
}
else if (inst.getOpcode() == llvm::Instruction::UDiv)
{
if (inst.getType() == Type::Word)
{
auto call = llvm::CallInst::Create(Arith256::getUDiv256Func(*module), {inst.getOperand(0), inst.getOperand(1)}, "", &inst);
inst.replaceAllUsesWith(call);
modified = true;
}
}
}
return modified;
}
bool LowerEVMPass::doFinalization(llvm::Module&)
{
return false;
}
}
bool prepare(llvm::Module& _module)
{
auto pm = llvm::legacy::PassManager{};
pm.add(llvm::createDeadCodeEliminationPass());
pm.add(new LowerEVMPass{});
pm.add(llvm::createDeadInstEliminationPass()); // Remove leftovers
return pm.run(_module);
}
}
}
}