OLD | NEW |
1 //===-- ValueEnumerator.cpp - Number values and types for bitcode writer --===// | 1 //===-- NaClValueEnumerator.cpp ------------------------------------------===// |
| 2 // Number values and types for bitcode writer |
2 // | 3 // |
3 // The LLVM Compiler Infrastructure | 4 // The LLVM Compiler Infrastructure |
4 // | 5 // |
5 // This file is distributed under the University of Illinois Open Source | 6 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 7 // License. See LICENSE.TXT for details. |
7 // | 8 // |
8 //===----------------------------------------------------------------------===// | 9 //===----------------------------------------------------------------------===// |
9 // | 10 // |
10 // This file implements the ValueEnumerator class. | 11 // This file implements the NaClValueEnumerator class. |
11 // | 12 // |
12 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
13 | 14 |
14 #include "ValueEnumerator.h" | 15 #include "NaClValueEnumerator.h" |
15 #include "llvm/ADT/STLExtras.h" | 16 #include "llvm/ADT/STLExtras.h" |
16 #include "llvm/ADT/SmallPtrSet.h" | 17 #include "llvm/ADT/SmallPtrSet.h" |
17 #include "llvm/IR/Constants.h" | 18 #include "llvm/IR/Constants.h" |
18 #include "llvm/IR/DerivedTypes.h" | 19 #include "llvm/IR/DerivedTypes.h" |
19 #include "llvm/IR/Instructions.h" | 20 #include "llvm/IR/Instructions.h" |
20 #include "llvm/IR/Module.h" | 21 #include "llvm/IR/Module.h" |
21 #include "llvm/IR/ValueSymbolTable.h" | 22 #include "llvm/IR/ValueSymbolTable.h" |
22 #include "llvm/Support/Debug.h" | 23 #include "llvm/Support/Debug.h" |
23 #include "llvm/Support/raw_ostream.h" | 24 #include "llvm/Support/raw_ostream.h" |
24 #include <algorithm> | 25 #include <algorithm> |
25 using namespace llvm; | 26 using namespace llvm; |
26 | 27 |
27 static bool isIntOrIntVectorValue(const std::pair<const Value*, unsigned> &V) { | 28 static bool isIntOrIntVectorValue(const std::pair<const Value*, unsigned> &V) { |
28 return V.first->getType()->isIntOrIntVectorTy(); | 29 return V.first->getType()->isIntOrIntVectorTy(); |
29 } | 30 } |
30 | 31 |
31 /// ValueEnumerator - Enumerate module-level information. | 32 /// NaClValueEnumerator - Enumerate module-level information. |
32 ValueEnumerator::ValueEnumerator(const Module *M) { | 33 NaClValueEnumerator::NaClValueEnumerator(const Module *M) { |
33 // Enumerate the global variables. | 34 // Enumerate the global variables. |
34 for (Module::const_global_iterator I = M->global_begin(), | 35 for (Module::const_global_iterator I = M->global_begin(), |
35 E = M->global_end(); I != E; ++I) | 36 E = M->global_end(); I != E; ++I) |
36 EnumerateValue(I); | 37 EnumerateValue(I); |
37 | 38 |
38 // Enumerate the functions. | 39 // Enumerate the functions. |
39 for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) { | 40 for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) { |
40 EnumerateValue(I); | 41 EnumerateValue(I); |
41 EnumerateAttributes(cast<Function>(I)->getAttributes()); | 42 EnumerateAttributes(cast<Function>(I)->getAttributes()); |
42 } | 43 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 if (Scope) EnumerateMetadata(Scope); | 103 if (Scope) EnumerateMetadata(Scope); |
103 if (IA) EnumerateMetadata(IA); | 104 if (IA) EnumerateMetadata(IA); |
104 } | 105 } |
105 } | 106 } |
106 } | 107 } |
107 | 108 |
108 // Optimize constant ordering. | 109 // Optimize constant ordering. |
109 OptimizeConstants(FirstConstant, Values.size()); | 110 OptimizeConstants(FirstConstant, Values.size()); |
110 } | 111 } |
111 | 112 |
112 unsigned ValueEnumerator::getInstructionID(const Instruction *Inst) const { | 113 unsigned NaClValueEnumerator::getInstructionID(const Instruction *Inst) const { |
113 InstructionMapType::const_iterator I = InstructionMap.find(Inst); | 114 InstructionMapType::const_iterator I = InstructionMap.find(Inst); |
114 assert(I != InstructionMap.end() && "Instruction is not mapped!"); | 115 assert(I != InstructionMap.end() && "Instruction is not mapped!"); |
115 return I->second; | 116 return I->second; |
116 } | 117 } |
117 | 118 |
118 void ValueEnumerator::setInstructionID(const Instruction *I) { | 119 void NaClValueEnumerator::setInstructionID(const Instruction *I) { |
119 InstructionMap[I] = InstructionCount++; | 120 InstructionMap[I] = InstructionCount++; |
120 } | 121 } |
121 | 122 |
122 unsigned ValueEnumerator::getValueID(const Value *V) const { | 123 unsigned NaClValueEnumerator::getValueID(const Value *V) const { |
123 if (isa<MDNode>(V) || isa<MDString>(V)) { | 124 if (isa<MDNode>(V) || isa<MDString>(V)) { |
124 ValueMapType::const_iterator I = MDValueMap.find(V); | 125 ValueMapType::const_iterator I = MDValueMap.find(V); |
125 assert(I != MDValueMap.end() && "Value not in slotcalculator!"); | 126 assert(I != MDValueMap.end() && "Value not in slotcalculator!"); |
126 return I->second-1; | 127 return I->second-1; |
127 } | 128 } |
128 | 129 |
129 ValueMapType::const_iterator I = ValueMap.find(V); | 130 ValueMapType::const_iterator I = ValueMap.find(V); |
130 assert(I != ValueMap.end() && "Value not in slotcalculator!"); | 131 assert(I != ValueMap.end() && "Value not in slotcalculator!"); |
131 return I->second-1; | 132 return I->second-1; |
132 } | 133 } |
133 | 134 |
134 void ValueEnumerator::dump() const { | 135 void NaClValueEnumerator::dump() const { |
135 print(dbgs(), ValueMap, "Default"); | 136 print(dbgs(), ValueMap, "Default"); |
136 dbgs() << '\n'; | 137 dbgs() << '\n'; |
137 print(dbgs(), MDValueMap, "MetaData"); | 138 print(dbgs(), MDValueMap, "MetaData"); |
138 dbgs() << '\n'; | 139 dbgs() << '\n'; |
139 } | 140 } |
140 | 141 |
141 void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map, | 142 void NaClValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map, |
142 const char *Name) const { | 143 const char *Name) const { |
143 | 144 |
144 OS << "Map Name: " << Name << "\n"; | 145 OS << "Map Name: " << Name << "\n"; |
145 OS << "Size: " << Map.size() << "\n"; | 146 OS << "Size: " << Map.size() << "\n"; |
146 for (ValueMapType::const_iterator I = Map.begin(), | 147 for (ValueMapType::const_iterator I = Map.begin(), |
147 E = Map.end(); I != E; ++I) { | 148 E = Map.end(); I != E; ++I) { |
148 | 149 |
149 const Value *V = I->first; | 150 const Value *V = I->first; |
150 if (V->hasName()) | 151 if (V->hasName()) |
151 OS << "Value: " << V->getName(); | 152 OS << "Value: " << V->getName(); |
(...skipping 12 matching lines...) Expand all Loading... |
164 OS << " [null]"; | 165 OS << " [null]"; |
165 | 166 |
166 } | 167 } |
167 OS << "\n\n"; | 168 OS << "\n\n"; |
168 } | 169 } |
169 } | 170 } |
170 | 171 |
171 // Optimize constant ordering. | 172 // Optimize constant ordering. |
172 namespace { | 173 namespace { |
173 struct CstSortPredicate { | 174 struct CstSortPredicate { |
174 ValueEnumerator &VE; | 175 NaClValueEnumerator &VE; |
175 explicit CstSortPredicate(ValueEnumerator &ve) : VE(ve) {} | 176 explicit CstSortPredicate(NaClValueEnumerator &ve) : VE(ve) {} |
176 bool operator()(const std::pair<const Value*, unsigned> &LHS, | 177 bool operator()(const std::pair<const Value*, unsigned> &LHS, |
177 const std::pair<const Value*, unsigned> &RHS) { | 178 const std::pair<const Value*, unsigned> &RHS) { |
178 // Sort by plane. | 179 // Sort by plane. |
179 if (LHS.first->getType() != RHS.first->getType()) | 180 if (LHS.first->getType() != RHS.first->getType()) |
180 return VE.getTypeID(LHS.first->getType()) < | 181 return VE.getTypeID(LHS.first->getType()) < |
181 VE.getTypeID(RHS.first->getType()); | 182 VE.getTypeID(RHS.first->getType()); |
182 // Then by frequency. | 183 // Then by frequency. |
183 return LHS.second > RHS.second; | 184 return LHS.second > RHS.second; |
184 } | 185 } |
185 }; | 186 }; |
186 } | 187 } |
187 | 188 |
188 /// OptimizeConstants - Reorder constant pool for denser encoding. | 189 /// OptimizeConstants - Reorder constant pool for denser encoding. |
189 void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) { | 190 void NaClValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd)
{ |
190 if (CstStart == CstEnd || CstStart+1 == CstEnd) return; | 191 if (CstStart == CstEnd || CstStart+1 == CstEnd) return; |
191 | 192 |
192 CstSortPredicate P(*this); | 193 CstSortPredicate P(*this); |
193 std::stable_sort(Values.begin()+CstStart, Values.begin()+CstEnd, P); | 194 std::stable_sort(Values.begin()+CstStart, Values.begin()+CstEnd, P); |
194 | 195 |
195 // Ensure that integer and vector of integer constants are at the start of the | 196 // Ensure that integer and vector of integer constants are at the start of the |
196 // constant pool. This is important so that GEP structure indices come before | 197 // constant pool. This is important so that GEP structure indices come before |
197 // gep constant exprs. | 198 // gep constant exprs. |
198 std::partition(Values.begin()+CstStart, Values.begin()+CstEnd, | 199 std::partition(Values.begin()+CstStart, Values.begin()+CstEnd, |
199 isIntOrIntVectorValue); | 200 isIntOrIntVectorValue); |
200 | 201 |
201 // Rebuild the modified portion of ValueMap. | 202 // Rebuild the modified portion of ValueMap. |
202 for (; CstStart != CstEnd; ++CstStart) | 203 for (; CstStart != CstEnd; ++CstStart) |
203 ValueMap[Values[CstStart].first] = CstStart+1; | 204 ValueMap[Values[CstStart].first] = CstStart+1; |
204 } | 205 } |
205 | 206 |
206 | 207 |
207 /// EnumerateValueSymbolTable - Insert all of the values in the specified symbol | 208 /// EnumerateValueSymbolTable - Insert all of the values in the specified symbol |
208 /// table into the values table. | 209 /// table into the values table. |
209 void ValueEnumerator::EnumerateValueSymbolTable(const ValueSymbolTable &VST) { | 210 void NaClValueEnumerator::EnumerateValueSymbolTable(const ValueSymbolTable &VST)
{ |
210 for (ValueSymbolTable::const_iterator VI = VST.begin(), VE = VST.end(); | 211 for (ValueSymbolTable::const_iterator VI = VST.begin(), VE = VST.end(); |
211 VI != VE; ++VI) | 212 VI != VE; ++VI) |
212 EnumerateValue(VI->getValue()); | 213 EnumerateValue(VI->getValue()); |
213 } | 214 } |
214 | 215 |
215 /// EnumerateNamedMetadata - Insert all of the values referenced by | 216 /// EnumerateNamedMetadata - Insert all of the values referenced by |
216 /// named metadata in the specified module. | 217 /// named metadata in the specified module. |
217 void ValueEnumerator::EnumerateNamedMetadata(const Module *M) { | 218 void NaClValueEnumerator::EnumerateNamedMetadata(const Module *M) { |
218 for (Module::const_named_metadata_iterator I = M->named_metadata_begin(), | 219 for (Module::const_named_metadata_iterator I = M->named_metadata_begin(), |
219 E = M->named_metadata_end(); I != E; ++I) | 220 E = M->named_metadata_end(); I != E; ++I) |
220 EnumerateNamedMDNode(I); | 221 EnumerateNamedMDNode(I); |
221 } | 222 } |
222 | 223 |
223 void ValueEnumerator::EnumerateNamedMDNode(const NamedMDNode *MD) { | 224 void NaClValueEnumerator::EnumerateNamedMDNode(const NamedMDNode *MD) { |
224 for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i) | 225 for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i) |
225 EnumerateMetadata(MD->getOperand(i)); | 226 EnumerateMetadata(MD->getOperand(i)); |
226 } | 227 } |
227 | 228 |
228 /// EnumerateMDNodeOperands - Enumerate all non-function-local values | 229 /// EnumerateMDNodeOperands - Enumerate all non-function-local values |
229 /// and types referenced by the given MDNode. | 230 /// and types referenced by the given MDNode. |
230 void ValueEnumerator::EnumerateMDNodeOperands(const MDNode *N) { | 231 void NaClValueEnumerator::EnumerateMDNodeOperands(const MDNode *N) { |
231 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { | 232 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { |
232 if (Value *V = N->getOperand(i)) { | 233 if (Value *V = N->getOperand(i)) { |
233 if (isa<MDNode>(V) || isa<MDString>(V)) | 234 if (isa<MDNode>(V) || isa<MDString>(V)) |
234 EnumerateMetadata(V); | 235 EnumerateMetadata(V); |
235 else if (!isa<Instruction>(V) && !isa<Argument>(V)) | 236 else if (!isa<Instruction>(V) && !isa<Argument>(V)) |
236 EnumerateValue(V); | 237 EnumerateValue(V); |
237 } else | 238 } else |
238 EnumerateType(Type::getVoidTy(N->getContext())); | 239 EnumerateType(Type::getVoidTy(N->getContext())); |
239 } | 240 } |
240 } | 241 } |
241 | 242 |
242 void ValueEnumerator::EnumerateMetadata(const Value *MD) { | 243 void NaClValueEnumerator::EnumerateMetadata(const Value *MD) { |
243 assert((isa<MDNode>(MD) || isa<MDString>(MD)) && "Invalid metadata kind"); | 244 assert((isa<MDNode>(MD) || isa<MDString>(MD)) && "Invalid metadata kind"); |
244 | 245 |
245 // Enumerate the type of this value. | 246 // Enumerate the type of this value. |
246 EnumerateType(MD->getType()); | 247 EnumerateType(MD->getType()); |
247 | 248 |
248 const MDNode *N = dyn_cast<MDNode>(MD); | 249 const MDNode *N = dyn_cast<MDNode>(MD); |
249 | 250 |
250 // In the module-level pass, skip function-local nodes themselves, but | 251 // In the module-level pass, skip function-local nodes themselves, but |
251 // do walk their operands. | 252 // do walk their operands. |
252 if (N && N->isFunctionLocal() && N->getFunction()) { | 253 if (N && N->isFunctionLocal() && N->getFunction()) { |
(...skipping 11 matching lines...) Expand all Loading... |
264 MDValues.push_back(std::make_pair(MD, 1U)); | 265 MDValues.push_back(std::make_pair(MD, 1U)); |
265 MDValueID = MDValues.size(); | 266 MDValueID = MDValues.size(); |
266 | 267 |
267 // Enumerate all non-function-local operands. | 268 // Enumerate all non-function-local operands. |
268 if (N) | 269 if (N) |
269 EnumerateMDNodeOperands(N); | 270 EnumerateMDNodeOperands(N); |
270 } | 271 } |
271 | 272 |
272 /// EnumerateFunctionLocalMetadataa - Incorporate function-local metadata | 273 /// EnumerateFunctionLocalMetadataa - Incorporate function-local metadata |
273 /// information reachable from the given MDNode. | 274 /// information reachable from the given MDNode. |
274 void ValueEnumerator::EnumerateFunctionLocalMetadata(const MDNode *N) { | 275 void NaClValueEnumerator::EnumerateFunctionLocalMetadata(const MDNode *N) { |
275 assert(N->isFunctionLocal() && N->getFunction() && | 276 assert(N->isFunctionLocal() && N->getFunction() && |
276 "EnumerateFunctionLocalMetadata called on non-function-local mdnode!"); | 277 "EnumerateFunctionLocalMetadata called on non-function-local mdnode!"); |
277 | 278 |
278 // Enumerate the type of this value. | 279 // Enumerate the type of this value. |
279 EnumerateType(N->getType()); | 280 EnumerateType(N->getType()); |
280 | 281 |
281 // Check to see if it's already in! | 282 // Check to see if it's already in! |
282 unsigned &MDValueID = MDValueMap[N]; | 283 unsigned &MDValueID = MDValueMap[N]; |
283 if (MDValueID) { | 284 if (MDValueID) { |
284 // Increment use count. | 285 // Increment use count. |
(...skipping 11 matching lines...) Expand all Loading... |
296 if (O->isFunctionLocal() && O->getFunction()) | 297 if (O->isFunctionLocal() && O->getFunction()) |
297 EnumerateFunctionLocalMetadata(O); | 298 EnumerateFunctionLocalMetadata(O); |
298 } else if (isa<Instruction>(V) || isa<Argument>(V)) | 299 } else if (isa<Instruction>(V) || isa<Argument>(V)) |
299 EnumerateValue(V); | 300 EnumerateValue(V); |
300 } | 301 } |
301 | 302 |
302 // Also, collect all function-local MDNodes for easy access. | 303 // Also, collect all function-local MDNodes for easy access. |
303 FunctionLocalMDs.push_back(N); | 304 FunctionLocalMDs.push_back(N); |
304 } | 305 } |
305 | 306 |
306 void ValueEnumerator::EnumerateValue(const Value *V) { | 307 void NaClValueEnumerator::EnumerateValue(const Value *V) { |
307 assert(!V->getType()->isVoidTy() && "Can't insert void values!"); | 308 assert(!V->getType()->isVoidTy() && "Can't insert void values!"); |
308 assert(!isa<MDNode>(V) && !isa<MDString>(V) && | 309 assert(!isa<MDNode>(V) && !isa<MDString>(V) && |
309 "EnumerateValue doesn't handle Metadata!"); | 310 "EnumerateValue doesn't handle Metadata!"); |
310 | 311 |
311 // Check to see if it's already in! | 312 // Check to see if it's already in! |
312 unsigned &ValueID = ValueMap[V]; | 313 unsigned &ValueID = ValueMap[V]; |
313 if (ValueID) { | 314 if (ValueID) { |
314 // Increment use count. | 315 // Increment use count. |
315 Values[ValueID-1].second++; | 316 Values[ValueID-1].second++; |
316 return; | 317 return; |
(...skipping 26 matching lines...) Expand all Loading... |
343 return; | 344 return; |
344 } | 345 } |
345 } | 346 } |
346 | 347 |
347 // Add the value. | 348 // Add the value. |
348 Values.push_back(std::make_pair(V, 1U)); | 349 Values.push_back(std::make_pair(V, 1U)); |
349 ValueID = Values.size(); | 350 ValueID = Values.size(); |
350 } | 351 } |
351 | 352 |
352 | 353 |
353 void ValueEnumerator::EnumerateType(Type *Ty) { | 354 void NaClValueEnumerator::EnumerateType(Type *Ty) { |
354 unsigned *TypeID = &TypeMap[Ty]; | 355 unsigned *TypeID = &TypeMap[Ty]; |
355 | 356 |
356 // We've already seen this type. | 357 // We've already seen this type. |
357 if (*TypeID) | 358 if (*TypeID) |
358 return; | 359 return; |
359 | 360 |
360 // If it is a non-anonymous struct, mark the type as being visited so that we | 361 // If it is a non-anonymous struct, mark the type as being visited so that we |
361 // don't recursively visit it. This is safe because we allow forward | 362 // don't recursively visit it. This is safe because we allow forward |
362 // references of these in the bitcode reader. | 363 // references of these in the bitcode reader. |
363 if (StructType *STy = dyn_cast<StructType>(Ty)) | 364 if (StructType *STy = dyn_cast<StructType>(Ty)) |
(...skipping 18 matching lines...) Expand all Loading... |
382 return; | 383 return; |
383 | 384 |
384 // Add this type now that its contents are all happily enumerated. | 385 // Add this type now that its contents are all happily enumerated. |
385 Types.push_back(Ty); | 386 Types.push_back(Ty); |
386 | 387 |
387 *TypeID = Types.size(); | 388 *TypeID = Types.size(); |
388 } | 389 } |
389 | 390 |
390 // Enumerate the types for the specified value. If the value is a constant, | 391 // Enumerate the types for the specified value. If the value is a constant, |
391 // walk through it, enumerating the types of the constant. | 392 // walk through it, enumerating the types of the constant. |
392 void ValueEnumerator::EnumerateOperandType(const Value *V) { | 393 void NaClValueEnumerator::EnumerateOperandType(const Value *V) { |
393 EnumerateType(V->getType()); | 394 EnumerateType(V->getType()); |
394 | 395 |
395 if (const Constant *C = dyn_cast<Constant>(V)) { | 396 if (const Constant *C = dyn_cast<Constant>(V)) { |
396 // If this constant is already enumerated, ignore it, we know its type must | 397 // If this constant is already enumerated, ignore it, we know its type must |
397 // be enumerated. | 398 // be enumerated. |
398 if (ValueMap.count(V)) return; | 399 if (ValueMap.count(V)) return; |
399 | 400 |
400 // This constant may have operands, make sure to enumerate the types in | 401 // This constant may have operands, make sure to enumerate the types in |
401 // them. | 402 // them. |
402 for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) { | 403 for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) { |
403 const Value *Op = C->getOperand(i); | 404 const Value *Op = C->getOperand(i); |
404 | 405 |
405 // Don't enumerate basic blocks here, this happens as operands to | 406 // Don't enumerate basic blocks here, this happens as operands to |
406 // blockaddress. | 407 // blockaddress. |
407 if (isa<BasicBlock>(Op)) continue; | 408 if (isa<BasicBlock>(Op)) continue; |
408 | 409 |
409 EnumerateOperandType(Op); | 410 EnumerateOperandType(Op); |
410 } | 411 } |
411 | 412 |
412 if (const MDNode *N = dyn_cast<MDNode>(V)) { | 413 if (const MDNode *N = dyn_cast<MDNode>(V)) { |
413 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) | 414 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) |
414 if (Value *Elem = N->getOperand(i)) | 415 if (Value *Elem = N->getOperand(i)) |
415 EnumerateOperandType(Elem); | 416 EnumerateOperandType(Elem); |
416 } | 417 } |
417 } else if (isa<MDString>(V) || isa<MDNode>(V)) | 418 } else if (isa<MDString>(V) || isa<MDNode>(V)) |
418 EnumerateMetadata(V); | 419 EnumerateMetadata(V); |
419 } | 420 } |
420 | 421 |
421 void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) { | 422 void NaClValueEnumerator::EnumerateAttributes(AttributeSet PAL) { |
422 if (PAL.isEmpty()) return; // null is always 0. | 423 if (PAL.isEmpty()) return; // null is always 0. |
423 | 424 |
424 // Do a lookup. | 425 // Do a lookup. |
425 unsigned &Entry = AttributeMap[PAL]; | 426 unsigned &Entry = AttributeMap[PAL]; |
426 if (Entry == 0) { | 427 if (Entry == 0) { |
427 // Never saw this before, add it. | 428 // Never saw this before, add it. |
428 Attribute.push_back(PAL); | 429 Attribute.push_back(PAL); |
429 Entry = Attribute.size(); | 430 Entry = Attribute.size(); |
430 } | 431 } |
431 | 432 |
432 // Do lookups for all attribute groups. | 433 // Do lookups for all attribute groups. |
433 for (unsigned i = 0, e = PAL.getNumSlots(); i != e; ++i) { | 434 for (unsigned i = 0, e = PAL.getNumSlots(); i != e; ++i) { |
434 AttributeSet AS = PAL.getSlotAttributes(i); | 435 AttributeSet AS = PAL.getSlotAttributes(i); |
435 unsigned &Entry = AttributeGroupMap[AS]; | 436 unsigned &Entry = AttributeGroupMap[AS]; |
436 if (Entry == 0) { | 437 if (Entry == 0) { |
437 AttributeGroups.push_back(AS); | 438 AttributeGroups.push_back(AS); |
438 Entry = AttributeGroups.size(); | 439 Entry = AttributeGroups.size(); |
439 } | 440 } |
440 } | 441 } |
441 } | 442 } |
442 | 443 |
443 void ValueEnumerator::incorporateFunction(const Function &F) { | 444 void NaClValueEnumerator::incorporateFunction(const Function &F) { |
444 InstructionCount = 0; | 445 InstructionCount = 0; |
445 NumModuleValues = Values.size(); | 446 NumModuleValues = Values.size(); |
446 NumModuleMDValues = MDValues.size(); | 447 NumModuleMDValues = MDValues.size(); |
447 | 448 |
448 // Adding function arguments to the value table. | 449 // Adding function arguments to the value table. |
449 for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); | 450 for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); |
450 I != E; ++I) | 451 I != E; ++I) |
451 EnumerateValue(I); | 452 EnumerateValue(I); |
452 | 453 |
453 FirstFuncConstantID = Values.size(); | 454 FirstFuncConstantID = Values.size(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
497 if (!I->getType()->isVoidTy()) | 498 if (!I->getType()->isVoidTy()) |
498 EnumerateValue(I); | 499 EnumerateValue(I); |
499 } | 500 } |
500 } | 501 } |
501 | 502 |
502 // Add all of the function-local metadata. | 503 // Add all of the function-local metadata. |
503 for (unsigned i = 0, e = FnLocalMDVector.size(); i != e; ++i) | 504 for (unsigned i = 0, e = FnLocalMDVector.size(); i != e; ++i) |
504 EnumerateFunctionLocalMetadata(FnLocalMDVector[i]); | 505 EnumerateFunctionLocalMetadata(FnLocalMDVector[i]); |
505 } | 506 } |
506 | 507 |
507 void ValueEnumerator::purgeFunction() { | 508 void NaClValueEnumerator::purgeFunction() { |
508 /// Remove purged values from the ValueMap. | 509 /// Remove purged values from the ValueMap. |
509 for (unsigned i = NumModuleValues, e = Values.size(); i != e; ++i) | 510 for (unsigned i = NumModuleValues, e = Values.size(); i != e; ++i) |
510 ValueMap.erase(Values[i].first); | 511 ValueMap.erase(Values[i].first); |
511 for (unsigned i = NumModuleMDValues, e = MDValues.size(); i != e; ++i) | 512 for (unsigned i = NumModuleMDValues, e = MDValues.size(); i != e; ++i) |
512 MDValueMap.erase(MDValues[i].first); | 513 MDValueMap.erase(MDValues[i].first); |
513 for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i) | 514 for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i) |
514 ValueMap.erase(BasicBlocks[i]); | 515 ValueMap.erase(BasicBlocks[i]); |
515 | 516 |
516 Values.resize(NumModuleValues); | 517 Values.resize(NumModuleValues); |
517 MDValues.resize(NumModuleMDValues); | 518 MDValues.resize(NumModuleMDValues); |
518 BasicBlocks.clear(); | 519 BasicBlocks.clear(); |
519 FunctionLocalMDs.clear(); | 520 FunctionLocalMDs.clear(); |
520 } | 521 } |
521 | 522 |
522 static void IncorporateFunctionInfoGlobalBBIDs(const Function *F, | 523 static void IncorporateFunctionInfoGlobalBBIDs(const Function *F, |
523 DenseMap<const BasicBlock*, unsigned> &IDMap) { | 524 DenseMap<const BasicBlock*, unsigned> &IDMap) { |
524 unsigned Counter = 0; | 525 unsigned Counter = 0; |
525 for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB) | 526 for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB) |
526 IDMap[BB] = ++Counter; | 527 IDMap[BB] = ++Counter; |
527 } | 528 } |
528 | 529 |
529 /// getGlobalBasicBlockID - This returns the function-specific ID for the | 530 /// getGlobalBasicBlockID - This returns the function-specific ID for the |
530 /// specified basic block. This is relatively expensive information, so it | 531 /// specified basic block. This is relatively expensive information, so it |
531 /// should only be used by rare constructs such as address-of-label. | 532 /// should only be used by rare constructs such as address-of-label. |
532 unsigned ValueEnumerator::getGlobalBasicBlockID(const BasicBlock *BB) const { | 533 unsigned NaClValueEnumerator::getGlobalBasicBlockID(const BasicBlock *BB) const
{ |
533 unsigned &Idx = GlobalBasicBlockIDs[BB]; | 534 unsigned &Idx = GlobalBasicBlockIDs[BB]; |
534 if (Idx != 0) | 535 if (Idx != 0) |
535 return Idx-1; | 536 return Idx-1; |
536 | 537 |
537 IncorporateFunctionInfoGlobalBBIDs(BB->getParent(), GlobalBasicBlockIDs); | 538 IncorporateFunctionInfoGlobalBBIDs(BB->getParent(), GlobalBasicBlockIDs); |
538 return getGlobalBasicBlockID(BB); | 539 return getGlobalBasicBlockID(BB); |
539 } | 540 } |
540 | 541 |
OLD | NEW |