@@ -368,9 +368,12 @@ struct ScopedAddressLivenessTest : UnitTest {
368368};
369369
370370// Arguments:
371- // - variadic list of live-range defining values
371+ // - variadic list of live-range defining values or instructions
372372// Dumps:
373373// - the liveness result and boundary
374+ //
375+ // Computes liveness for the specified def nodes by finding all their direct SSA
376+ // uses. If the def is an instruction, then all results are considered.
374377struct MultiDefLivenessTest : UnitTest {
375378 MultiDefLivenessTest (UnitTestRunner *pass) : UnitTest(pass) {}
376379
@@ -380,9 +383,16 @@ struct MultiDefLivenessTest : UnitTest {
380383
381384 llvm::outs () << " MultiDef lifetime analysis:\n " ;
382385 while (arguments.hasUntaken ()) {
383- SILValue value = arguments.takeValue ();
384- llvm::outs () << " def: " << value;
385- liveness.initializeDef (value);
386+ auto argument = arguments.takeArgument ();
387+ if (isa<InstructionArgument>(argument)) {
388+ auto *instruction = cast<InstructionArgument>(argument).getValue ();
389+ llvm::outs () << " def instruction: " << instruction;
390+ liveness.initializeDef (instruction);
391+ } else {
392+ SILValue value = cast<ValueArgument>(argument).getValue ();
393+ llvm::outs () << " def value: " << value;
394+ liveness.initializeDef (value);
395+ }
386396 }
387397 liveness.computeSimple ();
388398 liveness.print (llvm::outs ());
@@ -393,6 +403,66 @@ struct MultiDefLivenessTest : UnitTest {
393403 }
394404};
395405
406+ // Arguments:
407+ // - the string "defs:"
408+ // - list of live-range defining values or instructions
409+ // - the string "uses:"
410+ // - variadic list of live-range user instructions
411+ // Dumps:
412+ // - the liveness result and boundary
413+ //
414+ // Computes liveness for the specified def nodes by considering only the
415+ // specified uses. The actual uses of the def nodes are ignored.
416+ //
417+ // This is useful for testing non-ssa liveness, for example, of memory
418+ // locations. In that case, the def nodes may be stores and the uses may be
419+ // destroy_addrs.
420+ struct MultiDefUseLivenessTest : UnitTest {
421+ MultiDefUseLivenessTest (UnitTestRunner *pass) : UnitTest(pass) {}
422+
423+ void invoke (Arguments &arguments) override {
424+ SmallVector<SILBasicBlock *, 8 > discoveredBlocks;
425+ MultiDefPrunedLiveness liveness (getFunction (), &discoveredBlocks);
426+
427+ llvm::outs () << " MultiDef lifetime analysis:\n " ;
428+ if (arguments.takeString () != " defs:" ) {
429+ llvm::report_fatal_error (
430+ " test specification expects the 'defs:' label\n " );
431+ }
432+ while (true ) {
433+ auto argument = arguments.takeArgument ();
434+ if (isa<InstructionArgument>(argument)) {
435+ auto *instruction = cast<InstructionArgument>(argument).getValue ();
436+ llvm::outs () << " def instruction: " << *instruction;
437+ liveness.initializeDef (instruction);
438+ continue ;
439+ }
440+ if (isa<ValueArgument>(argument)) {
441+ SILValue value = cast<ValueArgument>(argument).getValue ();
442+ llvm::outs () << " def value: " << value;
443+ liveness.initializeDef (value);
444+ continue ;
445+ }
446+ if (cast<StringArgument>(argument).getValue () != " uses:" ) {
447+ llvm::report_fatal_error (
448+ " test specification expects the 'uses:' label\n " );
449+ }
450+ break ;
451+ }
452+ while (arguments.hasUntaken ()) {
453+ auto *inst = arguments.takeInstruction ();
454+ // lifetimeEnding has no effects on liveness, it's only a cache for the
455+ // caller.
456+ liveness.updateForUse (inst, /* lifetimeEnding*/ false );
457+ }
458+ liveness.print (llvm::outs ());
459+
460+ PrunedLivenessBoundary boundary;
461+ liveness.computeBoundary (boundary);
462+ boundary.print (llvm::outs ());
463+ }
464+ };
465+
396466// Arguments:
397467// - bool: pruneDebug
398468// - bool: maximizeLifetimes
@@ -815,6 +885,7 @@ void UnitTestRunner::withTest(StringRef name, Doit doit) {
815885 ADD_UNIT_TEST_SUBCLASS (" is-lexical" , IsLexicalTest)
816886 ADD_UNIT_TEST_SUBCLASS (" linear-liveness" , LinearLivenessTest)
817887 ADD_UNIT_TEST_SUBCLASS (" multidef-liveness" , MultiDefLivenessTest)
888+ ADD_UNIT_TEST_SUBCLASS (" multidefuse-liveness" , MultiDefUseLivenessTest)
818889 ADD_UNIT_TEST_SUBCLASS (" ossa-lifetime-completion" , OSSALifetimeCompletionTest)
819890 ADD_UNIT_TEST_SUBCLASS (" pruned-liveness-boundary-with-list-of-last-users-insertion-points" , PrunedLivenessBoundaryWithListOfLastUsersInsertionPointsTest)
820891 ADD_UNIT_TEST_SUBCLASS (" shrink-borrow-scope" , ShrinkBorrowScopeTest)
0 commit comments