diff options
author | Luke Drummond <luke.drummond@codeplay.com> | 2016-06-15 16:19:46 +0000 |
---|---|---|
committer | Luke Drummond <luke.drummond@codeplay.com> | 2016-06-15 16:19:46 +0000 |
commit | 9d4842251c0b8406fa0801208bbbe3d365eff6c3 (patch) | |
tree | 60085be2c21041ee2099ae704fe699d5cb9c8948 | |
parent | 194cb55f37ad7a7ec7720945743ad3659994c7de (diff) | |
download | bcm5719-llvm-9d4842251c0b8406fa0801208bbbe3d365eff6c3.tar.gz bcm5719-llvm-9d4842251c0b8406fa0801208bbbe3d365eff6c3.zip |
Allow runtimes to execute custom LLVM ModulePasses over the expression IR
During expression evaluation, the ClangExpressionParser preforms a
number of hard-coded fixups on the expression's IR before the module
is assembled and dispatched to be run in a ThreadPlan.
This patch allows the runtimes to register LLVM passes to be run over the
generated IR, that they may perform language or architecture-specfic fixups
or analyses over the generated expression.
This makes expression evaluation for plugins more flexible and allows
language-specific fixes to reside in their own module, rather than
littering the expression evaluator itself with language-specific fixes.
llvm-svn: 272800
-rw-r--r-- | lldb/include/lldb/Expression/LLVMUserExpression.h | 14 | ||||
-rw-r--r-- | lldb/include/lldb/Target/LanguageRuntime.h | 9 | ||||
-rw-r--r-- | lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp | 36 |
3 files changed, 58 insertions, 1 deletions
diff --git a/lldb/include/lldb/Expression/LLVMUserExpression.h b/lldb/include/lldb/Expression/LLVMUserExpression.h index 8775c8bd865..3762fa11ddb 100644 --- a/lldb/include/lldb/Expression/LLVMUserExpression.h +++ b/lldb/include/lldb/Expression/LLVMUserExpression.h @@ -16,6 +16,9 @@ #include <map> #include <vector> +// Other libraries and framework includes +#include "llvm/IR/LegacyPassManager.h" + // Project includes #include "lldb/Expression/UserExpression.h" @@ -35,6 +38,17 @@ namespace lldb_private class LLVMUserExpression : public UserExpression { public: + // The IRPasses struct is filled in by a runtime after an expression is compiled and can be used to to run + // fixups/analysis passes as required. EarlyPasses are run on the generated module before lldb runs its own IR + // fixups and inserts instrumentation code/pointer checks. LatePasses are run after the module has been processed by + // llvm, before the module is assembled and run in the ThreadPlan. + struct IRPasses + { + IRPasses() : EarlyPasses(nullptr), LatePasses(nullptr){}; + std::shared_ptr<llvm::legacy::PassManager> EarlyPasses; + std::shared_ptr<llvm::legacy::PassManager> LatePasses; + }; + LLVMUserExpression(ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix, lldb::LanguageType language, ResultType desired_type, const EvaluateExpressionOptions &options); diff --git a/lldb/include/lldb/Target/LanguageRuntime.h b/lldb/include/lldb/Target/LanguageRuntime.h index 20473e3b793..beb7a9e7487 100644 --- a/lldb/include/lldb/Target/LanguageRuntime.h +++ b/lldb/include/lldb/Target/LanguageRuntime.h @@ -22,6 +22,8 @@ #include "lldb/Core/ValueObject.h" #include "lldb/Core/Value.h" #include "lldb/Target/ExecutionContextScope.h" +#include "lldb/Expression/LLVMUserExpression.h" + #include "clang/Basic/TargetOptions.h" namespace lldb_private { @@ -157,6 +159,13 @@ public: return false; } + // Called by ClangExpressionParser::PrepareForExecution to query for any custom LLVM IR passes + // that need to be run before an expression is assembled and run. + virtual bool + GetIRPasses(LLVMUserExpression::IRPasses &custom_passes) + { + return false; + } protected: //------------------------------------------------------------------ // Classes that inherit from LanguageRuntime can see and modify these diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index a9c2f560cc0..d1a3c0dea82 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -837,6 +837,30 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr, sc.target_sp = target_sp; } + LLVMUserExpression::IRPasses custom_passes; + { + auto lang = m_expr.Language(); + if (log) + log->Printf("%s - Currrent expression language is %s\n", __FUNCTION__, + Language::GetNameForLanguageType(lang)); + + if (lang != lldb::eLanguageTypeUnknown) + { + auto runtime = exe_ctx.GetProcessSP()->GetLanguageRuntime(lang); + if (runtime) + runtime->GetIRPasses(custom_passes); + } + } + + if (custom_passes.EarlyPasses) + { + if (log) + log->Printf("%s - Running Early IR Passes from LanguageRuntime on expression module '%s'", __FUNCTION__, + m_expr.FunctionName()); + + custom_passes.EarlyPasses->run(*llvm_module_ap); + } + execution_unit_sp.reset(new IRExecutionUnit (m_llvm_context, // handed off here llvm_module_ap, // handed off here function_name, @@ -925,12 +949,22 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr, IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.AsCString()); - if (!ir_dynamic_checks.runOnModule(*execution_unit_sp->GetModule())) + llvm::Module *module = execution_unit_sp->GetModule(); + if (!module || !ir_dynamic_checks.runOnModule(*module)) { err.SetErrorToGenericError(); err.SetErrorString("Couldn't add dynamic checks to the expression"); return err; } + + if (custom_passes.LatePasses) + { + if (log) + log->Printf("%s - Running Late IR Passes from LanguageRuntime on expression module '%s'", + __FUNCTION__, m_expr.FunctionName()); + + custom_passes.LatePasses->run(*module); + } } } |