@@ -273,29 +273,30 @@ void AggressiveDCEPass::AddBreaksAndContinuesToWorklist(
273273 });
274274}
275275
276- bool AggressiveDCEPass::AggressiveDCE (Function* func) {
277- if (func->IsDeclaration ()) return false ;
276+ Pass::Status AggressiveDCEPass::AggressiveDCE (Function* func) {
277+ if (func->IsDeclaration ()) return Pass::Status::SuccessWithoutChange ;
278278 std::list<BasicBlock*> structured_order;
279279 cfg ()->ComputeStructuredOrder (func, &*func->begin (), &structured_order);
280280 live_local_vars_.clear ();
281281 InitializeWorkList (func, structured_order);
282282 ProcessWorkList (func);
283- ProcessDebugInformation (structured_order);
283+ if (ProcessDebugInformation (structured_order) == Pass::Status::Failure)
284+ return Pass::Status::Failure;
284285 ProcessWorkList (func);
285286 return KillDeadInstructions (func, structured_order);
286287}
287288
288- void AggressiveDCEPass::ProcessDebugInformation (
289+ Pass::Status AggressiveDCEPass::ProcessDebugInformation (
289290 std::list<BasicBlock*>& structured_order) {
290291 for (auto bi = structured_order.begin (); bi != structured_order.end (); bi++) {
291- (*bi)->ForEachInst ([this ](Instruction* inst) {
292+ bool succeeded = (*bi)->WhileEachInst ([this ](Instruction* inst) {
292293 // DebugDeclare is not dead. It must be converted to DebugValue in a
293294 // later pass
294295 if (inst->IsNonSemanticInstruction () &&
295296 inst->GetShader100DebugOpcode () ==
296297 NonSemanticShaderDebugInfo100DebugDeclare) {
297298 AddToWorklist (inst);
298- return ;
299+ return true ;
299300 }
300301
301302 // If the Value of a DebugValue is killed, set Value operand to Undef
@@ -307,6 +308,9 @@ void AggressiveDCEPass::ProcessDebugInformation(
307308 if (!live_insts_.Set (def->unique_id ())) {
308309 AddToWorklist (inst);
309310 uint32_t undef_id = Type2Undef (def->type_id ());
311+ if (undef_id == 0 ) {
312+ return false ;
313+ }
310314 inst->SetInOperand (kDebugValueValue , {undef_id});
311315 context ()->get_def_use_mgr ()->UpdateDefUse (inst);
312316 id = inst->GetSingleWordInOperand (kDebugValueLocalVariable );
@@ -318,14 +322,18 @@ void AggressiveDCEPass::ProcessDebugInformation(
318322 auto expression = get_def_use_mgr ()->GetDef (id);
319323 AddToWorklist (expression);
320324 context ()->get_def_use_mgr ()->UpdateDefUse (expression);
321- return ;
325+ return true ;
322326 }
323327 }
328+ return true ;
324329 });
330+
331+ if (!succeeded) return Pass::Status::Failure;
325332 }
333+ return Pass::Status::SuccessWithoutChange;
326334}
327335
328- bool AggressiveDCEPass::KillDeadInstructions (
336+ Pass::Status AggressiveDCEPass::KillDeadInstructions (
329337 const Function* func, std::list<BasicBlock*>& structured_order) {
330338 bool modified = false ;
331339 for (auto bi = structured_order.begin (); bi != structured_order.end ();) {
@@ -360,6 +368,9 @@ bool AggressiveDCEPass::KillDeadInstructions(
360368 // Find an undef for the return value and make sure it gets kept by
361369 // the pass.
362370 auto undef_id = Type2Undef (func->type_id ());
371+ if (undef_id == 0 ) {
372+ return Pass::Status::Failure;
373+ }
363374 auto undef = get_def_use_mgr ()->GetDef (undef_id);
364375 live_insts_.Set (undef->unique_id ());
365376 merge_terminator->SetOpcode (spv::Op::OpReturnValue);
@@ -378,7 +389,8 @@ bool AggressiveDCEPass::KillDeadInstructions(
378389 ++bi;
379390 }
380391 }
381- return modified;
392+ return modified ? Pass::Status::SuccessWithChange
393+ : Pass::Status::SuccessWithoutChange;
382394}
383395
384396void AggressiveDCEPass::ProcessWorkList (Function* func) {
@@ -638,7 +650,7 @@ void AggressiveDCEPass::InitializeWorkList(
638650 }
639651}
640652
641- void AggressiveDCEPass::InitializeModuleScopeLiveInstructions () {
653+ Pass::Status AggressiveDCEPass::InitializeModuleScopeLiveInstructions () {
642654 // Keep all execution modes.
643655 for (auto & exec : get_module ()->execution_modes ()) {
644656 AddToWorklist (&exec);
@@ -713,6 +725,9 @@ void AggressiveDCEPass::InitializeModuleScopeLiveInstructions() {
713725 }
714726 if (debug_global_seen) {
715727 auto dbg_none = context ()->get_debug_info_mgr ()->GetDebugInfoNone ();
728+ if (dbg_none == nullptr ) {
729+ return Pass::Status::Failure;
730+ }
716731 AddToWorklist (dbg_none);
717732 }
718733
@@ -726,6 +741,7 @@ void AggressiveDCEPass::InitializeModuleScopeLiveInstructions() {
726741 AddToWorklist (&dbg);
727742 }
728743 }
744+ return Pass::Status::SuccessWithoutChange;
729745}
730746
731747Pass::Status AggressiveDCEPass::ProcessImpl () {
@@ -753,15 +769,23 @@ Pass::Status AggressiveDCEPass::ProcessImpl() {
753769 // Eliminate Dead functions.
754770 bool modified = EliminateDeadFunctions ();
755771
756- InitializeModuleScopeLiveInstructions ();
772+ if (InitializeModuleScopeLiveInstructions () == Pass::Status::Failure) {
773+ return Pass::Status::Failure;
774+ }
757775
758776 // Run |AggressiveDCE| on the remaining functions. The order does not matter,
759777 // since |AggressiveDCE| is intra-procedural. This can mean that function
760778 // will become dead if all function call to them are removed. These dead
761779 // function will still be in the module after this pass. We expect this to be
762780 // rare.
763781 for (Function& fp : *context ()->module ()) {
764- modified |= AggressiveDCE (&fp);
782+ Pass::Status function_status = AggressiveDCE (&fp);
783+ if (function_status == Pass::Status::Failure) {
784+ return Pass::Status::Failure;
785+ }
786+ if (function_status == Pass::Status::SuccessWithChange) {
787+ modified = true ;
788+ }
765789 }
766790
767791 // If the decoration manager is kept live then the context will try to keep it
0 commit comments