1+ // Licensed to the .NET Foundation under one or more agreements.
2+ // The .NET Foundation licenses this file to you under the MIT license.
3+
4+ using System ;
5+ using System . Collections . Generic ;
6+ using System . Text ;
7+ using ILLink . Shared . DataFlow ;
8+ using Mono . Cecil ;
9+ using Mono . Linker . Dataflow ;
10+ using MultiValue = ILLink . Shared . DataFlow . ValueSet < ILLink . Shared . DataFlow . SingleValue > ;
11+
12+
13+ namespace ILLink . Shared . TrimAnalysis
14+ {
15+ partial record ArrayValue
16+ {
17+ public static MultiValue Create ( MultiValue size , TypeReference elementType )
18+ {
19+ MultiValue result = MultiValueLattice . Top ;
20+ foreach ( var sizeValue in size ) {
21+ result = MultiValueLattice . Meet ( result , new MultiValue ( new ArrayValue ( sizeValue , elementType ) ) ) ;
22+ }
23+
24+ return result ;
25+ }
26+
27+ public static MultiValue Create ( int size , TypeReference elementType )
28+ {
29+ return new MultiValue ( new ArrayValue ( new ConstIntValue ( size ) , elementType ) ) ;
30+ }
31+
32+ /// <summary>
33+ /// Constructs an array value of the given size
34+ /// </summary>
35+ ArrayValue ( SingleValue size , TypeReference elementType )
36+ {
37+ Size = size ;
38+ ElementType = elementType ;
39+ IndexValues = new Dictionary < int , ValueBasicBlockPair > ( ) ;
40+ }
41+
42+ public TypeReference ElementType { get ; }
43+ public Dictionary < int , ValueBasicBlockPair > IndexValues { get ; }
44+
45+ public partial bool TryGetValueByIndex ( int index , out MultiValue value )
46+ {
47+ if ( IndexValues . TryGetValue ( index , out var valuePair ) ) {
48+ value = valuePair . Value ;
49+ return true ;
50+ }
51+
52+ value = default ;
53+ return false ;
54+ }
55+
56+ public override int GetHashCode ( )
57+ {
58+ return HashCode . Combine ( GetType ( ) . GetHashCode ( ) , Size ) ;
59+ }
60+
61+ public bool Equals ( ArrayValue ? otherArr )
62+ {
63+ if ( otherArr == null )
64+ return false ;
65+
66+ bool equals = Size . Equals ( otherArr . Size ) ;
67+ equals &= IndexValues . Count == otherArr . IndexValues . Count ;
68+ if ( ! equals )
69+ return false ;
70+
71+ // If both sets T and O are the same size and "T intersect O" is empty, then T == O.
72+ HashSet < KeyValuePair < int , ValueBasicBlockPair > > thisValueSet = new ( IndexValues ) ;
73+ HashSet < KeyValuePair < int , ValueBasicBlockPair > > otherValueSet = new ( otherArr . IndexValues ) ;
74+ thisValueSet . ExceptWith ( otherValueSet ) ;
75+ return thisValueSet . Count == 0 ;
76+ }
77+
78+ public override SingleValue DeepCopy ( )
79+ {
80+ var newValue = new ArrayValue ( Size . DeepCopy ( ) , ElementType ) ;
81+ foreach ( var kvp in IndexValues ) {
82+ newValue . IndexValues . Add ( kvp . Key , new ValueBasicBlockPair ( kvp . Value . Value . Clone ( ) , kvp . Value . BasicBlockIndex ) ) ;
83+ }
84+
85+ return newValue ;
86+ }
87+
88+ public override string ToString ( )
89+ {
90+ StringBuilder result = new ( ) ;
91+ result . Append ( "Array Size:" ) ;
92+ result . Append ( this . ValueToString ( Size ) ) ;
93+
94+ result . Append ( ", Values:(" ) ;
95+ bool first = true ;
96+ foreach ( var element in IndexValues ) {
97+ if ( ! first ) {
98+ result . Append ( "," ) ;
99+ first = false ;
100+ }
101+
102+ result . Append ( "(" ) ;
103+ result . Append ( element . Key ) ;
104+ result . Append ( ",(" ) ;
105+ bool firstValue = true ;
106+ foreach ( var v in element . Value . Value ) {
107+ if ( firstValue ) {
108+ result . Append ( "," ) ;
109+ firstValue = false ;
110+ }
111+
112+ result . Append ( v . ToString ( ) ) ;
113+ }
114+ result . Append ( "))" ) ;
115+ }
116+ result . Append ( ')' ) ;
117+
118+ return result . ToString ( ) ;
119+ }
120+ }
121+ }
0 commit comments