diff options
| author | Sean Callanan <scallanan@apple.com> | 2010-08-17 22:36:13 +0000 |
|---|---|---|
| committer | Sean Callanan <scallanan@apple.com> | 2010-08-17 22:36:13 +0000 |
| commit | f346a3dd680d4b72eb6f20a7c05df09202446b80 (patch) | |
| tree | 20d448ce90b757bef5980b8c6e63f19d2560b571 | |
| parent | efdc74ea597f0c44af4909ecf465e5118f714183 (diff) | |
| download | bcm5719-llvm-f346a3dd680d4b72eb6f20a7c05df09202446b80.tar.gz bcm5719-llvm-f346a3dd680d4b72eb6f20a7c05df09202446b80.zip | |
Documented IRForTarget
llvm-svn: 111313
| -rw-r--r-- | lldb/include/lldb/Expression/IRForTarget.h | 220 |
1 files changed, 203 insertions, 17 deletions
diff --git a/lldb/include/lldb/Expression/IRForTarget.h b/lldb/include/lldb/Expression/IRForTarget.h index db18e5b6715..4d6f5527d7a 100644 --- a/lldb/include/lldb/Expression/IRForTarget.h +++ b/lldb/include/lldb/Expression/IRForTarget.h @@ -27,61 +27,247 @@ namespace lldb_private { class ClangExpressionDeclMap; } +//---------------------------------------------------------------------- +/// @class IRForTarget IRForTarget.h "lldb/Expression/IRForTarget.h" +/// @brief Transforms the IR for a function to run in the target +/// +/// Once an expression has been parsed and converted to IR, it can run +/// in two contexts: interpreted by LLDB as a DWARF location expression, +/// or compiled by the JIT and inserted into the target process for +/// execution. +/// +/// IRForTarget makes the second possible, by applying a series of +/// transformations to the IR which make it relocatable. These +/// transformations are discussed in more detail next to their relevant +/// functions. +//---------------------------------------------------------------------- class IRForTarget : public llvm::ModulePass { public: + //------------------------------------------------------------------ + /// Constructor + /// + /// @param[in] pid + /// A unique identifier for this pass. I'm not sure what this does; + /// it just gets passed down to ModulePass's constructor. + /// + /// @param[in] decl_map + /// The list of externally-referenced variables for the expression, + /// for use in looking up globals and allocating the argument + /// struct. See the documentation for ClangExpressionDeclMap. + /// + /// @param[in] target_data + /// The data layout information for the target. This information is + /// used to determine the sizes of types that have been lowered into + /// IR types. + //------------------------------------------------------------------ IRForTarget(const void *pid, lldb_private::ClangExpressionDeclMap *decl_map, const llvm::TargetData *target_data); + + //------------------------------------------------------------------ + /// Destructor + //------------------------------------------------------------------ ~IRForTarget(); + + //------------------------------------------------------------------ + /// Run this IR transformer on a single module + /// + /// @param[in] M + /// The module to run on. This module is searched for the function + /// ___clang_expr, and that function is passed to the passes one by + /// one. + //------------------------------------------------------------------ bool runOnModule(llvm::Module &M); + + //------------------------------------------------------------------ + /// Interface stub + //------------------------------------------------------------------ void assignPassManager(llvm::PMStack &PMS, llvm::PassManagerType T = llvm::PMT_ModulePassManager); + + //------------------------------------------------------------------ + /// Returns PMT_ModulePassManager + //------------------------------------------------------------------ llvm::PassManagerType getPotentialPassManagerType() const; private: - // pass to find the result variable created in the result synthesizer and - // make a result variable out of it (or a void variable if there is no - // result) + //------------------------------------------------------------------ + /// A function-level pass to take the generated global value + /// ___clang_expr_result and make it into a persistent variable. + /// Also see ClangResultSynthesizer. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// The top-level pass implementation + /// + /// @param[in] M + /// The module currently being processed. + /// + /// @param[in] F + /// The function currently being processed. + //------------------------------------------------------------------ bool createResultVariable(llvm::Module &M, llvm::Function &F); - - // pass to rewrite Objective-C method calls to use the runtime function - // sel_registerName + + //------------------------------------------------------------------ + /// A basic block-level pass to find all Objective-C method calls and + /// rewrite them to use sel_registerName instead of statically allocated + /// selectors. The reason is that the selectors are created on the + /// assumption that the Objective-C runtime will scan the appropriate + /// section and prepare them. This doesn't happen when code is copied + /// into the target, though, and there's no easy way to induce the + /// runtime to scan them. So instead we get our selectors from + /// sel_registerName. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// Replace a single selector reference + /// + /// @param[in] selector_load + /// The load of the statically-allocated selector. + /// + /// @param[in] BB + /// The basic block currently being processed. + //------------------------------------------------------------------ bool RewriteObjCSelector(llvm::Instruction* selector_load, llvm::Module &M); + + //------------------------------------------------------------------ + /// The top-level pass implementation + /// + /// @param[in] M + /// The module currently being processed. + /// + /// @param[in] BB + /// The basic block currently being processed. + //------------------------------------------------------------------ bool rewriteObjCSelectors(llvm::Module &M, llvm::BasicBlock &BB); - // pass to find declarations of, and references to, persistent variables and - // register them for (de)materialization + //------------------------------------------------------------------ + /// A basic block-level pass to find all newly-declared persistent + /// variables and register them with the ClangExprDeclMap. This + /// allows them to be materialized and dematerialized like normal + /// external variables. Before transformation, these persistent + /// variables look like normal locals, so they have an allocation. + /// This pass excises these allocations and makes references look + /// like external references where they will be resolved -- like all + /// other external references -- by resolveExternals(). + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// Handle a single allocation of a persistent variable + /// + /// @param[in] persistent_alloc + /// The allocation of the persistent variable. + /// + /// @param[in] M + /// The module currently being processed. + //------------------------------------------------------------------ bool RewritePersistentAlloc(llvm::Instruction *persistent_alloc, llvm::Module &M); + + //------------------------------------------------------------------ + /// The top-level pass implementation + /// + /// @param[in] M + /// The module currently being processed. + /// + /// @param[in] BB + /// The basic block currently being processed. + //------------------------------------------------------------------ bool rewritePersistentAllocs(llvm::Module &M, llvm::BasicBlock &BB); - // pass to register referenced variables and redirect functions at their - // targets in the debugged process + //------------------------------------------------------------------ + /// A basic block-level pass to find all external variables and + /// functions used in the IR. Each found external variable is added + /// to the struct, and each external function is resolved in place, + /// its call replaced with a call to a function pointer whose value + /// is the address of the function in the target process. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// Handle a single externally-defined variable + /// + /// @param[in] M + /// The module currently being processed. + /// + /// @param[in] V + /// The variable. + /// + /// @param[in] Store + /// True if the access is a store. + //------------------------------------------------------------------ bool MaybeHandleVariable(llvm::Module &M, llvm::Value *V, bool Store); + + //------------------------------------------------------------------ + /// Handle a single external function call + /// + /// @param[in] M + /// The module currently being processed. + /// + /// @param[in] C + /// The call instruction. + //------------------------------------------------------------------ bool MaybeHandleCall(llvm::Module &M, llvm::CallInst *C); + + //------------------------------------------------------------------ + /// The top-level pass implementation + /// + /// @param[in] M + /// The module currently being processed. + /// + /// @param[in] BB + /// The basic block currently being processed. + //------------------------------------------------------------------ bool resolveExternals(llvm::Module &M, llvm::BasicBlock &BB); - // pass to find references to guard variables and excise them + //------------------------------------------------------------------ + /// A basic block-level pass to excise guard variables from the code. + /// The result for the function is passed through Clang as a static + /// variable. Static variables normally have guard variables to + /// ensure that they are only initialized once. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// The top-level pass implementation + /// + /// @param[in] M + /// The module currently being processed. + /// + /// @param[in] BB + /// The basic block currently being processed. + //------------------------------------------------------------------ bool removeGuards(llvm::Module &M, llvm::BasicBlock &BB); - // pass to replace all identified variables with references to members of - // the argument struct + //------------------------------------------------------------------ + /// A function-level pass to make all external variable references + /// point at the correct offsets from the void* passed into the + /// function. ClangExpressionDeclMap::DoStructLayout() must be called + /// beforehand, so that the offsets are valid. + //------------------------------------------------------------------ + + //------------------------------------------------------------------ + /// The top-level pass implementation + /// + /// @param[in] M + /// The module currently being processed. + /// + /// @param[in] F + /// The function currently being processed. + //------------------------------------------------------------------ bool replaceVariables(llvm::Module &M, llvm::Function &F); - lldb_private::ClangExpressionDeclMap *m_decl_map; - const llvm::TargetData *m_target_data; - - llvm::Constant *m_sel_registerName; + lldb_private::ClangExpressionDeclMap *m_decl_map; ///< The DeclMap containing the Decls + const llvm::TargetData *m_target_data; ///< The TargetData for use in determining type sizes + llvm::Constant *m_sel_registerName; ///< The address of the function sel_registerName, cast to the appropriate function pointer type }; #endif |

