| 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 |