cameron314 created this revision. cameron314 added a reviewer: spyffe. cameron314 added subscribers: mamai, lldb-commits. cameron314 set the repository for this revision to rL LLVM.
This allows expressions such as 'i == 1 || i == 2` to be executed using the IR interpreter. Repository: rL LLVM http://reviews.llvm.org/D19124 Files: source/Expression/IRInterpreter.cpp Index: source/Expression/IRInterpreter.cpp =================================================================== --- source/Expression/IRInterpreter.cpp +++ source/Expression/IRInterpreter.cpp @@ -106,6 +106,7 @@ 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 @@ 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 @@ void Jump (const BasicBlock *bb) { + m_prev_bb = m_bb; m_bb = bb; m_ii = m_bb->begin(); m_ie = m_bb->end(); @@ -563,6 +567,7 @@ case Instruction::Alloca: case Instruction::BitCast: case Instruction::Br: + case Instruction::PHI: break; case Instruction::Call: { @@ -1052,6 +1057,46 @@ } } 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);
Index: source/Expression/IRInterpreter.cpp =================================================================== --- source/Expression/IRInterpreter.cpp +++ source/Expression/IRInterpreter.cpp @@ -106,6 +106,7 @@ 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 @@ 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 @@ void Jump (const BasicBlock *bb) { + m_prev_bb = m_bb; m_bb = bb; m_ii = m_bb->begin(); m_ie = m_bb->end(); @@ -563,6 +567,7 @@ case Instruction::Alloca: case Instruction::BitCast: case Instruction::Br: + case Instruction::PHI: break; case Instruction::Call: { @@ -1052,6 +1057,46 @@ } } 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);
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits