summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuke Drummond <luke.drummond@codeplay.com>2016-06-15 16:19:46 +0000
committerLuke Drummond <luke.drummond@codeplay.com>2016-06-15 16:19:46 +0000
commit9d4842251c0b8406fa0801208bbbe3d365eff6c3 (patch)
tree60085be2c21041ee2099ae704fe699d5cb9c8948
parent194cb55f37ad7a7ec7720945743ad3659994c7de (diff)
downloadbcm5719-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.h14
-rw-r--r--lldb/include/lldb/Target/LanguageRuntime.h9
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp36
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);
+ }
}
}
OpenPOWER on IntegriCloud