4 #include <llvm/IR/BasicBlock.h> 5 #include <llvm/IR/Function.h> 6 #include <llvm/IR/Module.h> 7 #include <llvm/IR/LegacyPassManager.h> 8 #include <llvm/Transforms/Scalar.h> 9 #include <llvm/Transforms/IPO.h> 10 #include <llvm/Transforms/Utils/BasicBlockUtils.h> 26 class LongJmpEliminationPass:
public llvm::FunctionPass
31 LongJmpEliminationPass():
32 llvm::FunctionPass(ID)
35 virtual bool runOnFunction(llvm::Function& _func)
override;
38 char LongJmpEliminationPass::ID = 0;
40 bool LongJmpEliminationPass::runOnFunction(llvm::Function& _func)
42 auto iter = _func.getParent()->begin();
43 if (&_func != &(*iter))
46 auto& mainFunc = _func;
47 auto& ctx = _func.getContext();
48 auto abortCode = llvm::ConstantInt::get(llvm::Type::getInt32Ty(ctx), -1);
50 auto& exitBB = mainFunc.back();
51 assert(exitBB.getName() ==
"Exit");
52 auto retPhi = llvm::cast<llvm::PHINode>(&exitBB.front());
54 auto modified =
false;
55 for (
auto bbIt = mainFunc.begin(); bbIt != mainFunc.end(); ++bbIt)
57 if (
auto term = llvm::dyn_cast<llvm::UnreachableInst>(bbIt->getTerminator()))
59 auto longjmp = term->getPrevNode();
60 assert(llvm::isa<llvm::CallInst>(longjmp));
61 auto bbPtr = &(*bbIt);
62 retPhi->addIncoming(abortCode, bbPtr);
63 llvm::ReplaceInstWithInst(term, llvm::BranchInst::Create(&exitBB));
64 longjmp->eraseFromParent();
76 auto pm = llvm::legacy::PassManager{};
77 pm.add(llvm::createFunctionInliningPass(2, 2));
78 pm.add(
new LongJmpEliminationPass{});
79 pm.add(llvm::createCFGSimplificationPass());
80 pm.add(llvm::createInstructionCombiningPass());
81 pm.add(llvm::createAggressiveDCEPass());
82 pm.add(llvm::createLowerSwitchPass());
83 return pm.run(_module);
89 class LowerEVMPass:
public llvm::BasicBlockPass
95 llvm::BasicBlockPass(ID)
98 virtual bool runOnBasicBlock(llvm::BasicBlock& _bb)
override;
100 using llvm::BasicBlockPass::doFinalization;
101 virtual bool doFinalization(llvm::Module& _module)
override;
104 char LowerEVMPass::ID = 0;
106 bool LowerEVMPass::runOnBasicBlock(llvm::BasicBlock& _bb)
108 auto modified =
false;
109 auto module = _bb.getParent()->getParent();
110 auto i512Ty = llvm::IntegerType::get(_bb.getContext(), 512);
111 for (
auto it = _bb.begin(); it != _bb.end(); ++it)
114 llvm::Function* func =
nullptr;
117 switch (inst.getOpcode())
119 case llvm::Instruction::UDiv:
123 case llvm::Instruction::URem:
127 case llvm::Instruction::SDiv:
131 case llvm::Instruction::SRem:
136 else if (inst.getType() == i512Ty)
138 switch (inst.getOpcode())
140 case llvm::Instruction::URem:
148 auto call = llvm::CallInst::Create(func, {inst.getOperand(0), inst.getOperand(1)});
149 llvm::ReplaceInstWithInst(_bb.getInstList(), it,
call);
156 bool LowerEVMPass::doFinalization(llvm::Module&)
165 auto pm = llvm::legacy::PassManager{};
166 pm.add(llvm::createCFGSimplificationPass());
167 pm.add(llvm::createDeadCodeEliminationPass());
168 pm.add(
new LowerEVMPass{});
169 return pm.run(_module);
static llvm::Function * getUDiv256Func(llvm::Module &_module)
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
bool prepare(llvm::Module &_module)
assert(len-trim+(2 *lenIndices)<=WIDTH)
static llvm::Function * getURem256Func(llvm::Module &_module)
static llvm::Function * getURem512Func(llvm::Module &_module)
static llvm::IntegerType * Word
static llvm::Function * getSRem256Func(llvm::Module &_module)
static llvm::Function * getSDiv256Func(llvm::Module &_module)
bool optimize(llvm::Module &_module)