|
|
@ -94,7 +94,7 @@ void Compiler::createBasicBlocks(code_iterator _codeBegin, code_iterator _codeEn |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
llvm::BasicBlock* Compiler::getJumpTableBlock(RuntimeManager& _runtimeManager) |
|
|
|
llvm::BasicBlock* Compiler::getJumpTableBlock() |
|
|
|
{ |
|
|
|
if (!m_jumpTableBlock) |
|
|
|
{ |
|
|
@ -102,7 +102,7 @@ llvm::BasicBlock* Compiler::getJumpTableBlock(RuntimeManager& _runtimeManager) |
|
|
|
InsertPointGuard g{m_builder}; |
|
|
|
m_builder.SetInsertPoint(m_jumpTableBlock->llvm()); |
|
|
|
auto dest = m_builder.CreatePHI(Type::Word, 8, "target"); |
|
|
|
auto switchInstr = m_builder.CreateSwitch(dest, getBadJumpBlock(_runtimeManager)); |
|
|
|
auto switchInstr = m_builder.CreateSwitch(dest, m_abortBB); |
|
|
|
for (auto&& p : m_basicBlocks) |
|
|
|
{ |
|
|
|
if (p.second.isJumpDest()) |
|
|
@ -112,18 +112,6 @@ llvm::BasicBlock* Compiler::getJumpTableBlock(RuntimeManager& _runtimeManager) |
|
|
|
return m_jumpTableBlock->llvm(); |
|
|
|
} |
|
|
|
|
|
|
|
llvm::BasicBlock* Compiler::getBadJumpBlock(RuntimeManager& _runtimeManager) |
|
|
|
{ |
|
|
|
if (!m_badJumpBlock) |
|
|
|
{ |
|
|
|
m_badJumpBlock.reset(new BasicBlock("BadJump", m_mainFunc, m_builder, true)); |
|
|
|
InsertPointGuard g{m_builder}; |
|
|
|
m_builder.SetInsertPoint(m_badJumpBlock->llvm()); |
|
|
|
_runtimeManager.exit(ReturnCode::BadJumpDestination); |
|
|
|
} |
|
|
|
return m_badJumpBlock->llvm(); |
|
|
|
} |
|
|
|
|
|
|
|
std::unique_ptr<llvm::Module> Compiler::compile(code_iterator _begin, code_iterator _end, std::string const& _id) |
|
|
|
{ |
|
|
|
auto module = std::unique_ptr<llvm::Module>(new llvm::Module(_id, m_builder.getContext())); |
|
|
@ -616,7 +604,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runti |
|
|
|
auto&& c = constant->getValue(); |
|
|
|
auto targetIdx = c.getActiveBits() <= 64 ? c.getZExtValue() : -1; |
|
|
|
auto it = m_basicBlocks.find(targetIdx); |
|
|
|
targetBlock = (it != m_basicBlocks.end() && it->second.isJumpDest()) ? it->second.llvm() : getBadJumpBlock(_runtimeManager); |
|
|
|
targetBlock = (it != m_basicBlocks.end() && it->second.isJumpDest()) ? it->second.llvm() : m_abortBB; |
|
|
|
} |
|
|
|
|
|
|
|
// TODO: Improve; check for constants
|
|
|
@ -629,7 +617,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runti |
|
|
|
else |
|
|
|
{ |
|
|
|
_basicBlock.setJumpTarget(target); |
|
|
|
m_builder.CreateBr(getJumpTableBlock(_runtimeManager)); |
|
|
|
m_builder.CreateBr(getJumpTableBlock()); |
|
|
|
} |
|
|
|
} |
|
|
|
else // JUMPI
|
|
|
@ -645,7 +633,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runti |
|
|
|
else |
|
|
|
{ |
|
|
|
_basicBlock.setJumpTarget(target); |
|
|
|
m_builder.CreateCondBr(cond, getJumpTableBlock(_runtimeManager), _nextBasicBlock); |
|
|
|
m_builder.CreateCondBr(cond, getJumpTableBlock(), _nextBasicBlock); |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
@ -901,12 +889,6 @@ void Compiler::removeDeadBlocks() |
|
|
|
m_jumpTableBlock->llvm()->eraseFromParent(); |
|
|
|
m_jumpTableBlock.reset(); |
|
|
|
} |
|
|
|
|
|
|
|
if (m_badJumpBlock && llvm::pred_begin(m_badJumpBlock->llvm()) == llvm::pred_end(m_badJumpBlock->llvm())) |
|
|
|
{ |
|
|
|
m_badJumpBlock->llvm()->eraseFromParent(); |
|
|
|
m_badJumpBlock.reset(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void Compiler::dumpCFGifRequired(std::string const& _dotfilePath) |
|
|
@ -931,8 +913,6 @@ void Compiler::dumpCFGtoStream(std::ostream& _out) |
|
|
|
blocks.push_back(&pair.second); |
|
|
|
if (m_jumpTableBlock) |
|
|
|
blocks.push_back(m_jumpTableBlock.get()); |
|
|
|
if (m_badJumpBlock) |
|
|
|
blocks.push_back(m_badJumpBlock.get()); |
|
|
|
|
|
|
|
// std::map<BasicBlock*,int> phiNodesPerBlock;
|
|
|
|
|
|
|
|