|
22 | 22 | #include "swift/SIL/SILBuilder.h"
|
23 | 23 | #include "swift/SIL/SILInstruction.h"
|
24 | 24 | #include "swift/SIL/ScopedAddressUtils.h"
|
| 25 | +#include "swift/SIL/Test.h" |
25 | 26 | #include "llvm/ADT/SmallBitVector.h"
|
26 | 27 | #include "llvm/ADT/SmallVector.h"
|
27 | 28 | #include "llvm/Transforms/Utils/ModuleUtils.h"
|
@@ -836,6 +837,89 @@ void FieldSensitivePrunedLiveRange<LivenessWithDefs>::computeBoundary(
|
836 | 837 | }
|
837 | 838 | }
|
838 | 839 |
|
| 840 | +namespace swift::test { |
| 841 | +// Arguments: |
| 842 | +// - value: entity whose fields' livenesses are being computed |
| 843 | +// - string: "defs:" |
| 844 | +// - variadic list of triples consisting of |
| 845 | +// - value: a live-range defining value |
| 846 | +// - int: the beginning of the range of fields defined by the value |
| 847 | +// - int: the end of the range of the fields defined by the value |
| 848 | +// - the string "uses:" |
| 849 | +// - variadic list of quadruples consisting of |
| 850 | +// - instruction: a live-range user |
| 851 | +// - bool: whether the user is lifetime-ending |
| 852 | +// - int: the beginning of the range of fields used by the instruction |
| 853 | +// - int: the end of the range of fields used by the instruction |
| 854 | +// Dumps: |
| 855 | +// - the liveness result and boundary |
| 856 | +// |
| 857 | +// Computes liveness for the specified def nodes by considering the |
| 858 | +// specified uses. The actual uses of the def nodes are ignored. |
| 859 | +// |
| 860 | +// This is useful for testing non-ssa liveness, for example, of memory |
| 861 | +// locations. In that case, the def nodes may be stores and the uses may be |
| 862 | +// destroy_addrs. |
| 863 | +static FunctionTest FieldSensitiveMultiDefUseLiveRangeTest( |
| 864 | + "fieldsensitive-multidefuse-liverange", |
| 865 | + [](auto &function, auto &arguments, auto &test) { |
| 866 | + SmallVector<SILBasicBlock *, 8> discoveredBlocks; |
| 867 | + auto value = arguments.takeValue(); |
| 868 | + FieldSensitiveMultiDefPrunedLiveRange liveness(&function, value, |
| 869 | + &discoveredBlocks); |
| 870 | + |
| 871 | + llvm::outs() << "FieldSensitive MultiDef lifetime analysis:\n"; |
| 872 | + if (arguments.takeString() != "defs:") { |
| 873 | + llvm::report_fatal_error( |
| 874 | + "test specification expects the 'defs:' label\n"); |
| 875 | + } |
| 876 | + while (true) { |
| 877 | + auto argument = arguments.takeArgument(); |
| 878 | + if (isa<StringArgument>(argument)) { |
| 879 | + if (cast<StringArgument>(argument).getValue() != "uses:") { |
| 880 | + llvm::report_fatal_error( |
| 881 | + "test specification expects the 'uses:' label\n"); |
| 882 | + } |
| 883 | + break; |
| 884 | + } |
| 885 | + auto begin = arguments.takeUInt(); |
| 886 | + auto end = arguments.takeUInt(); |
| 887 | + TypeTreeLeafTypeRange range(begin, end); |
| 888 | + if (isa<InstructionArgument>(argument)) { |
| 889 | + auto *instruction = cast<InstructionArgument>(argument).getValue(); |
| 890 | + llvm::outs() << " def in range [" << begin << ", " << end |
| 891 | + << ") instruction: " << *instruction; |
| 892 | + liveness.initializeDef(instruction, range); |
| 893 | + continue; |
| 894 | + } |
| 895 | + if (isa<ValueArgument>(argument)) { |
| 896 | + SILValue value = cast<ValueArgument>(argument).getValue(); |
| 897 | + llvm::outs() << " def in range [" << begin << ", " << end |
| 898 | + << ") value: " << value; |
| 899 | + liveness.initializeDef(value, range); |
| 900 | + continue; |
| 901 | + } |
| 902 | + llvm::report_fatal_error( |
| 903 | + "test specification expects the 'uses:' label\n"); |
| 904 | + } |
| 905 | + liveness.finishedInitializationOfDefs(); |
| 906 | + while (arguments.hasUntaken()) { |
| 907 | + auto *inst = arguments.takeInstruction(); |
| 908 | + auto lifetimeEnding = arguments.takeBool(); |
| 909 | + auto begin = arguments.takeUInt(); |
| 910 | + auto end = arguments.takeUInt(); |
| 911 | + TypeTreeLeafTypeRange range(begin, end); |
| 912 | + liveness.updateForUse(inst, range, lifetimeEnding); |
| 913 | + } |
| 914 | + liveness.print(llvm::errs()); |
| 915 | + |
| 916 | + FieldSensitivePrunedLivenessBoundary boundary( |
| 917 | + liveness.getNumSubElements()); |
| 918 | + liveness.computeBoundary(boundary); |
| 919 | + boundary.print(llvm::errs()); |
| 920 | + }); |
| 921 | +} // end namespace swift::test |
| 922 | + |
839 | 923 | bool FieldSensitiveMultiDefPrunedLiveRange::isUserBeforeDef(
|
840 | 924 | SILInstruction *user, unsigned element) const {
|
841 | 925 | auto *block = user->getParent();
|
|
0 commit comments