@@ -630,12 +630,21 @@ class TransferTracker {
630630 if (!ShouldEmitDebugEntryValues)
631631 return false ;
632632
633+ const DIExpression *DIExpr = Prop.DIExpr ;
634+
633635 // We don't currently emit entry values for DBG_VALUE_LISTs.
634- if (Prop.IsVariadic )
635- return false ;
636+ if (Prop.IsVariadic ) {
637+ // If this debug value can be converted to be non-variadic, then do so;
638+ // otherwise give up.
639+ auto NonVariadicExpression =
640+ DIExpression::convertToNonVariadicExpression (DIExpr);
641+ if (!NonVariadicExpression)
642+ return false ;
643+ DIExpr = *NonVariadicExpression;
644+ }
636645
637646 // Is the variable appropriate for entry values (i.e., is a parameter).
638- if (!isEntryValueVariable (Var, Prop. DIExpr ))
647+ if (!isEntryValueVariable (Var, DIExpr))
639648 return false ;
640649
641650 // Is the value assigned to this variable still the entry value?
@@ -644,12 +653,12 @@ class TransferTracker {
644653
645654 // Emit a variable location using an entry value expression.
646655 DIExpression *NewExpr =
647- DIExpression::prepend (Prop. DIExpr , DIExpression::EntryValue);
656+ DIExpression::prepend (DIExpr, DIExpression::EntryValue);
648657 Register Reg = MTracker->LocIdxToLocID [Num.getLoc ()];
649658 MachineOperand MO = MachineOperand::CreateReg (Reg, false );
650659
651660 PendingDbgValues.push_back (
652- emitMOLoc (MO, Var, {NewExpr, Prop.Indirect , Prop. IsVariadic }));
661+ emitMOLoc (MO, Var, {NewExpr, Prop.Indirect , false }));
653662 return true ;
654663 }
655664
@@ -809,8 +818,8 @@ class TransferTracker {
809818 for (const auto &Var : ActiveMLocIt->second ) {
810819 auto ActiveVLocIt = ActiveVLocs.find (Var);
811820 // Re-state the variable location: if there's no replacement then NewLoc
812- // is None and a $noreg DBG_VALUE will be created. Otherwise, a DBG_VALUE
813- // identifying the alternative location will be emitted.
821+ // is std::nullopt and a $noreg DBG_VALUE will be created. Otherwise, a
822+ // DBG_VALUE identifying the alternative location will be emitted.
814823 const DbgValueProperties &Properties = ActiveVLocIt->second .Properties ;
815824
816825 // Produce the new list of debug ops - an empty list if no new location
@@ -1418,39 +1427,14 @@ bool InstrRefBasedLDV::transferDebugValue(const MachineInstr &MI) {
14181427 return true ;
14191428}
14201429
1421- bool InstrRefBasedLDV::transferDebugInstrRef (MachineInstr &MI,
1422- const ValueTable *MLiveOuts,
1423- const ValueTable *MLiveIns) {
1424- if (!MI.isDebugRef ())
1425- return false ;
1426-
1427- // Only handle this instruction when we are building the variable value
1428- // transfer function.
1429- if (!VTracker && !TTracker)
1430- return false ;
1431-
1432- unsigned InstNo = MI.getDebugOperand (0 ).getInstrRefInstrIndex ();
1433- unsigned OpNo = MI.getDebugOperand (0 ).getInstrRefOpIndex ();
1434-
1435- const DILocalVariable *Var = MI.getDebugVariable ();
1436- const DIExpression *Expr = MI.getDebugExpression ();
1437- const DILocation *DebugLoc = MI.getDebugLoc ();
1438- const DILocation *InlinedAt = DebugLoc->getInlinedAt ();
1439- assert (Var->isValidLocationForIntrinsic (DebugLoc) &&
1440- " Expected inlined-at fields to agree" );
1441-
1442- DebugVariable V (Var, Expr, InlinedAt);
1443-
1444- auto *Scope = LS.findLexicalScope (MI.getDebugLoc ().get ());
1445- if (Scope == nullptr )
1446- return true ; // Handled by doing nothing. This variable is never in scope.
1447-
1448- const MachineFunction &MF = *MI.getParent ()->getParent ();
1449-
1430+ std::optional<ValueIDNum> InstrRefBasedLDV::getValueForInstrRef (
1431+ unsigned InstNo, unsigned OpNo, MachineInstr &MI,
1432+ const ValueTable *MLiveOuts, const ValueTable *MLiveIns) {
14501433 // Various optimizations may have happened to the value during codegen,
14511434 // recorded in the value substitution table. Apply any substitutions to
14521435 // the instruction / operand number in this DBG_INSTR_REF, and collect
14531436 // any subregister extractions performed during optimization.
1437+ const MachineFunction &MF = *MI.getParent ()->getParent ();
14541438
14551439 // Create dummy substitution with Src set, for lookup.
14561440 auto SoughtSub =
@@ -1586,14 +1570,64 @@ bool InstrRefBasedLDV::transferDebugInstrRef(MachineInstr &MI,
15861570 }
15871571 }
15881572
1589- // We, we have a value number or std::nullopt. Tell the variable value tracker
1590- // about it. The rest of this LiveDebugValues implementation acts exactly the
1591- // same for DBG_INSTR_REFs as DBG_VALUEs (just, the former can refer to values
1592- // that aren't immediately available).
1593- DbgValueProperties Properties (Expr, false , true );
1573+ return NewID;
1574+ }
1575+
1576+ bool InstrRefBasedLDV::transferDebugInstrRef (MachineInstr &MI,
1577+ const ValueTable *MLiveOuts,
1578+ const ValueTable *MLiveIns) {
1579+ if (!MI.isDebugRef ())
1580+ return false ;
1581+
1582+ // Only handle this instruction when we are building the variable value
1583+ // transfer function.
1584+ if (!VTracker && !TTracker)
1585+ return false ;
1586+
1587+ const DILocalVariable *Var = MI.getDebugVariable ();
1588+ const DIExpression *Expr = MI.getDebugExpression ();
1589+ const DILocation *DebugLoc = MI.getDebugLoc ();
1590+ const DILocation *InlinedAt = DebugLoc->getInlinedAt ();
1591+ assert (Var->isValidLocationForIntrinsic (DebugLoc) &&
1592+ " Expected inlined-at fields to agree" );
1593+
1594+ DebugVariable V (Var, Expr, InlinedAt);
1595+
1596+ auto *Scope = LS.findLexicalScope (MI.getDebugLoc ().get ());
1597+ if (Scope == nullptr )
1598+ return true ; // Handled by doing nothing. This variable is never in scope.
1599+
15941600 SmallVector<DbgOpID> DbgOpIDs;
1595- if (NewID)
1596- DbgOpIDs.push_back (DbgOpStore.insert (*NewID));
1601+ for (const MachineOperand &MO : MI.debug_operands ()) {
1602+ if (!MO.isDbgInstrRef ()) {
1603+ assert (!MO.isReg () && " DBG_INSTR_REF should not contain registers" );
1604+ DbgOpID ConstOpID = DbgOpStore.insert (DbgOp (MO));
1605+ DbgOpIDs.push_back (ConstOpID);
1606+ continue ;
1607+ }
1608+
1609+ unsigned InstNo = MO.getInstrRefInstrIndex ();
1610+ unsigned OpNo = MO.getInstrRefOpIndex ();
1611+
1612+ // Default machine value number is <None> -- if no instruction defines
1613+ // the corresponding value, it must have been optimized out.
1614+ std::optional<ValueIDNum> NewID =
1615+ getValueForInstrRef (InstNo, OpNo, MI, MLiveOuts, MLiveIns);
1616+ // We have a value number or std::nullopt. If the latter, then kill the
1617+ // entire debug value.
1618+ if (NewID) {
1619+ DbgOpIDs.push_back (DbgOpStore.insert (*NewID));
1620+ } else {
1621+ DbgOpIDs.clear ();
1622+ break ;
1623+ }
1624+ }
1625+
1626+ // We have a DbgOpID for every value or for none. Tell the variable value
1627+ // tracker about it. The rest of this LiveDebugValues implementation acts
1628+ // exactly the same for DBG_INSTR_REFs as DBG_VALUEs (just, the former can
1629+ // refer to values that aren't immediately available).
1630+ DbgValueProperties Properties (Expr, false , true );
15971631 if (VTracker)
15981632 VTracker->defVar (MI, Properties, DbgOpIDs);
15991633
@@ -1602,40 +1636,84 @@ bool InstrRefBasedLDV::transferDebugInstrRef(MachineInstr &MI,
16021636 if (!TTracker)
16031637 return true ;
16041638
1639+ // Fetch the concrete DbgOps now, as we will need them later.
1640+ SmallVector<DbgOp> DbgOps;
1641+ for (DbgOpID OpID : DbgOpIDs) {
1642+ DbgOps.push_back (DbgOpStore.find (OpID));
1643+ }
1644+
16051645 // Pick a location for the machine value number, if such a location exists.
16061646 // (This information could be stored in TransferTracker to make it faster).
1607- TransferTracker::LocationAndQuality FoundLoc;
1647+ SmallDenseMap<ValueIDNum, TransferTracker::LocationAndQuality> FoundLocs;
1648+ SmallVector<ValueIDNum> ValuesToFind;
1649+ // Initialized the preferred-location map with illegal locations, to be
1650+ // filled in later.
1651+ for (const DbgOp &Op : DbgOps) {
1652+ if (!Op.IsConst )
1653+ if (FoundLocs.insert ({Op.ID , TransferTracker::LocationAndQuality ()})
1654+ .second )
1655+ ValuesToFind.push_back (Op.ID );
1656+ }
1657+
16081658 for (auto Location : MTracker->locations ()) {
16091659 LocIdx CurL = Location.Idx ;
16101660 ValueIDNum ID = MTracker->readMLoc (CurL);
1611- if (NewID && ID == NewID) {
1612- // If this is the first location with that value, pick it. Otherwise,
1613- // consider whether it's a "longer term" location.
1614- std::optional<TransferTracker::LocationQuality> ReplacementQuality =
1615- TTracker->getLocQualityIfBetter (CurL, FoundLoc.getQuality ());
1616- if (ReplacementQuality) {
1617- FoundLoc =
1618- TransferTracker::LocationAndQuality (CurL, *ReplacementQuality);
1619- if (FoundLoc.isBest ())
1661+ auto ValueToFindIt = find (ValuesToFind, ID);
1662+ if (ValueToFindIt == ValuesToFind.end ())
1663+ continue ;
1664+ auto &Previous = FoundLocs.find (ID)->second ;
1665+ // If this is the first location with that value, pick it. Otherwise,
1666+ // consider whether it's a "longer term" location.
1667+ std::optional<TransferTracker::LocationQuality> ReplacementQuality =
1668+ TTracker->getLocQualityIfBetter (CurL, Previous.getQuality ());
1669+ if (ReplacementQuality) {
1670+ Previous = TransferTracker::LocationAndQuality (CurL, *ReplacementQuality);
1671+ if (Previous.isBest ()) {
1672+ ValuesToFind.erase (ValueToFindIt);
1673+ if (ValuesToFind.empty ())
16201674 break ;
16211675 }
16221676 }
16231677 }
16241678
16251679 SmallVector<ResolvedDbgOp> NewLocs;
1626- if (!FoundLoc.isIllegal ())
1627- NewLocs.push_back (FoundLoc.getLoc ());
1680+ for (const DbgOp &DbgOp : DbgOps) {
1681+ if (DbgOp.IsConst ) {
1682+ NewLocs.push_back (DbgOp.MO );
1683+ continue ;
1684+ }
1685+ LocIdx FoundLoc = FoundLocs.find (DbgOp.ID )->second .getLoc ();
1686+ if (FoundLoc.isIllegal ()) {
1687+ NewLocs.clear ();
1688+ break ;
1689+ }
1690+ NewLocs.push_back (FoundLoc);
1691+ }
16281692 // Tell transfer tracker that the variable value has changed.
16291693 TTracker->redefVar (MI, Properties, NewLocs);
16301694
1631- // If there was a value with no location; but the value is defined in a
1632- // later instruction in this block, this is a block-local use-before-def.
1633- if (FoundLoc.isIllegal () && NewID && NewID->getBlock () == CurBB &&
1634- NewID->getInst () > CurInst) {
1635- SmallVector<DbgOp> UseBeforeDefLocs;
1636- UseBeforeDefLocs.push_back (*NewID);
1637- TTracker->addUseBeforeDef (V, {MI.getDebugExpression (), false , true },
1638- UseBeforeDefLocs, NewID->getInst ());
1695+ // If there were values with no location, but all such values are defined in
1696+ // later instructions in this block, this is a block-local use-before-def.
1697+ if (!DbgOps.empty () && NewLocs.empty ()) {
1698+ bool IsValidUseBeforeDef = true ;
1699+ uint64_t LastUseBeforeDef = 0 ;
1700+ for (auto ValueLoc : FoundLocs) {
1701+ ValueIDNum NewID = ValueLoc.first ;
1702+ LocIdx FoundLoc = ValueLoc.second .getLoc ();
1703+ if (!FoundLoc.isIllegal ())
1704+ continue ;
1705+ // If we have an value with no location that is not defined in this block,
1706+ // then it has no location in this block, leaving this value undefined.
1707+ if (NewID.getBlock () != CurBB || NewID.getInst () <= CurInst) {
1708+ IsValidUseBeforeDef = false ;
1709+ break ;
1710+ }
1711+ LastUseBeforeDef = std::max (LastUseBeforeDef, NewID.getInst ());
1712+ }
1713+ if (IsValidUseBeforeDef) {
1714+ TTracker->addUseBeforeDef (V, {MI.getDebugExpression (), false , true },
1715+ DbgOps, LastUseBeforeDef);
1716+ }
16391717 }
16401718
16411719 // Produce a DBG_VALUE representing what this DBG_INSTR_REF meant.
@@ -4004,13 +4082,13 @@ std::optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIs(
40044082
40054083 // This function will be called twice per DBG_INSTR_REF, and might end up
40064084 // computing lots of SSA information: memoize it.
4007- auto SeenDbgPHIIt = SeenDbgPHIs.find (&Here);
4085+ auto SeenDbgPHIIt = SeenDbgPHIs.find (std::make_pair ( &Here, InstrNum) );
40084086 if (SeenDbgPHIIt != SeenDbgPHIs.end ())
40094087 return SeenDbgPHIIt->second ;
40104088
40114089 std::optional<ValueIDNum> Result =
40124090 resolveDbgPHIsImpl (MF, MLiveOuts, MLiveIns, Here, InstrNum);
4013- SeenDbgPHIs.insert ({&Here, Result});
4091+ SeenDbgPHIs.insert ({std::make_pair ( &Here, InstrNum) , Result});
40144092 return Result;
40154093}
40164094
0 commit comments