@@ -1116,7 +1116,107 @@ void FieldSensitiveMultiDefPrunedLiveRange::findBoundariesInBlock(
11161116 << " Live at beginning of block! No dead args!\n " );
11171117 }
11181118
1119- assert ((isLiveOut ||
1120- prevCount < boundary.getNumLastUsersAndDeadDefs (bitNo)) &&
1121- " findBoundariesInBlock must be called on a live block" );
1119+ assert (
1120+ (isLiveOut || prevCount < boundary.getNumLastUsersAndDeadDefs (bitNo)) &&
1121+ " findBoundariesInBlock must be called on a live block" );
1122+ }
1123+
1124+ bool FieldSensitiveMultiDefPrunedLiveRange::findEarlierConsumingUse (
1125+ SILInstruction *inst, unsigned index,
1126+ llvm::function_ref<bool (SILInstruction *)> callback) const {
1127+ PRUNED_LIVENESS_LOG (
1128+ llvm::dbgs ()
1129+ << " Performing single block search for consuming use for bit: " << index
1130+ << " !\n " );
1131+
1132+ // Walk our block back from inst looking for defs or a consuming use. If we
1133+ // see a def, return true. If we see a use, we keep processing if the callback
1134+ // returns true... and return false early if the callback returns false.
1135+ for (auto ii = std::next (inst->getReverseIterator ()),
1136+ ie = inst->getParent ()->rend ();
1137+ ii != ie; ++ii) {
1138+ PRUNED_LIVENESS_LOG (llvm::dbgs () << " Visiting: " << *ii);
1139+ // If we have a def, then we are automatically done.
1140+ if (isDef (&*ii, index)) {
1141+ PRUNED_LIVENESS_LOG (llvm::dbgs () << " Is Def! Returning true!\n " );
1142+ return true ;
1143+ }
1144+
1145+ // If we have a consuming use, emit the error.
1146+ if (isInterestingUser (&*ii, index) ==
1147+ IsInterestingUser::LifetimeEndingUse) {
1148+ PRUNED_LIVENESS_LOG (llvm::dbgs () << " Is Lifetime Ending Use!\n " );
1149+ if (!callback (&*ii)) {
1150+ PRUNED_LIVENESS_LOG (llvm::dbgs ()
1151+ << " Callback returned false... exiting!\n " );
1152+ return false ;
1153+ }
1154+ PRUNED_LIVENESS_LOG (llvm::dbgs ()
1155+ << " Callback returned true... continuing!\n " );
1156+ }
1157+
1158+ // Otherwise, keep going.
1159+ }
1160+
1161+ // Then check our argument defs.
1162+ for (auto *arg : inst->getParent ()->getArguments ()) {
1163+ PRUNED_LIVENESS_LOG (llvm::dbgs () << " Visiting arg: " << *arg);
1164+ if (isDef (arg, index)) {
1165+ PRUNED_LIVENESS_LOG (llvm::dbgs () << " Found def. Returning true!\n " );
1166+ return true ;
1167+ }
1168+ }
1169+
1170+ PRUNED_LIVENESS_LOG (llvm::dbgs () << " Finished single block. Didn't find "
1171+ " anything... Performing interprocedural" );
1172+
1173+ // Ok, we now know that we need to look further back.
1174+ BasicBlockWorklist worklist (inst->getFunction ());
1175+ for (auto *predBlock : inst->getParent ()->getPredecessorBlocks ()) {
1176+ worklist.pushIfNotVisited (predBlock);
1177+ }
1178+
1179+ while (auto *next = worklist.pop ()) {
1180+ PRUNED_LIVENESS_LOG (llvm::dbgs ()
1181+ << " Checking block bb" << next->getDebugID () << ' \n ' );
1182+ for (auto ii = next->rbegin (), ie = next->rend (); ii != ie; ++ii) {
1183+ PRUNED_LIVENESS_LOG (llvm::dbgs () << " Visiting: " << *ii);
1184+ // If we have a def, then we are automatically done.
1185+ if (isDef (&*ii, index)) {
1186+ PRUNED_LIVENESS_LOG (llvm::dbgs () << " Is Def! Returning true!\n " );
1187+ return true ;
1188+ }
1189+
1190+ // If we have a consuming use, emit the error.
1191+ if (isInterestingUser (&*ii, index) ==
1192+ IsInterestingUser::LifetimeEndingUse) {
1193+ PRUNED_LIVENESS_LOG (llvm::dbgs () << " Is Lifetime Ending Use!\n " );
1194+ if (!callback (&*ii)) {
1195+ PRUNED_LIVENESS_LOG (llvm::dbgs ()
1196+ << " Callback returned false... exiting!\n " );
1197+ return false ;
1198+ }
1199+ PRUNED_LIVENESS_LOG (llvm::dbgs ()
1200+ << " Callback returned true... continuing!\n " );
1201+ }
1202+
1203+ // Otherwise, keep going.
1204+ }
1205+
1206+ for (auto *arg : next->getArguments ()) {
1207+ PRUNED_LIVENESS_LOG (llvm::dbgs () << " Visiting arg: " << *arg);
1208+ if (isDef (arg, index)) {
1209+ PRUNED_LIVENESS_LOG (llvm::dbgs () << " Found def. Returning true!\n " );
1210+ return true ;
1211+ }
1212+ }
1213+
1214+ PRUNED_LIVENESS_LOG (llvm::dbgs ()
1215+ << " Didn't find anything... visiting predecessors!\n " );
1216+ for (auto *predBlock : next->getPredecessorBlocks ()) {
1217+ worklist.pushIfNotVisited (predBlock);
1218+ }
1219+ }
1220+
1221+ return true ;
11221222}
0 commit comments