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(locations, newLocations);
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* x, Register* 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 }