"expr -i" now performs the required transforms to
prepare the IR for JIT compilation. We still need
to do the JIT compilation and move the arguments
in/out of target memory.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@108279 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/IRForTarget.cpp b/source/Expression/IRForTarget.cpp
index a6b50e5..8876109 100644
--- a/source/Expression/IRForTarget.cpp
+++ b/source/Expression/IRForTarget.cpp
@@ -11,7 +11,11 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/InstrTypes.h"
+#include "llvm/Instructions.h"
#include "llvm/Module.h"
+#include "llvm/Target/TargetData.h"
+
+#include "clang/AST/ASTContext.h"
#include "lldb/Core/dwarf.h"
#include "lldb/Core/Log.h"
@@ -24,9 +28,11 @@
using namespace llvm;
IRForTarget::IRForTarget(const void *pid,
- lldb_private::ClangExpressionDeclMap *decl_map) :
+ lldb_private::ClangExpressionDeclMap *decl_map,
+ const llvm::TargetData *target_data) :
ModulePass(pid),
- m_decl_map(decl_map)
+ m_decl_map(decl_map),
+ m_target_data(target_data)
{
}
@@ -34,41 +40,180 @@
{
}
-bool
-IRForTarget::runOnBasicBlock(BasicBlock &BB)
+static clang::NamedDecl *
+DeclForGlobalValue(llvm::Module &module,
+ llvm::GlobalValue *global_value)
+{
+ NamedMDNode *named_metadata = module.getNamedMetadata("clang.global.decl.ptrs");
+
+ if (!named_metadata)
+ return NULL;
+
+ unsigned num_nodes = named_metadata->getNumOperands();
+ unsigned node_index;
+
+ for (node_index = 0;
+ node_index < num_nodes;
+ ++node_index)
+ {
+ MDNode *metadata_node = named_metadata->getOperand(node_index);
+
+ if (!metadata_node)
+ return NULL;
+
+ if (metadata_node->getNumOperands() != 2)
+ return NULL;
+
+ if (metadata_node->getOperand(0) != global_value)
+ continue;
+
+ ConstantInt *constant_int = dyn_cast<ConstantInt>(metadata_node->getOperand(1));
+
+ if (!constant_int)
+ return NULL;
+
+ uintptr_t ptr = constant_int->getZExtValue();
+
+ return reinterpret_cast<clang::NamedDecl *>(ptr);
+ }
+
+ return NULL;
+}
+
+bool
+IRForTarget::MaybeHandleVariable(Module &M,
+ lldb_private::ClangExpressionDeclMap *DM,
+ llvm::Value *V,
+ bool Store)
{
lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
+
+ if (GlobalVariable *global_variable = dyn_cast<GlobalVariable>(V))
+ {
+ clang::NamedDecl *named_decl = DeclForGlobalValue(M, global_variable);
+ const llvm::Type *value_type = global_variable->getType();
+
+ size_t value_size = m_target_data->getTypeStoreSize(value_type);
+ off_t value_alignment = m_target_data->getPrefTypeAlignment(value_type);
+
+ if (named_decl && !DM->AddValueToStruct(V, named_decl, value_size, value_alignment))
+ return false;
+ }
+
+ return true;
+}
+
+bool
+IRForTarget::runOnBasicBlock(Module &M, BasicBlock &BB)
+{
/////////////////////////////////////////////////////////////////////////
// Prepare the current basic block for execution in the remote process
//
- if (log)
+ llvm::BasicBlock::iterator ii;
+
+ for (ii = BB.begin();
+ ii != BB.end();
+ ++ii)
{
- log->Printf("Preparing basic block %s:",
- BB.hasName() ? BB.getNameStr().c_str() : "[anonymous]");
+ Instruction &inst = *ii;
- llvm::BasicBlock::iterator ii;
+ if (LoadInst *load = dyn_cast<LoadInst>(&inst))
+ if (!MaybeHandleVariable(M, m_decl_map, load->getPointerOperand(), false))
+ return false;
- for (ii = BB.begin();
- ii != BB.end();
- ++ii)
- {
- llvm::Instruction &inst = *ii;
-
- std::string s;
- raw_string_ostream os(s);
-
- inst.print(os);
-
- if (log)
- log->Printf(" %s", s.c_str());
- }
+ if (StoreInst *store = dyn_cast<StoreInst>(&inst))
+ if (!MaybeHandleVariable(M, m_decl_map, store->getPointerOperand(), false))
+ return false;
}
return true;
}
+static std::string PrintValue(llvm::Value *V, bool truncate = false)
+{
+ std::string s;
+ raw_string_ostream rso(s);
+ V->print(rso);
+ rso.flush();
+ if (truncate)
+ s.resize(s.length() - 1);
+ return s;
+}
+
+bool
+IRForTarget::replaceVariables(Module &M, Function *F)
+{
+ lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
+
+ m_decl_map->DoStructLayout();
+
+ if (log)
+ log->Printf("Element arrangement:");
+
+ uint32_t num_elements;
+ uint32_t element_index;
+
+ size_t size;
+ off_t alignment;
+
+ if (!m_decl_map->GetStructInfo (num_elements, size, alignment))
+ return false;
+
+ Function::arg_iterator iter(F->getArgumentList().begin());
+
+ if (iter == F->getArgumentList().end())
+ return false;
+
+ llvm::Argument *argument = iter;
+
+ if (!argument->getName().equals("___clang_arg"))
+ return false;
+
+ if (log)
+ log->Printf("Arg: %s", PrintValue(argument).c_str());
+
+ llvm::BasicBlock &entry_block(F->getEntryBlock());
+ llvm::Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
+
+ if (!first_entry_instruction)
+ return false;
+
+ LLVMContext &context(M.getContext());
+ const IntegerType *offset_type(Type::getInt32Ty(context));
+
+ if (!offset_type)
+ return false;
+
+ for (element_index = 0; element_index < num_elements; ++element_index)
+ {
+ const clang::NamedDecl *decl;
+ llvm::Value *value;
+ off_t offset;
+
+ if (!m_decl_map->GetStructElement (decl, value, offset, element_index))
+ return false;
+
+ if (log)
+ log->Printf(" %s (%s) placed at %d",
+ decl->getIdentifier()->getNameStart(),
+ PrintValue(value, true).c_str(),
+ offset);
+
+ ConstantInt *offset_int(ConstantInt::getSigned(offset_type, offset));
+ GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(argument, offset_int, "", first_entry_instruction);
+ BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType(), "", first_entry_instruction);
+
+ value->replaceAllUsesWith(bit_cast);
+ }
+
+ if (log)
+ log->Printf("Total structure [align %d, size %d]", alignment, size);
+
+ return true;
+}
+
bool
IRForTarget::runOnModule(Module &M)
{
@@ -90,7 +235,24 @@
bbi != function->end();
++bbi)
{
- runOnBasicBlock(*bbi);
+ if (!runOnBasicBlock(M, *bbi))
+ return false;
+ }
+
+ if (!replaceVariables(M, function))
+ return false;
+
+ if (log)
+ {
+ for (bbi = function->begin();
+ bbi != function->end();
+ ++bbi)
+ {
+ log->Printf("Rewrote basic block %s for running: \n%s",
+ bbi->hasName() ? bbi->getNameStr().c_str() : "[anonymous]",
+ PrintValue(bbi).c_str());
+ }
+
}
return true;
@@ -98,7 +260,7 @@
void
IRForTarget::assignPassManager(PMStack &PMS,
- PassManagerType T)
+ PassManagerType T)
{
}