@@ -533,6 +533,7 @@ LifetimeChecker::LifetimeChecker(const DIMemoryObjectInfo &TheMemory,
533
533
case DIUseKind::Escape:
534
534
continue ;
535
535
case DIUseKind::Assign:
536
+ case DIUseKind::AssignWrappedValue:
536
537
case DIUseKind::IndirectIn:
537
538
case DIUseKind::InitOrAssign:
538
539
case DIUseKind::InOutArgument:
@@ -750,6 +751,7 @@ void LifetimeChecker::doIt() {
750
751
continue ;
751
752
752
753
case DIUseKind::Assign:
754
+ case DIUseKind::AssignWrappedValue:
753
755
// Instructions classified as assign are only generated when lowering
754
756
// InitOrAssign instructions in regions known to be initialized. Since
755
757
// they are already known to be definitely init, don't reprocess them.
@@ -1048,16 +1050,15 @@ void LifetimeChecker::handleStoreUse(unsigned UseID) {
1048
1050
// an initialization or assign in the uses list so that clients know about it.
1049
1051
if (isFullyUninitialized) {
1050
1052
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;
1051
1060
} 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;
1061
1062
} else {
1062
1063
// If it is initialized on some paths, but not others, then we have an
1063
1064
// inconsistent initialization, which needs dynamic control logic in the
@@ -1918,7 +1919,7 @@ void LifetimeChecker::updateInstructionForInitState(DIMemoryUse &Use) {
1918
1919
Use.Kind == DIUseKind::SelfInit)
1919
1920
InitKind = IsInitialization;
1920
1921
else {
1921
- assert (Use.Kind == DIUseKind::Assign);
1922
+ assert (Use.Kind == DIUseKind::Assign || Use. Kind == DIUseKind::AssignWrappedValue );
1922
1923
InitKind = IsNotInitialization;
1923
1924
}
1924
1925
@@ -1967,14 +1968,21 @@ void LifetimeChecker::updateInstructionForInitState(DIMemoryUse &Use) {
1967
1968
Use.Inst = nullptr ;
1968
1969
NonLoadUses.erase (Inst);
1969
1970
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" );
1978
1986
}
1979
1987
1980
1988
return ;
0 commit comments