@@ -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.
@@ -1047,16 +1049,15 @@ void LifetimeChecker::handleStoreUse(unsigned UseID) {
1047
1049
// an initialization or assign in the uses list so that clients know about it.
1048
1050
if (isFullyUninitialized) {
1049
1051
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;
1050
1059
} 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;
1060
1061
} else {
1061
1062
// If it is initialized on some paths, but not others, then we have an
1062
1063
// inconsistent initialization, which needs dynamic control logic in the
@@ -1909,7 +1910,7 @@ void LifetimeChecker::updateInstructionForInitState(DIMemoryUse &Use) {
1909
1910
Use.Kind == DIUseKind::SelfInit)
1910
1911
InitKind = IsInitialization;
1911
1912
else {
1912
- assert (Use.Kind == DIUseKind::Assign);
1913
+ assert (Use.Kind == DIUseKind::Assign || Use. Kind == DIUseKind::AssignWrappedValue );
1913
1914
InitKind = IsNotInitialization;
1914
1915
}
1915
1916
@@ -1958,14 +1959,21 @@ void LifetimeChecker::updateInstructionForInitState(DIMemoryUse &Use) {
1958
1959
Use.Inst = nullptr ;
1959
1960
NonLoadUses.erase (Inst);
1960
1961
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" );
1969
1977
}
1970
1978
1971
1979
return ;
0 commit comments