@@ -341,23 +341,37 @@ void DeadCodeAnalysis::visitCallOperation(CallOpInterface call) {
341341// / constant value lattices are uninitialized, return std::nullopt to indicate
342342// / the analysis should bail out.
343343static std::optional<SmallVector<Attribute>> getOperandValuesImpl (
344- Operation *op,
344+ Operation *op, bool failIfAnyNull,
345345 function_ref<const Lattice<ConstantValue> *(Value)> getLattice) {
346346 SmallVector<Attribute> operands;
347347 operands.reserve (op->getNumOperands ());
348348 for (Value operand : op->getOperands ()) {
349349 const Lattice<ConstantValue> *cv = getLattice (operand);
350350 // If any of the operands' values are uninitialized, bail out.
351- if (cv->getValue ().isUninitialized ())
352- return {};
351+ if (cv->getValue ().isUninitialized ()) {
352+ if (failIfAnyNull)
353+ return {};
354+ operands.emplace_back ();
355+ continue ;
356+ }
357+
353358 operands.push_back (cv->getValue ().getConstantValue ());
354359 }
355360 return operands;
356361}
357362
358363std::optional<SmallVector<Attribute>>
359364DeadCodeAnalysis::getOperandValues (Operation *op) {
360- return getOperandValuesImpl (op, [&](Value value) {
365+ return getOperandValuesImpl (op, true , [&](Value value) {
366+ auto *lattice = getOrCreate<Lattice<ConstantValue>>(value);
367+ lattice->useDefSubscribe (this );
368+ return lattice;
369+ });
370+ }
371+
372+ SmallVector<Attribute>
373+ DeadCodeAnalysis::getOperandValuesBestEffort (Operation *op) {
374+ return *getOperandValuesImpl (op, false , [&](Value value) {
361375 auto *lattice = getOrCreate<Lattice<ConstantValue>>(value);
362376 lattice->useDefSubscribe (this );
363377 return lattice;
@@ -366,11 +380,9 @@ DeadCodeAnalysis::getOperandValues(Operation *op) {
366380
367381void DeadCodeAnalysis::visitBranchOperation (BranchOpInterface branch) {
368382 // Try to deduce a single successor for the branch.
369- std::optional<SmallVector<Attribute>> operands = getOperandValues (branch);
370- if (!operands)
371- return ;
383+ SmallVector<Attribute> operands = getOperandValuesBestEffort (branch);
372384
373- if (Block *successor = branch.getSuccessorForOperands (* operands)) {
385+ if (Block *successor = branch.getSuccessorForOperands (operands)) {
374386 markEdgeLive (branch->getBlock (), successor);
375387 } else {
376388 // Otherwise, mark all successors as executable and outgoing edges.
@@ -382,12 +394,10 @@ void DeadCodeAnalysis::visitBranchOperation(BranchOpInterface branch) {
382394void DeadCodeAnalysis::visitRegionBranchOperation (
383395 RegionBranchOpInterface branch) {
384396 // Try to deduce which regions are executable.
385- std::optional<SmallVector<Attribute>> operands = getOperandValues (branch);
386- if (!operands)
387- return ;
397+ SmallVector<Attribute> operands = getOperandValuesBestEffort (branch);
388398
389399 SmallVector<RegionSuccessor> successors;
390- branch.getEntrySuccessorRegions (* operands, successors);
400+ branch.getEntrySuccessorRegions (operands, successors);
391401 for (const RegionSuccessor &successor : successors) {
392402 // The successor can be either an entry block or the parent operation.
393403 ProgramPoint *point =
0 commit comments