[Lldb-commits] [lldb] r108279 - in /lldb/trunk: include/lldb/Expression/ClangExpressionDeclMap.h include/lldb/Expression/IRForTarget.h lldb.xcodeproj/project.pbxproj source/Expression/ClangExpression.cpp source/Expression/ClangExpressionDeclMap.cpp source/Expression/IRForTarget.cpp

Sean Callanan scallanan at apple.com
Tue Jul 13 14:41:46 PDT 2010


Author: spyffe
Date: Tue Jul 13 16:41:46 2010
New Revision: 108279

URL: http://llvm.org/viewvc/llvm-project?rev=108279&view=rev
Log:
"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.

Modified:
    lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
    lldb/trunk/include/lldb/Expression/IRForTarget.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Expression/ClangExpression.cpp
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Expression/IRForTarget.cpp

Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=108279&r1=108278&r2=108279&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Tue Jul 13 16:41:46 2010
@@ -27,6 +27,10 @@
     class DeclContext;
 }
 
+namespace llvm {
+    class Value;
+}
+
 namespace lldb_private {
 
 class Function;
@@ -43,6 +47,20 @@
     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 @@
         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);

Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRForTarget.h?rev=108279&r1=108278&r2=108279&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/IRForTarget.h (original)
+++ lldb/trunk/include/lldb/Expression/IRForTarget.h Tue Jul 13 16:41:46 2010
@@ -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 @@
 {
 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

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=108279&r1=108278&r2=108279&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Tue Jul 13 16:41:46 2010
@@ -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 = (

Modified: lldb/trunk/source/Expression/ClangExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpression.cpp?rev=108279&r1=108278&r2=108279&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpression.cpp Tue Jul 13 16:41:46 2010
@@ -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 @@
     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 @@
     // 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 @@
 {
     // 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 @@
         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);
 }

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=108279&r1=108278&r2=108279&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Tue Jul 13 16:41:46 2010
@@ -38,7 +38,8 @@
 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 @@
     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)

Modified: lldb/trunk/source/Expression/IRForTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=108279&r1=108278&r2=108279&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRForTarget.cpp (original)
+++ lldb/trunk/source/Expression/IRForTarget.cpp Tue Jul 13 16:41:46 2010
@@ -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 @@
 {
 }
 
-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 @@
          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)
 {
 }
 





More information about the lldb-commits mailing list