Author: ldrumm Date: Wed Jun 15 11:19:46 2016 New Revision: 272800 URL: http://llvm.org/viewvc/llvm-project?rev=272800&view=rev Log: 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. Modified: lldb/trunk/include/lldb/Expression/LLVMUserExpression.h lldb/trunk/include/lldb/Target/LanguageRuntime.h lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp Modified: lldb/trunk/include/lldb/Expression/LLVMUserExpression.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/LLVMUserExpression.h?rev=272800&r1=272799&r2=272800&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/LLVMUserExpression.h (original) +++ lldb/trunk/include/lldb/Expression/LLVMUserExpression.h Wed Jun 15 11:19:46 2016 @@ -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); Modified: lldb/trunk/include/lldb/Target/LanguageRuntime.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/LanguageRuntime.h?rev=272800&r1=272799&r2=272800&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/LanguageRuntime.h (original) +++ lldb/trunk/include/lldb/Target/LanguageRuntime.h Wed Jun 15 11:19:46 2016 @@ -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 Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp?rev=272800&r1=272799&r2=272800&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp (original) +++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp Wed Jun 15 11:19:46 2016 @@ -837,6 +837,30 @@ ClangExpressionParser::PrepareForExecuti 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::PrepareForExecuti 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); + } } } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits