diff options
author | Sean Callanan <scallanan@apple.com> | 2013-04-18 22:06:33 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2013-04-18 22:06:33 +0000 |
commit | 1582ee6840bc45b1c7dcab37d89c913f97ef6aac (patch) | |
tree | f4d1c4b1f5857f5cfb2ba1ac839d2f5eb7753d77 /lldb/source/Expression/IRForTarget.cpp | |
parent | 526560a5531c29f0083fe2d6b099671b8cdee8f0 (diff) | |
download | bcm5719-llvm-1582ee6840bc45b1c7dcab37d89c913f97ef6aac.tar.gz bcm5719-llvm-1582ee6840bc45b1c7dcab37d89c913f97ef6aac.zip |
This commit changes the way LLDB executes user
expressions.
Previously, ClangUserExpression assumed that if
there was a constant result for an expression
then it could be determined during parsing. In
particular, the IRInterpreter ran while parser
state (in particular, ClangExpressionDeclMap)
was present. This approach is flawed, because
the IRInterpreter actually is capable of using
external variables, and hence the result might
be different each run. Until now, we papered
over this flaw by re-parsing the expression each
time we ran it.
I have rewritten the IRInterpreter to be
completely independent of the ClangExpressionDeclMap.
Instead of special-casing external variable lookup,
which ties the IRInterpreter closely to LLDB,
we now interpret the exact same IR that the JIT
would see. This IR assumes that materialization
has occurred; hence the recent implementation of the
Materializer, which does not require parser state
(in the form of ClangExpressionDeclMap) to be
present.
Materialization, interpretation, and dematerialization
are now all independent of parsing. This means that
in theory we can parse expressions once and run them
many times. I have three outstanding tasks before
shutting this down:
- First, I will ensure that all of this works with
core files. Core files have a Process but do not
allow allocating memory, which currently confuses
materialization.
- Second, I will make expression breakpoint
conditions remember their ClangUserExpression and
re-use it.
- Third, I will tear out all the redundant code
(for example, materialization logic in
ClangExpressionDeclMap) that is no longer used.
While implementing this fix, I also found a bug in
IRForTarget's handling of floating-point constants.
This should be fixed.
llvm-svn: 179801
Diffstat (limited to 'lldb/source/Expression/IRForTarget.cpp')
-rw-r--r-- | lldb/source/Expression/IRForTarget.cpp | 139 |
1 files changed, 12 insertions, 127 deletions
diff --git a/lldb/source/Expression/IRForTarget.cpp b/lldb/source/Expression/IRForTarget.cpp index 2b3618a53a7..1c1f120b86c 100644 --- a/lldb/source/Expression/IRForTarget.cpp +++ b/lldb/source/Expression/IRForTarget.cpp @@ -42,6 +42,7 @@ static char ID; IRForTarget::StaticDataAllocator::StaticDataAllocator(lldb_private::IRExecutionUnit &execution_unit) : m_execution_unit(execution_unit), + m_stream_string(lldb_private::Stream::eBinary, execution_unit.GetAddressByteSize(), execution_unit.GetByteOrder()), m_allocation(LLDB_INVALID_ADDRESS) { } @@ -63,15 +64,11 @@ lldb::addr_t IRForTarget::StaticDataAllocator::Allocate() IRForTarget::IRForTarget (lldb_private::ClangExpressionDeclMap *decl_map, bool resolve_vars, - lldb_private::ExecutionPolicy execution_policy, - lldb::ClangExpressionVariableSP &const_result, lldb_private::IRExecutionUnit &execution_unit, lldb_private::Stream *error_stream, const char *func_name) : ModulePass(ID), m_resolve_vars(resolve_vars), - m_execution_policy(execution_policy), - m_interpret_success(false), m_func_name(func_name), m_module(NULL), m_decl_map(decl_map), @@ -79,7 +76,6 @@ IRForTarget::IRForTarget (lldb_private::ClangExpressionDeclMap *decl_map, m_memory_map(execution_unit), m_CFStringCreateWithBytes(NULL), m_sel_registerName(NULL), - m_const_result(const_result), m_error_stream(error_stream), m_has_side_effects(false), m_result_store(NULL), @@ -444,97 +440,6 @@ IRForTarget::DeclForGlobal (GlobalValue *global_val) return DeclForGlobal(global_val, m_module); } -void -IRForTarget::MaybeSetConstantResult (llvm::Constant *initializer, - const lldb_private::ConstString &name, - lldb_private::TypeFromParser type) -{ - if (llvm::ConstantExpr *init_expr = dyn_cast<llvm::ConstantExpr>(initializer)) - { - switch (init_expr->getOpcode()) - { - default: - return; - case Instruction::IntToPtr: - MaybeSetConstantResult (init_expr->getOperand(0), name, type); - return; - } - } - else if (llvm::ConstantInt *init_int = dyn_cast<llvm::ConstantInt>(initializer)) - { - m_const_result = m_decl_map->BuildIntegerVariable(name, type, init_int->getValue()); - } -} - -void -IRForTarget::MaybeSetCastResult (lldb_private::TypeFromParser type) -{ - lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - - if (!m_result_store) - return; - - LoadInst *original_load = NULL; - - for (llvm::Value *current_value = m_result_store->getValueOperand(), *next_value; - current_value != NULL; - current_value = next_value) - { - CastInst *cast_inst = dyn_cast<CastInst>(current_value); - LoadInst *load_inst = dyn_cast<LoadInst>(current_value); - - if (cast_inst) - { - next_value = cast_inst->getOperand(0); - } - else if (load_inst) - { - if (isa<LoadInst>(load_inst->getPointerOperand())) - { - next_value = load_inst->getPointerOperand(); - } - else - { - original_load = load_inst; - break; - } - } - else - { - return; - } - } - - if (!original_load) - return; - - Value *loaded_value = original_load->getPointerOperand(); - GlobalVariable *loaded_global = dyn_cast<GlobalVariable>(loaded_value); - - if (!loaded_global) - return; - - clang::NamedDecl *loaded_decl = DeclForGlobal(loaded_global); - - if (!loaded_decl) - return; - - clang::VarDecl *loaded_var = dyn_cast<clang::VarDecl>(loaded_decl); - - if (!loaded_var) - return; - - if (log) - { - lldb_private::StreamString type_desc_stream; - type.DumpTypeDescription(&type_desc_stream); - - log->Printf("Type to cast variable to: \"%s\"", type_desc_stream.GetString().c_str()); - } - - m_const_result = m_decl_map->BuildCastVariable(m_result_name, loaded_var, type); -} - bool IRForTarget::CreateResultVariable (llvm::Function &llvm_function) { @@ -714,7 +619,7 @@ IRForTarget::CreateResultVariable (llvm::Function &llvm_function) log->Printf("Result decl type: \"%s\"", type_desc_stream.GetData()); } - m_result_name = m_decl_map->GetPersistentResultName(); + m_result_name = lldb_private::ConstString("$RESULT_NAME"); if (log) log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64, @@ -806,15 +711,14 @@ IRForTarget::CreateResultVariable (llvm::Function &llvm_function) result_global->replaceAllUsesWith(new_result_global); } - - if (!m_const_result) - if (!m_decl_map->AddPersistentVariable(result_decl, - m_result_name, - m_result_type, - true, - m_result_is_pointer)) - return false; + if (!m_decl_map->AddPersistentVariable(result_decl, + m_result_name, + m_result_type, + true, + m_result_is_pointer)) + return false; + result_global->eraseFromParent(); return true; @@ -2138,10 +2042,11 @@ IRForTarget::ReplaceStaticLiterals (llvm::BasicBlock &basic_block) llvm::Instruction *inst = *user_iter; ConstantFP *operand_constant_fp = dyn_cast<ConstantFP>(operand_val); - Type *operand_type = operand_constant_fp->getType(); if (operand_constant_fp) { + Type *operand_type = operand_constant_fp->getType(); + APFloat operand_apfloat = operand_constant_fp->getValueAPF(); APInt operand_apint = operand_apfloat.bitcastToAPInt(); @@ -2195,7 +2100,7 @@ IRForTarget::ReplaceStaticLiterals (llvm::BasicBlock &basic_block) llvm::Type *fp_ptr_ty = operand_constant_fp->getType()->getPointerTo(); - Constant *new_pointer = BuildRelocation(fp_ptr_ty, offset); + Constant *new_pointer = BuildRelocation(fp_ptr_ty, aligned_offset); llvm::LoadInst *fp_load = new llvm::LoadInst(new_pointer, "fp_load", inst); @@ -2762,12 +2667,6 @@ IRForTarget::runOnModule (Module &llvm_module) return false; } - - if (m_const_result && m_execution_policy != lldb_private::eExecutionPolicyAlways) - { - m_interpret_success = true; - return true; - } for (bbi = function->begin(); bbi != function->end(); @@ -2804,20 +2703,6 @@ IRForTarget::runOnModule (Module &llvm_module) } } - if (m_decl_map && m_execution_policy != lldb_private::eExecutionPolicyAlways) - { - IRInterpreter::maybeRunOnFunction(m_decl_map, m_memory_map, m_error_stream,m_const_result, m_result_name, m_result_type, *function, llvm_module, m_interpreter_error); - - if (m_interpreter_error.Success()) - return true; - } - - if (m_execution_policy == lldb_private::eExecutionPolicyNever) { - if (m_result_name) - m_decl_map->RemoveResultVariable(m_result_name); - return false; - } - if (log && log->GetVerbose()) { std::string s; |