@@ -533,6 +533,7 @@ LifetimeChecker::LifetimeChecker(const DIMemoryObjectInfo &TheMemory,
533533 case DIUseKind::Escape:
534534 continue ;
535535 case DIUseKind::Assign:
536+ case DIUseKind::AssignWrappedValue:
536537 case DIUseKind::IndirectIn:
537538 case DIUseKind::InitOrAssign:
538539 case DIUseKind::InOutArgument:
@@ -750,6 +751,7 @@ void LifetimeChecker::doIt() {
750751 continue ;
751752
752753 case DIUseKind::Assign:
754+ case DIUseKind::AssignWrappedValue:
753755 // Instructions classified as assign are only generated when lowering
754756 // InitOrAssign instructions in regions known to be initialized. Since
755757 // they are already known to be definitely init, don't reprocess them.
@@ -1047,16 +1049,15 @@ void LifetimeChecker::handleStoreUse(unsigned UseID) {
10471049 // an initialization or assign in the uses list so that clients know about it.
10481050 if (isFullyUninitialized) {
10491051 Use.Kind = DIUseKind::Initialization;
1052+ } else if (isFullyInitialized && isa<AssignByWrapperInst>(Use.Inst )) {
1053+ // If some fields are uninitialized, re-write assign_by_wrapper to assignment
1054+ // of the backing wrapper. If all fields are initialized, assign to the wrapped
1055+ // value.
1056+ auto allFieldsInitialized =
1057+ getAnyUninitializedMemberAtInst (Use.Inst , 0 , TheMemory.getNumElements ()) == -1 ;
1058+ Use.Kind = allFieldsInitialized ? DIUseKind::AssignWrappedValue : DIUseKind::Assign;
10501059 } else if (isFullyInitialized) {
1051- // Only re-write assign_by_wrapper to assignment if all fields have been
1052- // initialized.
1053- if (isa<AssignByWrapperInst>(Use.Inst ) &&
1054- getAnyUninitializedMemberAtInst (Use.Inst , 0 ,
1055- TheMemory.getNumElements ()) != -1 ) {
1056- Use.Kind = DIUseKind::Initialization;
1057- } else {
1058- Use.Kind = DIUseKind::Assign;
1059- }
1060+ Use.Kind = DIUseKind::Assign;
10601061 } else {
10611062 // If it is initialized on some paths, but not others, then we have an
10621063 // inconsistent initialization, which needs dynamic control logic in the
@@ -1909,7 +1910,7 @@ void LifetimeChecker::updateInstructionForInitState(DIMemoryUse &Use) {
19091910 Use.Kind == DIUseKind::SelfInit)
19101911 InitKind = IsInitialization;
19111912 else {
1912- assert (Use.Kind == DIUseKind::Assign);
1913+ assert (Use.Kind == DIUseKind::Assign || Use. Kind == DIUseKind::AssignWrappedValue );
19131914 InitKind = IsNotInitialization;
19141915 }
19151916
@@ -1958,14 +1959,21 @@ void LifetimeChecker::updateInstructionForInitState(DIMemoryUse &Use) {
19581959 Use.Inst = nullptr ;
19591960 NonLoadUses.erase (Inst);
19601961
1961- if (TheMemory.isClassInitSelf () &&
1962- Use.Kind == DIUseKind::SelfInit) {
1963- assert (InitKind == IsInitialization);
1964- AI->setOwnershipQualifier (AssignOwnershipQualifier::Reinit);
1965- } else {
1966- AI->setOwnershipQualifier ((InitKind == IsInitialization
1967- ? AssignOwnershipQualifier::Init
1968- : AssignOwnershipQualifier::Reassign));
1962+ switch (Use.Kind ) {
1963+ case DIUseKind::Initialization:
1964+ AI->setAssignInfo (AssignOwnershipQualifier::Init,
1965+ AssignByWrapperInst::Destination::BackingWrapper);
1966+ break ;
1967+ case DIUseKind::Assign:
1968+ AI->setAssignInfo (AssignOwnershipQualifier::Reassign,
1969+ AssignByWrapperInst::Destination::BackingWrapper);
1970+ break ;
1971+ case DIUseKind::AssignWrappedValue:
1972+ AI->setAssignInfo (AssignOwnershipQualifier::Reassign,
1973+ AssignByWrapperInst::Destination::WrappedValue);
1974+ break ;
1975+ default :
1976+ llvm_unreachable (" Wrong use kind for assign_by_wrapper" );
19691977 }
19701978
19711979 return ;
0 commit comments