Commit 3a50a43d by Ben Clayton

SpirvShaderDebugger: Implement scope nesting

Previously nested scopes would hide their parent variables. This is no longer the case. Bug: b/148401179 Change-Id: Icf2771a525524b8796ab12e295e141388bb5b399 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/42368 Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com>
parent f6e439f9
...@@ -377,6 +377,12 @@ T *find(Scope *scope) ...@@ -377,6 +377,12 @@ T *find(Scope *scope)
return scope->parent ? find<T>(scope->parent) : nullptr; return scope->parent ? find<T>(scope->parent) : nullptr;
} }
bool hasDebuggerScope(debug::Scope *spirvScope)
{
return debug::cast<debug::Function>(spirvScope) != nullptr ||
debug::cast<debug::LexicalBlock>(spirvScope) != nullptr;
}
} // namespace debug } // namespace debug
} // anonymous namespace } // anonymous namespace
...@@ -421,7 +427,8 @@ struct SpirvShader::Impl::Debugger ...@@ -421,7 +427,8 @@ struct SpirvShader::Impl::Debugger
void process(const SpirvShader *shader, const InsnIterator &insn, EmitState *state, Pass pass); void process(const SpirvShader *shader, const InsnIterator &insn, EmitState *state, Pass pass);
void setPosition(EmitState *state, const std::string &path, uint32_t line, uint32_t column); void setLocation(EmitState *state, const std::shared_ptr<vk::dbg::File> &, int line, int column);
void setLocation(EmitState *state, const std::string &path, int line, int column);
// exposeVariable exposes the variable with the given ID to the debugger // exposeVariable exposes the variable with the given ID to the debugger
// using the specified key. // using the specified key.
...@@ -469,8 +476,6 @@ private: ...@@ -469,8 +476,6 @@ private:
// use get() and add() to access this // use get() and add() to access this
std::unordered_map<debug::Object::ID, std::unique_ptr<debug::Object>> objects; std::unordered_map<debug::Object::ID, std::unique_ptr<debug::Object>> objects;
std::unordered_map<std::string, vk::dbg::File::ID> fileIDs;
// defineOrEmit() when called in Pass::Define, creates and stores a // defineOrEmit() when called in Pass::Define, creates and stores a
// zero-initialized object into the Debugger::objects map using the // zero-initialized object into the Debugger::objects map using the
// object identifier held by second instruction operand. // object identifier held by second instruction operand.
...@@ -483,6 +488,8 @@ private: ...@@ -483,6 +488,8 @@ private:
// The object type is automatically inferred from the function signature. // The object type is automatically inferred from the function signature.
template<typename F, typename T = typename std::remove_pointer<ArgTyT<F>>::type> template<typename F, typename T = typename std::remove_pointer<ArgTyT<F>>::type>
void defineOrEmit(InsnIterator insn, Pass pass, F &&emit); void defineOrEmit(InsnIterator insn, Pass pass, F &&emit);
std::unordered_map<std::string, std::shared_ptr<vk::dbg::File>> files;
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
...@@ -502,7 +509,7 @@ public: ...@@ -502,7 +509,7 @@ public:
void enter(vk::dbg::Context::Lock &lock, const char *name); void enter(vk::dbg::Context::Lock &lock, const char *name);
void exit(); void exit();
void updateActiveLaneMask(int lane, bool enabled); void updateActiveLaneMask(int lane, bool enabled);
void update(vk::dbg::File::ID file, int line, int column); void updateLocation(vk::dbg::File::ID file, int line, int column);
void createScope(const debug::Scope *); void createScope(const debug::Scope *);
void setScope(debug::SourceScope *newScope); void setScope(debug::SourceScope *newScope);
...@@ -594,7 +601,7 @@ void SpirvShader::Impl::Debugger::State::updateActiveLaneMask(int lane, bool ena ...@@ -594,7 +601,7 @@ void SpirvShader::Impl::Debugger::State::updateActiveLaneMask(int lane, bool ena
rootScopes.localsByLane[lane]->put("enabled", vk::dbg::make_constant(enabled)); rootScopes.localsByLane[lane]->put("enabled", vk::dbg::make_constant(enabled));
} }
void SpirvShader::Impl::Debugger::State::update(vk::dbg::File::ID fileID, int line, int column) void SpirvShader::Impl::Debugger::State::updateLocation(vk::dbg::File::ID fileID, int line, int column)
{ {
auto file = debugger->ctx->lock().get(fileID); auto file = debugger->ctx->lock().get(fileID);
thread->update([&](vk::dbg::Frame &frame) { thread->update([&](vk::dbg::Frame &frame) {
...@@ -645,19 +652,35 @@ void SpirvShader::Impl::Debugger::State::createScope(const debug::Scope *spirvSc ...@@ -645,19 +652,35 @@ void SpirvShader::Impl::Debugger::State::createScope(const debug::Scope *spirvSc
ASSERT(spirvScope != nullptr); ASSERT(spirvScope != nullptr);
// TODO: Deal with scope nesting.
auto lock = debugger->ctx->lock(); auto lock = debugger->ctx->lock();
Scopes s = {}; Scopes s = {};
s.locals = lock.createScope(spirvScope->source->dbgFile); s.locals = lock.createScope(spirvScope->source->dbgFile);
s.hovers = lock.createScope(spirvScope->source->dbgFile); s.hovers = lock.createScope(spirvScope->source->dbgFile);
for(int i = 0; i < sw::SIMD::Width; i++) for(int i = 0; i < sw::SIMD::Width; i++)
{ {
auto locals = lock.createVariableContainer(); auto locals = lock.createVariableContainer();
locals->extend(builtinsByLane[i]);
s.localsByLane[i] = locals; s.localsByLane[i] = locals;
s.locals->variables->put(laneNames[i], locals); s.locals->variables->put(laneNames[i], locals);
} }
if(hasDebuggerScope(spirvScope->parent))
{
auto parent = getScopes(spirvScope->parent);
for(int i = 0; i < sw::SIMD::Width; i++)
{
s.localsByLane[i]->extend(parent.localsByLane[i]);
}
s.hovers->variables->extend(parent.hovers->variables);
}
else
{
for(int i = 0; i < sw::SIMD::Width; i++)
{
s.localsByLane[i]->extend(builtinsByLane[i]);
}
}
scopes.emplace(spirvScope, std::move(s)); scopes.emplace(spirvScope, std::move(s));
} }
...@@ -667,7 +690,7 @@ void SpirvShader::Impl::Debugger::State::setScope(debug::SourceScope *newSrcScop ...@@ -667,7 +690,7 @@ void SpirvShader::Impl::Debugger::State::setScope(debug::SourceScope *newSrcScop
if(oldSrcScope == newSrcScope) { return; } if(oldSrcScope == newSrcScope) { return; }
srcScope = newSrcScope; srcScope = newSrcScope;
if(debug::cast<debug::LexicalBlock>(srcScope->scope)) if(hasDebuggerScope(srcScope->scope))
{ {
auto lock = debugger->ctx->lock(); auto lock = debugger->ctx->lock();
auto thread = lock.currentThread(); auto thread = lock.currentThread();
...@@ -1027,7 +1050,7 @@ void SpirvShader::Impl::Debugger::process(const SpirvShader *shader, const InsnI ...@@ -1027,7 +1050,7 @@ void SpirvShader::Impl::Debugger::process(const SpirvShader *shader, const InsnI
auto file = dbg->ctx->lock().createVirtualFile(source->file.c_str(), source->source.c_str()); auto file = dbg->ctx->lock().createVirtualFile(source->file.c_str(), source->source.c_str());
source->dbgFile = file; source->dbgFile = file;
fileIDs.emplace(source->file.c_str(), file->id); files.emplace(source->file.c_str(), file);
}); });
break; break;
...@@ -1057,12 +1080,17 @@ void SpirvShader::Impl::Debugger::process(const SpirvShader *shader, const InsnI ...@@ -1057,12 +1080,17 @@ void SpirvShader::Impl::Debugger::process(const SpirvShader *shader, const InsnI
} }
} }
void SpirvShader::Impl::Debugger::setPosition(EmitState *state, const std::string &path, uint32_t line, uint32_t column) void SpirvShader::Impl::Debugger::setLocation(EmitState *state, const std::shared_ptr<vk::dbg::File> &file, int line, int column)
{ {
auto it = fileIDs.find(path); rr::Call(&State::updateLocation, state->routine->dbgState, file->id, line, column);
if(it != fileIDs.end()) }
void SpirvShader::Impl::Debugger::setLocation(EmitState *state, const std::string &path, int line, int column)
{
auto it = files.find(path);
if(it != files.end())
{ {
rr::Call(&State::update, state->routine->dbgState, it->second, line, column); setLocation(state, it->second, line, column);
} }
} }
...@@ -1479,18 +1507,19 @@ void SpirvShader::dbgBeginEmitInstruction(InsnIterator insn, EmitState *state) c ...@@ -1479,18 +1507,19 @@ void SpirvShader::dbgBeginEmitInstruction(InsnIterator insn, EmitState *state) c
} }
# endif // PRINT_EACH_EXECUTED_INSTRUCTION # endif // PRINT_EACH_EXECUTED_INSTRUCTION
if(extensionsImported.count(Extension::OpenCLDebugInfo100) == 0) // Only single line step over statement instructions.
if(auto dbg = impl.debugger)
{ {
// We're emitting debugger logic for SPIR-V. if(extensionsImported.count(Extension::OpenCLDebugInfo100) == 0)
// Only single line step over statement instructions.
if(IsStatement(insn.opcode()))
{ {
auto dbg = impl.debugger; // We're emitting debugger logic for SPIR-V.
if(!dbg) { return; } if(IsStatement(insn.opcode()))
{
auto line = dbg->spirvLineMappings.at(insn.wordPointer(0)); auto line = dbg->spirvLineMappings.at(insn.wordPointer(0));
auto column = 0; auto column = 0;
rr::Call(&Impl::Debugger::State::update, state->routine->dbgState, dbg->spirvFile->id, line, column); dbg->setLocation(state, dbg->spirvFile, line, column);
}
} }
} }
} }
...@@ -1542,7 +1571,7 @@ SpirvShader::EmitResult SpirvShader::EmitLine(InsnIterator insn, EmitState *stat ...@@ -1542,7 +1571,7 @@ SpirvShader::EmitResult SpirvShader::EmitLine(InsnIterator insn, EmitState *stat
auto path = getString(insn.word(1)); auto path = getString(insn.word(1));
auto line = insn.word(2); auto line = insn.word(2);
auto column = insn.word(3); auto column = insn.word(3);
dbg->setPosition(state, path, line, column); dbg->setLocation(state, path, line, column);
} }
return EmitResult::Continue; return EmitResult::Continue;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment