diff options
author | Marianne Mailhot-Sarrasin <marianne.mailhot.sarrasin@gmail.com> | 2016-05-12 20:00:53 +0000 |
---|---|---|
committer | Marianne Mailhot-Sarrasin <marianne.mailhot.sarrasin@gmail.com> | 2016-05-12 20:00:53 +0000 |
commit | 3fe71581743ceb838b113ee728e6de7f7ee8d25d (patch) | |
tree | c87db2d9a24ac05559c2a4b0da0e8cb2d4e1b06d /lldb/source/Expression/IRInterpreter.cpp | |
parent | bc8397cdf0a76c614e53dc1deede78b0e568f753 (diff) | |
download | bcm5719-llvm-3fe71581743ceb838b113ee728e6de7f7ee8d25d.tar.gz bcm5719-llvm-3fe71581743ceb838b113ee728e6de7f7ee8d25d.zip |
[LLDB] Added support for PHI nodes to IR interpreter
This allows expressions such as 'i == 1 || i == 2` to be executed using the IR interpreter, instead of relying on JIT code injection (which may not be available on some platforms).
Patch by cameron314
Differential Revision: http://reviews.llvm.org/D19124
llvm-svn: 269340
Diffstat (limited to 'lldb/source/Expression/IRInterpreter.cpp')
-rw-r--r-- | lldb/source/Expression/IRInterpreter.cpp | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp index 42d6dc116f9..0285248314b 100644 --- a/lldb/source/Expression/IRInterpreter.cpp +++ b/lldb/source/Expression/IRInterpreter.cpp @@ -106,6 +106,7 @@ public: DataLayout &m_target_data; lldb_private::IRExecutionUnit &m_execution_unit; const BasicBlock *m_bb; + const BasicBlock *m_prev_bb; BasicBlock::const_iterator m_ii; BasicBlock::const_iterator m_ie; @@ -121,7 +122,9 @@ public: lldb::addr_t stack_frame_bottom, lldb::addr_t stack_frame_top) : m_target_data (target_data), - m_execution_unit (execution_unit) + m_execution_unit (execution_unit), + m_bb (nullptr), + m_prev_bb (nullptr) { m_byte_order = (target_data.isLittleEndian() ? lldb::eByteOrderLittle : lldb::eByteOrderBig); m_addr_byte_size = (target_data.getPointerSize(0)); @@ -137,6 +140,7 @@ public: void Jump (const BasicBlock *bb) { + m_prev_bb = m_bb; m_bb = bb; m_ii = m_bb->begin(); m_ie = m_bb->end(); @@ -569,6 +573,7 @@ IRInterpreter::CanInterpret (llvm::Module &module, case Instruction::Alloca: case Instruction::BitCast: case Instruction::Br: + case Instruction::PHI: break; case Instruction::Call: { @@ -1063,6 +1068,46 @@ IRInterpreter::Interpret (llvm::Module &module, } } continue; + case Instruction::PHI: + { + const PHINode *phi_inst = dyn_cast<PHINode>(inst); + + if (!phi_inst) + { + if (log) + log->Printf("getOpcode() returns PHI, but instruction is not a PHINode"); + error.SetErrorToGenericError(); + error.SetErrorString(interpreter_internal_error); + return false; + } + if (!frame.m_prev_bb) + { + if (log) + log->Printf("Encountered PHI node without having jumped from another basic block"); + error.SetErrorToGenericError(); + error.SetErrorString(interpreter_internal_error); + return false; + } + + Value* value = phi_inst->getIncomingValueForBlock(frame.m_prev_bb); + lldb_private::Scalar result; + if (!frame.EvaluateValue(result, value, module)) + { + if (log) + log->Printf("Couldn't evaluate %s", PrintValue(value).c_str()); + error.SetErrorToGenericError(); + error.SetErrorString(bad_value_error); + return false; + } + frame.AssignValue(inst, result, module); + + if (log) + { + log->Printf("Interpreted a %s", inst->getOpcodeName()); + log->Printf(" Incoming value : %s", frame.SummarizeValue(value).c_str()); + } + } + break; case Instruction::GetElementPtr: { const GetElementPtrInst *gep_inst = dyn_cast<GetElementPtrInst>(inst); |