1 using System;
  2 using System.IO;
  3 using System.Collections;
  4 using CodeFormatter = System.Text.CodeFormatter;
  5 
  6 namespace cmsx.intermediate
  7 {
  8     public class AddressDescriptor
  9     {
 10         public nothrow AddressDescriptor(Value* variable_) : variable(variable_)
 11         {
 12         }
 13         public void DebugPrint(CodeFormatter& formatter)
 14         {
 15             formatter << "addr." << variable->Name() << "(";
 16             bool first = true;
 17             for (Location* location : locations)
 18             {
 19                 if (first)
 20                 {
 21                     first = false;
 22                 }
 23                 else
 24                 {
 25                     formatter << ", ";
 26                 }
 27                 location->DebugPrint(formatter);
 28             }
 29             formatter << ")";
 30         }
 31         public void AddLocation(Location* location)
 32         {
 33             for (Location* loc : locations)
 34             {
 35                 if (loc == location) return;
 36             }
 37             locations.Add(location);
 38         }
 39         public void SetLocation(Location* location)
 40         {
 41             locations.Clear();
 42             locations.Add(location);
 43         }
 44         public nothrow Location* GetLocation() const
 45         {
 46             Location* location = null;
 47             for (Location* loc : locations)
 48             {
 49                 if (loc is Register*)
 50                 {
 51                     return loc;
 52                 }
 53                 else
 54                 {
 55                     location = loc;
 56                 }
 57             }
 58             return location;
 59         }
 60         public nothrow Location* GetMemoryLocation() const
 61         {
 62             Location* location = null;
 63             for (Location* loc : locations)
 64             {
 65                 if (loc is MemoryLocation*)
 66                 {
 67                     return loc;
 68                 }
 69                 else
 70                 {
 71                     location = loc;
 72                 }
 73             }
 74             return location;
 75         }
 76         public nothrow bool HasLocation(Location* location) const
 77         {
 78             for (Location* loc : locations)
 79             {
 80                 if (loc == location) return true;
 81             }
 82             return false;
 83         }
 84         public inline nothrow bool IsEmpty() const
 85         {
 86             return locations.IsEmpty();
 87         }
 88         public nothrow void RemoveLocation(Location* location)
 89         {
 90             List<Location*>.Iterator it = Find(locations.Begin()locations.End()location);
 91             if (it != locations.End())
 92             {
 93                 locations.Remove(it);
 94             }
 95         }
 96         public nothrow void RemoveRegisterLocations()
 97         {
 98             List<Location*> newLocations;
 99             for (Location* location : locations)
100             {
101                 if (!(location is Register*))
102                 {
103                     newLocations.Add(location);
104                 }
105             }
106             Swap(locationsnewLocations);
107         }
108         public Value* variable;
109         public List<Location*> locations;
110     }
111 
112     public class AddressDescriptors
113     {
114         public default nothrow AddressDescriptors();
115         suppress AddressDescriptors(const AddressDescriptors&);
116         suppress void operator=(const AddressDescriptors&);
117         suppress AddressDescriptors(AddressDescriptors&&);
118         suppress void operator=(AddressDescriptors&&);
119         public AddressDescriptor* GetAddressDescriptor(Value* value)
120         {
121             HashMap<Value*AddressDescriptor*>.ConstIterator it = addressDescriptorMap.CFind(value);
122             if (it != addressDescriptorMap.CEnd())
123             {
124                 return it->second;
125             }
126             AddressDescriptor* addressDescriptor = new AddressDescriptor(value);
127             addressDescriptors.Add(UniquePtr<AddressDescriptor>(addressDescriptor));
128             addressDescriptorMap[value] = addressDescriptor;
129             return addressDescriptor;
130         }
131         public void RemoveRegisterFromAllBut(Value* xRegister* rx)
132         {
133             for (const UniquePtr<AddressDescriptor>& addressDescriptor : addressDescriptors)
134             {
135                 if (addressDescriptor->variable != x)
136                 {
137                     addressDescriptor->RemoveLocation(rx);
138                 }
139             }
140         }
141         public nothrow void RemoveRegister(Register* reg)
142         {
143             for (const UniquePtr<AddressDescriptor>& addressDescriptor : addressDescriptors)
144             {
145                 addressDescriptor->RemoveLocation(reg);
146             }
147         }
148         public nothrow void RemoveRegisterLocations()
149         {
150             for (const UniquePtr<AddressDescriptor>& addressDescriptor : addressDescriptors)
151             {
152                 addressDescriptor->RemoveRegisterLocations();
153             }
154         }
155         public void DebugPrint(CodeFormatter& formatter)
156         {
157             formatter << "address descriptors: { " << endl();
158             formatter.IncIndent();
159             for (const UniquePtr<AddressDescriptor>& descriptor : addressDescriptors)
160             {
161                 descriptor->DebugPrint(formatter);
162                 formatter << endl();
163             }
164             formatter.DecIndent();
165             formatter << "}" << endl();
166         }
167         private List<UniquePtr<AddressDescriptor>> addressDescriptors;
168         private HashMap<Value*AddressDescriptor*> addressDescriptorMap;
169     }
170 }