diff options
author | Sean Callanan <scallanan@apple.com> | 2010-07-13 21:41:46 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2010-07-13 21:41:46 +0000 |
commit | 549c9f7f9a4b0951c17a837f08e01f5c36512b54 (patch) | |
tree | aba30ec942523154830bb7b2edd5228f108c8ded | |
parent | 50bcf13a7b5339991297eed7493cb383fa115386 (diff) | |
download | bcm5719-llvm-549c9f7f9a4b0951c17a837f08e01f5c36512b54.tar.gz bcm5719-llvm-549c9f7f9a4b0951c17a837f08e01f5c36512b54.zip |
"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.
llvm-svn: 108279
-rw-r--r-- | lldb/include/lldb/Expression/ClangExpressionDeclMap.h | 34 | ||||
-rw-r--r-- | lldb/include/lldb/Expression/IRForTarget.h | 17 | ||||
-rw-r--r-- | lldb/lldb.xcodeproj/project.pbxproj | 3 | ||||
-rw-r--r-- | lldb/source/Expression/ClangExpression.cpp | 25 | ||||
-rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 102 | ||||
-rw-r--r-- | lldb/source/Expression/IRForTarget.cpp | 208 |
6 files changed, 359 insertions, 30 deletions
diff --git a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h index b3ac176e7a7..9719d55cf42 100644 --- a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h +++ b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h @@ -27,6 +27,10 @@ namespace clang { class DeclContext; } +namespace llvm { + class Value; +} + namespace lldb_private { class Function; @@ -43,6 +47,20 @@ public: bool GetIndexForDecl (uint32_t &index, const clang::Decl *decl); + // Interface for IRForTarget + bool AddValueToStruct (llvm::Value *value, + const clang::NamedDecl *decl, + size_t size, + off_t alignment); + bool DoStructLayout (); + bool GetStructInfo (uint32_t &num_elements, + size_t &size, + off_t &alignment); + bool GetStructElement (const clang::NamedDecl *&decl, + llvm::Value *&value, + off_t &offset, + uint32_t index); + // Interface for DwarfExpression Value *GetValueForIndex (uint32_t index); @@ -57,12 +75,28 @@ private: Value *m_value; /* owned by ClangExpressionDeclMap */ }; + struct StructMember + { + const clang::NamedDecl *m_decl; + llvm::Value *m_value; + off_t m_offset; + size_t m_size; + off_t m_alignment; + }; + typedef std::vector<Tuple> TupleVector; typedef TupleVector::iterator TupleIterator; + typedef std::vector<StructMember> StructMemberVector; + typedef StructMemberVector::iterator StructMemberIterator; + TupleVector m_tuples; + StructMemberVector m_members; ExecutionContext *m_exe_ctx; SymbolContext *m_sym_ctx; /* owned by ClangExpressionDeclMap */ + off_t m_struct_alignment; + size_t m_struct_size; + bool m_struct_laid_out; void AddOneVariable(NameSearchContext &context, Variable *var); void AddOneFunction(NameSearchContext &context, Function *fun); diff --git a/lldb/include/lldb/Expression/IRForTarget.h b/lldb/include/lldb/Expression/IRForTarget.h index 8480a299f20..2e2810a3f48 100644 --- a/lldb/include/lldb/Expression/IRForTarget.h +++ b/lldb/include/lldb/Expression/IRForTarget.h @@ -11,11 +11,13 @@ #define liblldb_IRForTarget_h_ #include "llvm/Pass.h" -#include "llvm/PassManager.h" namespace llvm { class BasicBlock; + class Function; class Module; + class TargetData; + class Value; } namespace lldb_private { @@ -26,16 +28,25 @@ class IRForTarget : public llvm::ModulePass { public: IRForTarget(const void *pid, - lldb_private::ClangExpressionDeclMap *decl_map); + lldb_private::ClangExpressionDeclMap *decl_map, + const llvm::TargetData *target_data); ~IRForTarget(); bool runOnModule(llvm::Module &M); void assignPassManager(llvm::PMStack &PMS, llvm::PassManagerType T = llvm::PMT_ModulePassManager); llvm::PassManagerType getPotentialPassManagerType() const; private: - bool runOnBasicBlock(llvm::BasicBlock &BB); + bool MaybeHandleVariable(llvm::Module &M, + lldb_private::ClangExpressionDeclMap *DM, + llvm::Value *V, + bool Store); + bool runOnBasicBlock(llvm::Module &M, + llvm::BasicBlock &BB); + bool replaceVariables(llvm::Module &M, + llvm::Function *F); lldb_private::ClangExpressionDeclMap *m_decl_map; + const llvm::TargetData *m_target_data; }; #endif
\ No newline at end of file diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index ad1b225251c..16b428ca2cb 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -2252,6 +2252,9 @@ buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */; compatibilityVersion = "Xcode 3.1"; hasScannedForEncodings = 1; + knownRegions = ( + en, + ); mainGroup = 08FB7794FE84155DC02AAC07 /* lldb */; projectDirPath = ""; projectReferences = ( diff --git a/lldb/source/Expression/ClangExpression.cpp b/lldb/source/Expression/ClangExpression.cpp index 2383faef054..14033662650 100644 --- a/lldb/source/Expression/ClangExpression.cpp +++ b/lldb/source/Expression/ClangExpression.cpp @@ -50,6 +50,7 @@ #include "llvm/System/DynamicLibrary.h" #include "llvm/System/Host.h" #include "llvm/System/Signals.h" +#include "llvm/Target/TargetRegistry.h" #include "llvm/Target/TargetSelect.h" // Project includes @@ -240,6 +241,9 @@ ClangExpression::CreateCompilerInstance (bool &IsAST) m_clang_ap->getLangOpts().CPlusPlus = true; m_clang_ap->getLangOpts().ObjC1 = true; m_clang_ap->getLangOpts().ThreadsafeStatics = false; + + // Set CodeGen options + m_clang_ap->getCodeGenOpts().EmitDeclMetadata = true; // Disable some warnings. m_clang_ap->getDiagnosticOpts().Warnings.push_back("no-unused-value"); @@ -250,7 +254,6 @@ ClangExpression::CreateCompilerInstance (bool &IsAST) // 3. Set up various important bits of infrastructure. m_clang_ap->createDiagnostics(0, 0); - m_clang_ap->getLangOpts().CPlusPlus = true; // Create the target instance. m_clang_ap->setTarget(TargetInfo::CreateTargetInfo(m_clang_ap->getDiagnostics(), @@ -294,7 +297,7 @@ ClangExpression::ParseExpression (const char *expr_text, { // HACK: for now we have to make a function body around our expression // since there is no way to parse a single expression line in LLVM/Clang. - std::string func_expr("extern \"C\" void ___clang_expr()\n{\n\t"); + std::string func_expr("extern \"C\" void ___clang_expr(void *___clang_arg)\n{\n\t"); func_expr.append(expr_text); func_expr.append(";\n}"); return ParseBareExpression (func_expr, stream, add_result_var); @@ -513,7 +516,23 @@ ClangExpression::PrepareIRForTarget (ClangExpressionVariableList &expr_local_var return 1; } - IRForTarget ir_for_target("IR for target", m_decl_map); + llvm::Triple target_triple = m_clang_ap->getTarget().getTriple(); + + std::string err; + + const llvm::Target *target = llvm::TargetRegistry::lookupTarget(m_target_triple, err); + + if (!target) + { + if (log) + log->Printf("Couldn't find a target for %s", m_target_triple.c_str()); + + return 1; + } + + std::auto_ptr<llvm::TargetMachine> target_machine(target->createTargetMachine(m_target_triple, "")); + + IRForTarget ir_for_target("IR for target", m_decl_map, target_machine->getTargetData()); return ir_for_target.runOnModule(*module); } diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index d78f84075db..b83cf4a330e 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -38,7 +38,8 @@ using namespace lldb_private; using namespace clang; ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx) : - m_exe_ctx(exe_ctx) + m_exe_ctx(exe_ctx), + m_struct_laid_out(false) { if (exe_ctx && exe_ctx->frame) m_sym_ctx = new SymbolContext(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything)); @@ -77,6 +78,105 @@ ClangExpressionDeclMap::GetIndexForDecl (uint32_t &index, return false; } +// Interface for IRForTarget + +bool +ClangExpressionDeclMap::AddValueToStruct (llvm::Value *value, + const clang::NamedDecl *decl, + size_t size, + off_t alignment) +{ + m_struct_laid_out = false; + + StructMemberIterator iter; + + for (iter = m_members.begin(); + iter != m_members.end(); + ++iter) + { + if (iter->m_decl == decl) + return true; + } + + StructMember member; + + member.m_value = value; + member.m_decl = decl; + member.m_offset = 0; + member.m_size = size; + member.m_alignment = alignment; + + m_members.push_back(member); + + return true; +} + +bool +ClangExpressionDeclMap::DoStructLayout () +{ + if (m_struct_laid_out) + return true; + + StructMemberIterator iter; + + off_t cursor = 0; + + m_struct_alignment = 0; + m_struct_size = 0; + + for (iter = m_members.begin(); + iter != m_members.end(); + ++iter) + { + if (iter == m_members.begin()) + m_struct_alignment = iter->m_alignment; + + if (cursor % iter->m_alignment) + cursor += (iter->m_alignment - (cursor % iter->m_alignment)); + + iter->m_offset = cursor; + cursor += iter->m_size; + } + + m_struct_size = cursor; + + m_struct_laid_out = true; + return true; +} + +bool ClangExpressionDeclMap::GetStructInfo (uint32_t &num_elements, + size_t &size, + off_t &alignment) +{ + if (!m_struct_laid_out) + return false; + + num_elements = m_members.size(); + size = m_struct_size; + alignment = m_struct_alignment; + + return true; +} + +bool +ClangExpressionDeclMap::GetStructElement (const clang::NamedDecl *&decl, + llvm::Value *&value, + off_t &offset, + uint32_t index) +{ + if (!m_struct_laid_out) + return false; + + if (index >= m_members.size()) + return false; + + decl = m_members[index].m_decl; + value = m_members[index].m_value; + offset = m_members[index].m_offset; + + return true; +} + // Interface for DwarfExpression Value *ClangExpressionDeclMap::GetValueForIndex (uint32_t index) diff --git a/lldb/source/Expression/IRForTarget.cpp b/lldb/source/Expression/IRForTarget.cpp index a6b50e59127..8876109448e 100644 --- a/lldb/source/Expression/IRForTarget.cpp +++ b/lldb/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,38 +40,177 @@ IRForTarget::~IRForTarget() { } -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 // + llvm::BasicBlock::iterator ii; + + for (ii = BB.begin(); + ii != BB.end(); + ++ii) + { + Instruction &inst = *ii; + + if (LoadInst *load = dyn_cast<LoadInst>(&inst)) + if (!MaybeHandleVariable(M, m_decl_map, load->getPointerOperand(), false)) + return false; + + 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) { - log->Printf("Preparing basic block %s:", - BB.hasName() ? BB.getNameStr().c_str() : "[anonymous]"); + const clang::NamedDecl *decl; + llvm::Value *value; + off_t offset; - llvm::BasicBlock::iterator ii; + if (!m_decl_map->GetStructElement (decl, value, offset, element_index)) + 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 (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; } @@ -90,7 +235,24 @@ IRForTarget::runOnModule(Module &M) 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 @@ IRForTarget::runOnModule(Module &M) void IRForTarget::assignPassManager(PMStack &PMS, - PassManagerType T) + PassManagerType T) { } |