@@ -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.
@@ -1048,16 +1050,15 @@ void LifetimeChecker::handleStoreUse(unsigned UseID) {
10481050 // an initialization or assign in the uses list so that clients know about it.
10491051 if (isFullyUninitialized) {
10501052 Use.Kind = DIUseKind::Initialization;
1053+ } else if (isFullyInitialized && isa<AssignByWrapperInst>(Use.Inst )) {
1054+ // If some fields are uninitialized, re-write assign_by_wrapper to assignment
1055+ // of the backing wrapper. If all fields are initialized, assign to the wrapped
1056+ // value.
1057+ auto allFieldsInitialized =
1058+ getAnyUninitializedMemberAtInst (Use.Inst , 0 , TheMemory.getNumElements ()) == -1 ;
1059+ Use.Kind = allFieldsInitialized ? DIUseKind::AssignWrappedValue : DIUseKind::Assign;
10511060 } else if (isFullyInitialized) {
1052- // Only re-write assign_by_wrapper to assignment if all fields have been
1053- // initialized.
1054- if (isa<AssignByWrapperInst>(Use.Inst ) &&
1055- getAnyUninitializedMemberAtInst (Use.Inst , 0 ,
1056- TheMemory.getNumElements ()) != -1 ) {
1057- Use.Kind = DIUseKind::Initialization;
1058- } else {
1059- Use.Kind = DIUseKind::Assign;
1060- }
1061+ Use.Kind = DIUseKind::Assign;
10611062 } else {
10621063 // If it is initialized on some paths, but not others, then we have an
10631064 // inconsistent initialization, which needs dynamic control logic in the
@@ -1918,7 +1919,7 @@ void LifetimeChecker::updateInstructionForInitState(DIMemoryUse &Use) {
19181919 Use.Kind == DIUseKind::SelfInit)
19191920 InitKind = IsInitialization;
19201921 else {
1921- assert (Use.Kind == DIUseKind::Assign);
1922+ assert (Use.Kind == DIUseKind::Assign || Use. Kind == DIUseKind::AssignWrappedValue );
19221923 InitKind = IsNotInitialization;
19231924 }
19241925
@@ -1967,14 +1968,21 @@ void LifetimeChecker::updateInstructionForInitState(DIMemoryUse &Use) {
19671968 Use.Inst = nullptr ;
19681969 NonLoadUses.erase (Inst);
19691970
1970- if (TheMemory.isClassInitSelf () &&
1971- Use.Kind == DIUseKind::SelfInit) {
1972- assert (InitKind == IsInitialization);
1973- AI->setOwnershipQualifier (AssignOwnershipQualifier::Reinit);
1974- } else {
1975- AI->setOwnershipQualifier ((InitKind == IsInitialization
1976- ? AssignOwnershipQualifier::Init
1977- : AssignOwnershipQualifier::Reassign));
1971+ switch (Use.Kind ) {
1972+ case DIUseKind::Initialization:
1973+ AI->setAssignInfo (AssignOwnershipQualifier::Init,
1974+ AssignByWrapperInst::Destination::BackingWrapper);
1975+ break ;
1976+ case DIUseKind::Assign:
1977+ AI->setAssignInfo (AssignOwnershipQualifier::Reassign,
1978+ AssignByWrapperInst::Destination::BackingWrapper);
1979+ break ;
1980+ case DIUseKind::AssignWrappedValue:
1981+ AI->setAssignInfo (AssignOwnershipQualifier::Reassign,
1982+ AssignByWrapperInst::Destination::WrappedValue);
1983+ break ;
1984+ default :
1985+ llvm_unreachable (" Wrong use kind for assign_by_wrapper" );
19781986 }
19791987
19801988 return ;
0 commit comments