@@ -6563,6 +6563,39 @@ void ThreadState::StepOverNopInstructions()
65636563 } while (true );
65646564}
65656565
6566+ void ThreadState::RetireLiveIDs ()
6567+ {
6568+ m_State->flags = ShaderEvents::NoEvent;
6569+ m_State->changes .clear ();
6570+
6571+ // Remove variables which have gone out of scope
6572+ ExecPointReference current (m_Block, m_FunctionInstructionIdx);
6573+ for (uint32_t id = 0 ; id < m_Live.size (); ++id)
6574+ {
6575+ if (!m_Live[id])
6576+ continue ;
6577+ // The fake output variable is always in scope
6578+ if (id == m_Output.id )
6579+ continue ;
6580+ // Globals are always in scope
6581+ if (m_IsGlobal[id])
6582+ continue ;
6583+
6584+ RDCASSERT (id < m_FunctionInfo->maxExecPointPerId .size ());
6585+ const ExecPointReference maxPoint = m_FunctionInfo->maxExecPointPerId [id];
6586+ RDCASSERT (maxPoint.IsValid ());
6587+ // Use control flow to determine if the current execution point is after the maximum point
6588+ if (current.IsAfter (maxPoint, m_FunctionInfo->controlFlow ))
6589+ {
6590+ m_Live[id] = false ;
6591+
6592+ ShaderVariableChange change;
6593+ change.before = m_Variables[id];
6594+ m_State->changes .push_back (change);
6595+ }
6596+ }
6597+ }
6598+
65666599void ThreadState::StepNext (ShaderDebugState *state, DebugAPIWrapper *apiWrapper,
65676600 const rdcarray<ThreadState> &workgroup, const rdcarray<bool > &activeMask)
65686601{
@@ -6578,33 +6611,7 @@ void ThreadState::StepNext(ShaderDebugState *state, DebugAPIWrapper *apiWrapper,
65786611 {
65796612 m_State->flags = ShaderEvents::NoEvent;
65806613 m_State->changes .clear ();
6581-
6582- // Remove variables which have gone out of scope
6583- ExecPointReference current (m_Block, m_FunctionInstructionIdx);
6584- for (uint32_t id = 0 ; id < m_Live.size (); ++id)
6585- {
6586- if (!m_Live[id])
6587- continue ;
6588- // The fake output variable is always in scope
6589- if (id == m_Output.id )
6590- continue ;
6591- // Globals are always in scope
6592- if (m_IsGlobal[id])
6593- continue ;
6594-
6595- auto itRange = m_FunctionInfo->maxExecPointPerId .find (id);
6596- RDCASSERT (itRange != m_FunctionInfo->maxExecPointPerId .end ());
6597- const ExecPointReference maxPoint = itRange->second ;
6598- // Use control flow to determine if the current execution point is after the maximum point
6599- if (current.IsAfter (maxPoint, m_FunctionInfo->controlFlow ))
6600- {
6601- m_Live[id] = false ;
6602-
6603- ShaderVariableChange change;
6604- change.before = m_Variables[id];
6605- m_State->changes .push_back (change);
6606- }
6607- }
6614+ RetireLiveIDs ();
66086615 }
66096616 ExecuteInstruction (apiWrapper, workgroup, activeMask);
66106617
@@ -8777,13 +8784,13 @@ ShaderDebugTrace *Debugger::BeginDebug(uint32_t eventId, const DXBC::DXBCContain
87778784 m_Stage = shaderStage;
87788785
87798786 uint32_t outputSSAId = m_Program->m_NextSSAId ;
8780- uint32_t nextSSAId = outputSSAId + 1 ;
8787+ uint32_t maxSSAId = outputSSAId + 1 ;
87818788
87828789 ShaderDebugTrace *ret = new ShaderDebugTrace;
87838790 ret->stage = shaderStage;
87848791
87858792 for (uint32_t i = 0 ; i < threadsInWorkgroup; i++)
8786- m_Workgroup.push_back (ThreadState (*this , m_GlobalState, nextSSAId ));
8793+ m_Workgroup.push_back (ThreadState (*this , m_GlobalState, maxSSAId ));
87878794
87888795 ThreadState &state = GetActiveLane ();
87898796
@@ -8900,7 +8907,7 @@ ShaderDebugTrace *Debugger::BeginDebug(uint32_t eventId, const DXBC::DXBCContain
89008907 sourceVar.variables .push_back (ref);
89018908 }
89028909
8903- m_LiveGlobals.resize (nextSSAId );
8910+ m_LiveGlobals.resize (maxSSAId );
89048911 MemoryTracking &globalMemory = m_GlobalState.memory ;
89058912 for (const DXIL::GlobalVar *gv : m_Program->m_GlobalVars )
89068913 {
@@ -9066,6 +9073,8 @@ ShaderDebugTrace *Debugger::BeginDebug(uint32_t eventId, const DXBC::DXBCContain
90669073
90679074 FunctionInfo::ReferencedIds &ssaRefs = info.referencedIds ;
90689075 FunctionInfo::ExecutionPointPerId &ssaMaxExecPoints = info.maxExecPointPerId ;
9076+ ssaMaxExecPoints.resize (maxSSAId);
9077+ std::set<Id> ssaMaxRefs;
90699078
90709079 uint32_t curBlock = 0 ;
90719080 info.instructionToBlock .resize (countInstructions);
@@ -9087,12 +9096,17 @@ ShaderDebugTrace *Debugger::BeginDebug(uint32_t eventId, const DXBC::DXBCContain
90879096 RDCASSERTEQUAL (ssaRefs.count (resultId), 0 );
90889097 ssaRefs.insert (resultId);
90899098
9090- auto it = ssaMaxExecPoints.find (resultId);
9091- if (it == ssaMaxExecPoints.end ())
9099+ auto it = ssaMaxRefs.find (resultId);
9100+ if (it == ssaMaxRefs.end ())
9101+ {
90929102 ssaMaxExecPoints[resultId] = current;
9103+ ssaMaxRefs.insert (resultId);
9104+ }
90939105 else
9094- // If the result SSA has tracking then this access should be at a later execution point
9095- RDCASSERT (it->second .IsAfter (current, controlFlow));
9106+ {
9107+ // If the result SSA has tracking then that access should be after setting the result
9108+ RDCASSERT (current.IsAfter (ssaMaxExecPoints[resultId], controlFlow));
9109+ }
90969110 }
90979111 // Track maximum execution point when an SSA is referenced as an argument
90989112 // Arguments to phi instructions are handled separately
@@ -9112,30 +9126,31 @@ ShaderDebugTrace *Debugger::BeginDebug(uint32_t eventId, const DXBC::DXBCContain
91129126 if (ssaRefs.count (argId) == 0 )
91139127 ssaRefs.insert (argId);
91149128 }
9115- auto it = ssaMaxExecPoints .find (argId);
9116- if (it == ssaMaxExecPoints .end ())
9129+ auto it = ssaMaxRefs .find (argId);
9130+ if (it == ssaMaxRefs .end ())
91179131 {
91189132 ssaMaxExecPoints[argId] = maxPoint;
9133+ ssaMaxRefs.insert (argId);
91199134 }
91209135 else
91219136 {
91229137 // Update the maximum execution point if access is later than the existing access
9123- if (maxPoint.IsAfter (it-> second , controlFlow))
9124- it-> second = maxPoint;
9138+ if (maxPoint.IsAfter (ssaMaxExecPoints[argId] , controlFlow))
9139+ ssaMaxExecPoints[argId] = maxPoint;
91259140 }
91269141 }
91279142 if (inst.op == Operation::Branch || inst.op == Operation::Unreachable ||
91289143 inst.op == Operation::Switch || inst.op == Operation::Ret)
91299144 ++curBlock;
91309145 }
91319146 // If these do not match in size that means there is a result SSA that is never read
9132- RDCASSERTEQUAL (ssaRefs.size (), ssaMaxExecPoints .size ());
9147+ RDCASSERTEQUAL (ssaRefs.size (), ssaMaxRefs .size ());
91339148
91349149 // Update any SSA max points which are inside a loop to the next uniform block
91359150 // This covers the case of SSA IDs that are assigned to but never accessed
9136- for (auto &it : ssaMaxExecPoints )
9151+ for (Id id : ssaMaxRefs )
91379152 {
9138- ExecPointReference &maxPoint = it. second ;
9153+ ExecPointReference &maxPoint = ssaMaxExecPoints[id] ;
91399154 uint32_t block = maxPoint.block ;
91409155 // If the current block is in a loop, set the execution point to the next uniform block
91419156 if (loopBlocks.contains (block))
@@ -9312,10 +9327,11 @@ ShaderDebugTrace *Debugger::BeginDebug(uint32_t eventId, const DXBC::DXBCContain
93129327 {
93139328 for (LocalMapping &localMapping : scope->localMappings )
93149329 {
9315- auto it = info.maxExecPointPerId .find (localMapping.debugVarSSAId );
9316- if (it != info.maxExecPointPerId .end ())
9330+ if (localMapping.debugVarSSAId < info.maxExecPointPerId .size ())
93179331 {
9318- const ExecPointReference ¤t = it->second ;
9332+ const ExecPointReference ¤t = info.maxExecPointPerId [localMapping.debugVarSSAId ];
9333+ if (!current.IsValid ())
9334+ continue ;
93199335 uint32_t scopeEndInst = scope->maxInstruction + 1 ;
93209336 scopeEndInst = RDCMIN (scopeEndInst, (uint32_t )info.instructionToBlock .size () - 1 );
93219337 const uint32_t scopeEndBlock = info.instructionToBlock [scopeEndInst];
@@ -9327,7 +9343,7 @@ ShaderDebugTrace *Debugger::BeginDebug(uint32_t eventId, const DXBC::DXBCContain
93279343 scopeEnd.instruction = info.function ->blocks [nextUniformBlock]->startInstructionIdx + 1 ;
93289344 }
93299345 if (scopeEnd.IsAfter (current, controlFlow))
9330- it-> second = scopeEnd;
9346+ info. maxExecPointPerId [localMapping. debugVarSSAId ] = scopeEnd;
93319347 }
93329348 }
93339349 }
0 commit comments