forked from OSchip/llvm-project
Add the ability to set breakpoints on named RenderScript reductions
- Add new `lldb_private::lldb_renderscript::RSReduceBreakpointResolver` class that can set breakpoints on kernels that are constituent functions of named reduction groups. Also support debugging of subsets of the the reduction group with the `-t, --function-role` flag which takes a comma-separated list of reduction function types outconverter,combiner,initializer,accumulator (defaults to all) - Add 2 new helper methods to `RenderScriptRuntime`, 1. `CreateReductionBreakpoint(name, types)`: instantiates a new RSReduceBreakpointResolver and inserts that resolver into the running process. 2. `PlaceBreakpointOnReduction`: which is a public helper function. - hook up the above functionality to the command-line with new `CommandObject*` classes that handle parsing of function roles and dispatch to the runtime. These are namespaced under the snappy `language renderscript reduction breakpoint ...` subcommand - [incidental] Factor multiple common uses of `FindFirstSymbolWithNameAndType(ConstString(".rs.info")` into static `IsRenderScriptScriptModule(ModuleSP module)` function, and replace original uses. llvm-svn: 283362
This commit is contained in:
parent
a40c479fe9
commit
b3bbcb1229
|
@ -10,7 +10,7 @@
|
|||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
|
||||
// Project includes
|
||||
#include "RenderScriptRuntime.h"
|
||||
|
@ -432,6 +432,13 @@ bool GetArgs(ExecutionContext &exe_ctx, ArgItem *arg_list, size_t num_args) {
|
|||
}
|
||||
}
|
||||
|
||||
bool IsRenderScriptScriptModule(ModuleSP module) {
|
||||
if (!module)
|
||||
return false;
|
||||
return module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"),
|
||||
eSymbolTypeData) != nullptr;
|
||||
}
|
||||
|
||||
bool ParseCoordinate(llvm::StringRef coord_s, RSCoordinate &coord) {
|
||||
// takes an argument of the form 'num[,num][,num]'.
|
||||
// Where 'coord_s' is a comma separated 1,2 or 3-dimensional coordinate
|
||||
|
@ -781,13 +788,7 @@ RSBreakpointResolver::SearchCallback(SearchFilter &filter,
|
|||
SymbolContext &context, Address *, bool) {
|
||||
ModuleSP module = context.module_sp;
|
||||
|
||||
if (!module)
|
||||
return Searcher::eCallbackReturnContinue;
|
||||
|
||||
// Is this a module containing renderscript kernels?
|
||||
if (nullptr ==
|
||||
module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"),
|
||||
eSymbolTypeData))
|
||||
if (!module || !IsRenderScriptScriptModule(module))
|
||||
return Searcher::eCallbackReturnContinue;
|
||||
|
||||
// Attempt to set a breakpoint on the kernel name symbol within the module
|
||||
|
@ -811,6 +812,66 @@ RSBreakpointResolver::SearchCallback(SearchFilter &filter,
|
|||
return Searcher::eCallbackReturnContinue;
|
||||
}
|
||||
|
||||
Searcher::CallbackReturn
|
||||
RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter,
|
||||
lldb_private::SymbolContext &context,
|
||||
Address *, bool) {
|
||||
// We need to have access to the list of reductions currently parsed, as
|
||||
// reduce names don't actually exist as
|
||||
// symbols in a module. They are only identifiable by parsing the .rs.info
|
||||
// packet, or finding the expand symbol. We
|
||||
// therefore need access to the list of parsed rs modules to properly resolve
|
||||
// reduction names.
|
||||
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
|
||||
ModuleSP module = context.module_sp;
|
||||
|
||||
if (!module || !IsRenderScriptScriptModule(module))
|
||||
return Searcher::eCallbackReturnContinue;
|
||||
|
||||
if (!m_rsmodules)
|
||||
return Searcher::eCallbackReturnContinue;
|
||||
|
||||
for (const auto &module_desc : *m_rsmodules) {
|
||||
if (module_desc->m_module != module)
|
||||
continue;
|
||||
|
||||
for (const auto &reduction : module_desc->m_reductions) {
|
||||
if (reduction.m_reduce_name != m_reduce_name)
|
||||
continue;
|
||||
|
||||
std::array<std::pair<ConstString, int>, 5> funcs{
|
||||
{{reduction.m_init_name, eKernelTypeInit},
|
||||
{reduction.m_accum_name, eKernelTypeAccum},
|
||||
{reduction.m_comb_name, eKernelTypeComb},
|
||||
{reduction.m_outc_name, eKernelTypeOutC},
|
||||
{reduction.m_halter_name, eKernelTypeHalter}}};
|
||||
|
||||
for (const auto &kernel : funcs) {
|
||||
// Skip constituent functions that don't match our spec
|
||||
if (!(m_kernel_types & kernel.second))
|
||||
continue;
|
||||
|
||||
const auto kernel_name = kernel.first;
|
||||
const auto symbol = module->FindFirstSymbolWithNameAndType(
|
||||
kernel_name, eSymbolTypeCode);
|
||||
if (!symbol)
|
||||
continue;
|
||||
|
||||
auto address = symbol->GetAddress();
|
||||
if (filter.AddressPasses(address)) {
|
||||
bool new_bp;
|
||||
m_breakpoint->AddLocation(address, &new_bp);
|
||||
if (log)
|
||||
log->Printf("%s: %s reduction breakpoint on %s in %s", __FUNCTION__,
|
||||
new_bp ? "new" : "existing", kernel_name.GetCString(),
|
||||
address.GetModule()->GetFileSpec().GetCString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return eCallbackReturnContinue;
|
||||
}
|
||||
|
||||
void RenderScriptRuntime::Initialize() {
|
||||
PluginManager::RegisterPlugin(GetPluginNameStatic(),
|
||||
"RenderScript language support", CreateInstance,
|
||||
|
@ -829,12 +890,8 @@ lldb_private::ConstString RenderScriptRuntime::GetPluginNameStatic() {
|
|||
RenderScriptRuntime::ModuleKind
|
||||
RenderScriptRuntime::GetModuleKind(const lldb::ModuleSP &module_sp) {
|
||||
if (module_sp) {
|
||||
// Is this a module containing renderscript kernels?
|
||||
const Symbol *info_sym = module_sp->FindFirstSymbolWithNameAndType(
|
||||
ConstString(".rs.info"), eSymbolTypeData);
|
||||
if (info_sym) {
|
||||
if (IsRenderScriptScriptModule(module_sp))
|
||||
return eModuleKindKernelObj;
|
||||
}
|
||||
|
||||
// Is this the main RS runtime library
|
||||
const ConstString rs_lib("libRS.so");
|
||||
|
@ -2722,17 +2779,21 @@ bool RSModuleDescriptor::ParseRSInfo() {
|
|||
eObjectSlot
|
||||
};
|
||||
|
||||
static const llvm::StringMap<int> rs_info_handlers{
|
||||
{// The number of visible global variables in the script
|
||||
{"exportVarCount", eExportVar},
|
||||
const auto rs_info_handler = [](llvm::StringRef name) -> int {
|
||||
return llvm::StringSwitch<int>(name)
|
||||
// The number of visible global variables in the script
|
||||
.Case("exportVarCount", eExportVar)
|
||||
// The number of RenderScrip `forEach` kernels __attribute__((kernel))
|
||||
{"exportForEachCount", eExportForEach},
|
||||
// The number of generalreductions: This marked in the script by `#pragma
|
||||
// reduce()`
|
||||
{"exportReduceCount", eExportReduce},
|
||||
// Total count of all RenderScript specific `#pragmas` used in the script
|
||||
{"pragmaCount", ePragma},
|
||||
{"objectSlotCount", eObjectSlot}}};
|
||||
.Case("exportForEachCount", eExportForEach)
|
||||
// The number of generalreductions: This marked in the script by
|
||||
// `#pragma reduce()`
|
||||
.Case("exportReduceCount", eExportReduce)
|
||||
// Total count of all RenderScript specific `#pragmas` used in the
|
||||
// script
|
||||
.Case("pragmaCount", ePragma)
|
||||
.Case("objectSlotCount", eObjectSlot)
|
||||
.Default(-1);
|
||||
};
|
||||
|
||||
// parse all text lines of .rs.info
|
||||
for (auto line = info_lines.begin(); line != info_lines.end(); ++line) {
|
||||
|
@ -2740,12 +2801,11 @@ bool RSModuleDescriptor::ParseRSInfo() {
|
|||
const auto key = kv_pair.first;
|
||||
const auto val = kv_pair.second.trim();
|
||||
|
||||
const auto handler = rs_info_handlers.find(key);
|
||||
if (handler == rs_info_handlers.end())
|
||||
const auto handler = rs_info_handler(key);
|
||||
if (handler == -1)
|
||||
continue;
|
||||
// getAsInteger returns `true` on an error condition - we're only interested
|
||||
// in
|
||||
// numeric fields at the moment
|
||||
// in numeric fields at the moment
|
||||
uint64_t n_lines;
|
||||
if (val.getAsInteger(10, n_lines)) {
|
||||
if (log)
|
||||
|
@ -2757,7 +2817,7 @@ bool RSModuleDescriptor::ParseRSInfo() {
|
|||
return false;
|
||||
|
||||
bool success = false;
|
||||
switch (handler->getValue()) {
|
||||
switch (handler) {
|
||||
case eExportVar:
|
||||
success = ParseExportVarCount(line, n_lines);
|
||||
break;
|
||||
|
@ -3225,7 +3285,36 @@ RenderScriptRuntime::CreateKernelBreakpoint(const ConstString &name) {
|
|||
// Give RS breakpoints a specific name, so the user can manipulate them as a
|
||||
// group.
|
||||
Error err;
|
||||
if (!bp->AddName("RenderScriptKernel", err) && log)
|
||||
if (!bp->AddName("RenderScriptKernel", err))
|
||||
if (log)
|
||||
log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
|
||||
err.AsCString());
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
BreakpointSP
|
||||
RenderScriptRuntime::CreateReductionBreakpoint(const ConstString &name,
|
||||
int kernel_types) {
|
||||
Log *log(
|
||||
GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
|
||||
|
||||
if (!m_filtersp) {
|
||||
if (log)
|
||||
log->Printf("%s - error, no breakpoint search filter set.", __FUNCTION__);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BreakpointResolverSP resolver_sp(new RSReduceBreakpointResolver(
|
||||
nullptr, name, &m_rsmodules, kernel_types));
|
||||
BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(
|
||||
m_filtersp, resolver_sp, false, false, false);
|
||||
|
||||
// Give RS breakpoints a specific name, so the user can manipulate them as a
|
||||
// group.
|
||||
Error err;
|
||||
if (!bp->AddName("RenderScriptReduction", err))
|
||||
if (log)
|
||||
log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
|
||||
err.AsCString());
|
||||
|
||||
|
@ -3446,6 +3535,28 @@ bool RenderScriptRuntime::PlaceBreakpointOnKernel(TargetSP target,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool RenderScriptRuntime::PlaceBreakpointOnReduction(TargetSP target,
|
||||
Stream &messages,
|
||||
const char *reduce_name,
|
||||
const RSCoordinate *coord,
|
||||
int kernel_types) {
|
||||
if (!reduce_name)
|
||||
return false;
|
||||
|
||||
InitSearchFilter(target);
|
||||
BreakpointSP bp =
|
||||
CreateReductionBreakpoint(ConstString(reduce_name), kernel_types);
|
||||
if (!bp)
|
||||
return false;
|
||||
|
||||
if (coord)
|
||||
SetConditional(bp, messages, *coord);
|
||||
|
||||
bp->GetDescription(&messages, lldb::eDescriptionLevelInitial, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderScriptRuntime::DumpModules(Stream &strm) const {
|
||||
strm.Printf("RenderScript Modules:");
|
||||
strm.EOL();
|
||||
|
@ -3666,6 +3777,164 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
static OptionDefinition g_renderscript_reduction_bp_set_options[] = {
|
||||
{LLDB_OPT_SET_1, false, "function-role", 't',
|
||||
OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner,
|
||||
"Break on a comma separated set of reduction kernel types "
|
||||
"(accumulator,outcoverter,combiner,initializer"},
|
||||
{LLDB_OPT_SET_1, false, "coordinate", 'c', OptionParser::eRequiredArgument,
|
||||
nullptr, nullptr, 0, eArgTypeValue,
|
||||
"Set a breakpoint on a single invocation of the kernel with specified "
|
||||
"coordinate.\n"
|
||||
"Coordinate takes the form 'x[,y][,z] where x,y,z are positive "
|
||||
"integers representing kernel dimensions. "
|
||||
"Any unset dimensions will be defaulted to zero."}};
|
||||
|
||||
class CommandObjectRenderScriptRuntimeReductionBreakpointSet
|
||||
: public CommandObjectParsed {
|
||||
public:
|
||||
CommandObjectRenderScriptRuntimeReductionBreakpointSet(
|
||||
CommandInterpreter &interpreter)
|
||||
: CommandObjectParsed(
|
||||
interpreter, "renderscript reduction breakpoint set",
|
||||
"Set a breakpoint on named RenderScript general reductions",
|
||||
"renderscript reduction breakpoint set <kernel_name> [-t "
|
||||
"<reduction_kernel_type,...>]",
|
||||
eCommandRequiresProcess | eCommandProcessMustBeLaunched |
|
||||
eCommandProcessMustBePaused),
|
||||
m_options(){};
|
||||
|
||||
class CommandOptions : public Options {
|
||||
public:
|
||||
CommandOptions()
|
||||
: Options(),
|
||||
m_kernel_types(RSReduceBreakpointResolver::eKernelTypeAll) {}
|
||||
|
||||
~CommandOptions() override = default;
|
||||
|
||||
Error SetOptionValue(uint32_t option_idx, const char *option_val,
|
||||
ExecutionContext *exe_ctx) override {
|
||||
Error err;
|
||||
StreamString err_str;
|
||||
const int short_option = m_getopt_table[option_idx].val;
|
||||
switch (short_option) {
|
||||
case 't':
|
||||
if (!ParseReductionTypes(option_val, err_str))
|
||||
err.SetErrorStringWithFormat(
|
||||
"Unable to deduce reduction types for %s: %s", option_val,
|
||||
err_str.GetData());
|
||||
break;
|
||||
case 'c': {
|
||||
auto coord = RSCoordinate{};
|
||||
if (!ParseCoordinate(option_val, coord))
|
||||
err.SetErrorStringWithFormat("unable to parse coordinate for %s",
|
||||
option_val);
|
||||
else {
|
||||
m_have_coord = true;
|
||||
m_coord = coord;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
err.SetErrorStringWithFormat("Invalid option '-%c'", short_option);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void OptionParsingStarting(ExecutionContext *exe_ctx) override {
|
||||
m_have_coord = false;
|
||||
}
|
||||
|
||||
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
|
||||
return llvm::makeArrayRef(g_renderscript_reduction_bp_set_options);
|
||||
}
|
||||
|
||||
bool ParseReductionTypes(const char *option_val, StreamString &err_str) {
|
||||
m_kernel_types = RSReduceBreakpointResolver::eKernelTypeNone;
|
||||
const auto reduce_name_to_type = [](llvm::StringRef name) -> int {
|
||||
return llvm::StringSwitch<int>(name)
|
||||
.Case("accumulator", RSReduceBreakpointResolver::eKernelTypeAccum)
|
||||
.Case("initializer", RSReduceBreakpointResolver::eKernelTypeInit)
|
||||
.Case("outconverter", RSReduceBreakpointResolver::eKernelTypeOutC)
|
||||
.Case("combiner", RSReduceBreakpointResolver::eKernelTypeComb)
|
||||
.Case("all", RSReduceBreakpointResolver::eKernelTypeAll)
|
||||
// Currently not exposed by the runtime
|
||||
// .Case("halter", RSReduceBreakpointResolver::eKernelTypeHalter)
|
||||
.Default(0);
|
||||
};
|
||||
|
||||
// Matching a comma separated list of known words is fairly
|
||||
// straightforward with PCRE, but we're
|
||||
// using ERE, so we end up with a little ugliness...
|
||||
RegularExpression::Match match(/* max_matches */ 5);
|
||||
RegularExpression match_type_list(
|
||||
llvm::StringRef("^([[:alpha:]]+)(,[[:alpha:]]+){0,4}$"));
|
||||
|
||||
assert(match_type_list.IsValid());
|
||||
|
||||
if (!match_type_list.Execute(llvm::StringRef(option_val), &match)) {
|
||||
err_str.PutCString(
|
||||
"a comma-separated list of kernel types is required");
|
||||
return false;
|
||||
}
|
||||
|
||||
// splitting on commas is much easier with llvm::StringRef than regex
|
||||
llvm::SmallVector<llvm::StringRef, 5> type_names;
|
||||
llvm::StringRef(option_val).split(type_names, ',');
|
||||
|
||||
for (const auto &name : type_names) {
|
||||
const int type = reduce_name_to_type(name);
|
||||
if (!type) {
|
||||
err_str.Printf("unknown kernel type name %s", name.str().c_str());
|
||||
return false;
|
||||
}
|
||||
m_kernel_types |= type;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int m_kernel_types;
|
||||
llvm::StringRef m_reduce_name;
|
||||
RSCoordinate m_coord;
|
||||
bool m_have_coord;
|
||||
};
|
||||
|
||||
Options *GetOptions() override { return &m_options; }
|
||||
|
||||
bool DoExecute(Args &command, CommandReturnObject &result) override {
|
||||
const size_t argc = command.GetArgumentCount();
|
||||
if (argc < 1) {
|
||||
result.AppendErrorWithFormat("'%s' takes 1 argument of reduction name, "
|
||||
"and an optional kernel type list",
|
||||
m_cmd_name.c_str());
|
||||
result.SetStatus(eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
|
||||
RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
|
||||
m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
|
||||
eLanguageTypeExtRenderScript));
|
||||
|
||||
auto &outstream = result.GetOutputStream();
|
||||
auto name = command.GetArgumentAtIndex(0);
|
||||
auto &target = m_exe_ctx.GetTargetSP();
|
||||
auto coord = m_options.m_have_coord ? &m_options.m_coord : nullptr;
|
||||
if (!runtime->PlaceBreakpointOnReduction(target, outstream, name, coord,
|
||||
m_options.m_kernel_types)) {
|
||||
result.SetStatus(eReturnStatusFailed);
|
||||
result.AppendError("Error: unable to place breakpoint on reduction");
|
||||
return false;
|
||||
}
|
||||
result.AppendMessage("Breakpoint(s) created");
|
||||
result.SetStatus(eReturnStatusSuccessFinishResult);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
CommandOptions m_options;
|
||||
};
|
||||
|
||||
static OptionDefinition g_renderscript_kernel_bp_set_options[] = {
|
||||
{LLDB_OPT_SET_1, false, "coordinate", 'c', OptionParser::eRequiredArgument,
|
||||
nullptr, nullptr, 0, eArgTypeValue,
|
||||
|
@ -3699,7 +3968,7 @@ public:
|
|||
~CommandOptions() override = default;
|
||||
|
||||
Error SetOptionValue(uint32_t option_idx, const char *option_arg,
|
||||
ExecutionContext *execution_context) override {
|
||||
ExecutionContext *exe_ctx) override {
|
||||
Error err;
|
||||
const int short_option = m_getopt_table[option_idx].val;
|
||||
|
||||
|
@ -3723,7 +3992,7 @@ public:
|
|||
return err;
|
||||
}
|
||||
|
||||
void OptionParsingStarting(ExecutionContext *execution_context) override {
|
||||
void OptionParsingStarting(ExecutionContext *exe_ctx) override {
|
||||
m_have_coord = false;
|
||||
}
|
||||
|
||||
|
@ -3822,6 +4091,24 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class CommandObjectRenderScriptRuntimeReductionBreakpoint
|
||||
: public CommandObjectMultiword {
|
||||
public:
|
||||
CommandObjectRenderScriptRuntimeReductionBreakpoint(
|
||||
CommandInterpreter &interpreter)
|
||||
: CommandObjectMultiword(interpreter, "renderscript reduction breakpoint",
|
||||
"Commands that manipulate breakpoints on "
|
||||
"renderscript general reductions.",
|
||||
nullptr) {
|
||||
LoadSubCommand(
|
||||
"set", CommandObjectSP(
|
||||
new CommandObjectRenderScriptRuntimeReductionBreakpointSet(
|
||||
interpreter)));
|
||||
}
|
||||
|
||||
~CommandObjectRenderScriptRuntimeReductionBreakpoint() override = default;
|
||||
};
|
||||
|
||||
class CommandObjectRenderScriptRuntimeKernelCoordinate
|
||||
: public CommandObjectParsed {
|
||||
public:
|
||||
|
@ -3962,7 +4249,7 @@ public:
|
|||
~CommandOptions() override = default;
|
||||
|
||||
Error SetOptionValue(uint32_t option_idx, const char *option_arg,
|
||||
ExecutionContext *execution_context) override {
|
||||
ExecutionContext *exe_ctx) override {
|
||||
Error err;
|
||||
const int short_option = m_getopt_table[option_idx].val;
|
||||
|
||||
|
@ -3981,7 +4268,7 @@ public:
|
|||
return err;
|
||||
}
|
||||
|
||||
void OptionParsingStarting(ExecutionContext *execution_context) override {
|
||||
void OptionParsingStarting(ExecutionContext *exe_ctx) override {
|
||||
m_outfile.Clear();
|
||||
}
|
||||
|
||||
|
@ -4083,7 +4370,7 @@ public:
|
|||
~CommandOptions() override = default;
|
||||
|
||||
Error SetOptionValue(uint32_t option_idx, const char *option_arg,
|
||||
ExecutionContext *execution_context) override {
|
||||
ExecutionContext *exe_ctx) override {
|
||||
Error err;
|
||||
const int short_option = m_getopt_table[option_idx].val;
|
||||
|
||||
|
@ -4102,9 +4389,7 @@ public:
|
|||
return err;
|
||||
}
|
||||
|
||||
void OptionParsingStarting(ExecutionContext *execution_context) override {
|
||||
m_id = 0;
|
||||
}
|
||||
void OptionParsingStarting(ExecutionContext *exe_ctx) override { m_id = 0; }
|
||||
|
||||
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
|
||||
return llvm::makeArrayRef(g_renderscript_runtime_alloc_list_options);
|
||||
|
@ -4313,6 +4598,21 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class CommandObjectRenderScriptRuntimeReduction
|
||||
: public CommandObjectMultiword {
|
||||
public:
|
||||
CommandObjectRenderScriptRuntimeReduction(CommandInterpreter &interpreter)
|
||||
: CommandObjectMultiword(interpreter, "renderscript reduction",
|
||||
"Commands that handle general reduction kernels",
|
||||
nullptr) {
|
||||
LoadSubCommand(
|
||||
"breakpoint",
|
||||
CommandObjectSP(new CommandObjectRenderScriptRuntimeReductionBreakpoint(
|
||||
interpreter)));
|
||||
}
|
||||
~CommandObjectRenderScriptRuntimeReduction() override = default;
|
||||
};
|
||||
|
||||
class CommandObjectRenderScriptRuntime : public CommandObjectMultiword {
|
||||
public:
|
||||
CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter)
|
||||
|
@ -4336,6 +4636,10 @@ public:
|
|||
"allocation",
|
||||
CommandObjectSP(
|
||||
new CommandObjectRenderScriptRuntimeAllocation(interpreter)));
|
||||
LoadSubCommand(
|
||||
"reduction",
|
||||
CommandObjectSP(
|
||||
new CommandObjectRenderScriptRuntimeReduction(interpreter)));
|
||||
}
|
||||
|
||||
~CommandObjectRenderScriptRuntime() override = default;
|
||||
|
|
|
@ -84,6 +84,58 @@ protected:
|
|||
ConstString m_kernel_name;
|
||||
};
|
||||
|
||||
class RSReduceBreakpointResolver : public BreakpointResolver {
|
||||
public:
|
||||
enum ReduceKernelTypeFlags {
|
||||
eKernelTypeAll = ~(0),
|
||||
eKernelTypeNone = 0,
|
||||
eKernelTypeAccum = (1 << 0),
|
||||
eKernelTypeInit = (1 << 1),
|
||||
eKernelTypeComb = (1 << 2),
|
||||
eKernelTypeOutC = (1 << 3),
|
||||
eKernelTypeHalter = (1 << 4)
|
||||
};
|
||||
|
||||
RSReduceBreakpointResolver(
|
||||
Breakpoint *breakpoint, ConstString reduce_name,
|
||||
std::vector<lldb_renderscript::RSModuleDescriptorSP> *rs_modules,
|
||||
int kernel_types = eKernelTypeAll)
|
||||
: BreakpointResolver(breakpoint, BreakpointResolver::NameResolver),
|
||||
m_reduce_name(reduce_name), m_rsmodules(rs_modules),
|
||||
m_kernel_types(kernel_types) {
|
||||
// The reduce breakpoint resolver handles adding breakpoints for named
|
||||
// reductions.
|
||||
// Breakpoints will be resolved for all constituent kernels in the named
|
||||
// reduction
|
||||
}
|
||||
|
||||
void GetDescription(Stream *strm) override {
|
||||
if (strm)
|
||||
strm->Printf("RenderScript reduce breakpoint for '%s'",
|
||||
m_reduce_name.AsCString());
|
||||
}
|
||||
|
||||
void Dump(Stream *s) const override {}
|
||||
|
||||
Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
|
||||
SymbolContext &context, Address *addr,
|
||||
bool containing) override;
|
||||
|
||||
Searcher::Depth GetDepth() override { return Searcher::eDepthModule; }
|
||||
|
||||
lldb::BreakpointResolverSP
|
||||
CopyForBreakpoint(Breakpoint &breakpoint) override {
|
||||
lldb::BreakpointResolverSP ret_sp(new RSReduceBreakpointResolver(
|
||||
&breakpoint, m_reduce_name, m_rsmodules, m_kernel_types));
|
||||
return ret_sp;
|
||||
}
|
||||
|
||||
private:
|
||||
ConstString m_reduce_name; // The name of the reduction
|
||||
std::vector<lldb_renderscript::RSModuleDescriptorSP> *m_rsmodules;
|
||||
int m_kernel_types;
|
||||
};
|
||||
|
||||
struct RSKernelDescriptor {
|
||||
public:
|
||||
RSKernelDescriptor(const RSModuleDescriptor *module, llvm::StringRef name,
|
||||
|
@ -247,6 +299,11 @@ public:
|
|||
lldb::TargetSP target, Stream &messages, const char *name,
|
||||
const lldb_renderscript::RSCoordinate *coords = nullptr);
|
||||
|
||||
bool PlaceBreakpointOnReduction(
|
||||
lldb::TargetSP target, Stream &messages, const char *reduce_name,
|
||||
const lldb_renderscript::RSCoordinate *coords = nullptr,
|
||||
int kernel_types = ~(0));
|
||||
|
||||
void SetBreakAllKernels(bool do_break, lldb::TargetSP target);
|
||||
|
||||
void Status(Stream &strm) const;
|
||||
|
@ -294,6 +351,9 @@ protected:
|
|||
|
||||
lldb::BreakpointSP CreateKernelBreakpoint(const ConstString &name);
|
||||
|
||||
lldb::BreakpointSP CreateReductionBreakpoint(const ConstString &name,
|
||||
int kernel_types);
|
||||
|
||||
void BreakOnModuleKernels(
|
||||
const lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
|
||||
|
||||
|
|
Loading…
Reference in New Issue