summaryrefslogtreecommitdiffstats
path: root/lldb/source/Expression/IRInterpreter.cpp
diff options
context:
space:
mode:
authorMarianne Mailhot-Sarrasin <marianne.mailhot.sarrasin@gmail.com>2016-05-12 20:00:53 +0000
committerMarianne Mailhot-Sarrasin <marianne.mailhot.sarrasin@gmail.com>2016-05-12 20:00:53 +0000
commit3fe71581743ceb838b113ee728e6de7f7ee8d25d (patch)
treec87db2d9a24ac05559c2a4b0da0e8cb2d4e1b06d /lldb/source/Expression/IRInterpreter.cpp
parentbc8397cdf0a76c614e53dc1deede78b0e568f753 (diff)
downloadbcm5719-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.cpp47
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);
OpenPOWER on IntegriCloud