Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- BitcodeReader.cpp - Internal BitcodeReader implementation ----------===// | 1 //===- NaClBitcodeReader.cpp ----------------------------------------------===// |
| 2 // Internal NaClBitcodeReader implementation | |
| 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 #include "llvm/Bitcode/ReaderWriter.h" | 11 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h" |
| 11 #include "BitcodeReader.h" | 12 #include "NaClBitcodeReader.h" |
| 12 #include "llvm/ADT/SmallString.h" | 13 #include "llvm/ADT/SmallString.h" |
| 13 #include "llvm/ADT/SmallVector.h" | 14 #include "llvm/ADT/SmallVector.h" |
| 14 #include "llvm/AutoUpgrade.h" | 15 #include "llvm/AutoUpgrade.h" |
| 15 #include "llvm/IR/Constants.h" | 16 #include "llvm/IR/Constants.h" |
| 16 #include "llvm/IR/DerivedTypes.h" | 17 #include "llvm/IR/DerivedTypes.h" |
| 17 #include "llvm/IR/InlineAsm.h" | 18 #include "llvm/IR/InlineAsm.h" |
| 18 #include "llvm/IR/IntrinsicInst.h" | 19 #include "llvm/IR/IntrinsicInst.h" |
| 19 #include "llvm/IR/Module.h" | 20 #include "llvm/IR/Module.h" |
| 20 #include "llvm/IR/OperandTraits.h" | 21 #include "llvm/IR/OperandTraits.h" |
| 21 #include "llvm/IR/Operator.h" | 22 #include "llvm/IR/Operator.h" |
| 22 #include "llvm/Support/DataStream.h" | 23 #include "llvm/Support/DataStream.h" |
| 23 #include "llvm/Support/MathExtras.h" | 24 #include "llvm/Support/MathExtras.h" |
| 24 #include "llvm/Support/MemoryBuffer.h" | 25 #include "llvm/Support/MemoryBuffer.h" |
| 25 using namespace llvm; | 26 using namespace llvm; |
| 26 | 27 |
| 27 enum { | 28 enum { |
| 28 SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex | 29 SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex |
| 29 }; | 30 }; |
| 30 | 31 |
| 31 void BitcodeReader::materializeForwardReferencedFunctions() { | 32 void NaClBitcodeReader::materializeForwardReferencedFunctions() { |
| 32 while (!BlockAddrFwdRefs.empty()) { | 33 while (!BlockAddrFwdRefs.empty()) { |
| 33 Function *F = BlockAddrFwdRefs.begin()->first; | 34 Function *F = BlockAddrFwdRefs.begin()->first; |
| 34 F->Materialize(); | 35 F->Materialize(); |
| 35 } | 36 } |
| 36 } | 37 } |
| 37 | 38 |
| 38 void BitcodeReader::FreeState() { | 39 void NaClBitcodeReader::FreeState() { |
| 39 if (BufferOwned) | 40 if (BufferOwned) |
| 40 delete Buffer; | 41 delete Buffer; |
| 41 Buffer = 0; | 42 Buffer = 0; |
| 42 std::vector<Type*>().swap(TypeList); | 43 std::vector<Type*>().swap(TypeList); |
| 43 ValueList.clear(); | 44 ValueList.clear(); |
| 44 MDValueList.clear(); | 45 MDValueList.clear(); |
| 45 | 46 |
| 46 std::vector<AttributeSet>().swap(MAttributes); | 47 std::vector<AttributeSet>().swap(MAttributes); |
| 47 std::vector<BasicBlock*>().swap(FunctionBBs); | 48 std::vector<BasicBlock*>().swap(FunctionBBs); |
| 48 std::vector<Function*>().swap(FunctionsWithBodies); | 49 std::vector<Function*>().swap(FunctionsWithBodies); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 219 } | 220 } |
| 220 | 221 |
| 221 // FIXME: can we inherit this from ConstantExpr? | 222 // FIXME: can we inherit this from ConstantExpr? |
| 222 template <> | 223 template <> |
| 223 struct OperandTraits<ConstantPlaceHolder> : | 224 struct OperandTraits<ConstantPlaceHolder> : |
| 224 public FixedNumOperandTraits<ConstantPlaceHolder, 1> { | 225 public FixedNumOperandTraits<ConstantPlaceHolder, 1> { |
| 225 }; | 226 }; |
| 226 } | 227 } |
| 227 | 228 |
| 228 | 229 |
| 229 void BitcodeReaderValueList::AssignValue(Value *V, unsigned Idx) { | 230 void NaClBitcodeReaderValueList::AssignValue(Value *V, unsigned Idx) { |
| 230 if (Idx == size()) { | 231 if (Idx == size()) { |
| 231 push_back(V); | 232 push_back(V); |
| 232 return; | 233 return; |
| 233 } | 234 } |
| 234 | 235 |
| 235 if (Idx >= size()) | 236 if (Idx >= size()) |
| 236 resize(Idx+1); | 237 resize(Idx+1); |
| 237 | 238 |
| 238 WeakVH &OldV = ValuePtrs[Idx]; | 239 WeakVH &OldV = ValuePtrs[Idx]; |
| 239 if (OldV == 0) { | 240 if (OldV == 0) { |
| 240 OldV = V; | 241 OldV = V; |
| 241 return; | 242 return; |
| 242 } | 243 } |
| 243 | 244 |
| 244 // Handle constants and non-constants (e.g. instrs) differently for | 245 // Handle constants and non-constants (e.g. instrs) differently for |
| 245 // efficiency. | 246 // efficiency. |
| 246 if (Constant *PHC = dyn_cast<Constant>(&*OldV)) { | 247 if (Constant *PHC = dyn_cast<Constant>(&*OldV)) { |
| 247 ResolveConstants.push_back(std::make_pair(PHC, Idx)); | 248 ResolveConstants.push_back(std::make_pair(PHC, Idx)); |
| 248 OldV = V; | 249 OldV = V; |
| 249 } else { | 250 } else { |
| 250 // If there was a forward reference to this value, replace it. | 251 // If there was a forward reference to this value, replace it. |
| 251 Value *PrevVal = OldV; | 252 Value *PrevVal = OldV; |
| 252 OldV->replaceAllUsesWith(V); | 253 OldV->replaceAllUsesWith(V); |
| 253 delete PrevVal; | 254 delete PrevVal; |
| 254 } | 255 } |
| 255 } | 256 } |
| 256 | 257 |
| 257 | 258 |
| 258 Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx, | 259 Constant *NaClBitcodeReaderValueList::getConstantFwdRef(unsigned Idx, |
| 259 Type *Ty) { | 260 Type *Ty) { |
| 260 if (Idx >= size()) | 261 if (Idx >= size()) |
| 261 resize(Idx + 1); | 262 resize(Idx + 1); |
| 262 | 263 |
| 263 if (Value *V = ValuePtrs[Idx]) { | 264 if (Value *V = ValuePtrs[Idx]) { |
| 264 assert(Ty == V->getType() && "Type mismatch in constant table!"); | 265 assert(Ty == V->getType() && "Type mismatch in constant table!"); |
| 265 return cast<Constant>(V); | 266 return cast<Constant>(V); |
| 266 } | 267 } |
| 267 | 268 |
| 268 // Create and return a placeholder, which will later be RAUW'd. | 269 // Create and return a placeholder, which will later be RAUW'd. |
| 269 Constant *C = new ConstantPlaceHolder(Ty, Context); | 270 Constant *C = new ConstantPlaceHolder(Ty, Context); |
| 270 ValuePtrs[Idx] = C; | 271 ValuePtrs[Idx] = C; |
| 271 return C; | 272 return C; |
| 272 } | 273 } |
| 273 | 274 |
| 274 Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) { | 275 Value *NaClBitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) { |
| 275 if (Idx >= size()) | 276 if (Idx >= size()) |
| 276 resize(Idx + 1); | 277 resize(Idx + 1); |
| 277 | 278 |
| 278 if (Value *V = ValuePtrs[Idx]) { | 279 if (Value *V = ValuePtrs[Idx]) { |
| 279 assert((Ty == 0 || Ty == V->getType()) && "Type mismatch in value table!"); | 280 assert((Ty == 0 || Ty == V->getType()) && "Type mismatch in value table!"); |
| 280 return V; | 281 return V; |
| 281 } | 282 } |
| 282 | 283 |
| 283 // No type specified, must be invalid reference. | 284 // No type specified, must be invalid reference. |
| 284 if (Ty == 0) return 0; | 285 if (Ty == 0) return 0; |
| 285 | 286 |
| 286 // Create and return a placeholder, which will later be RAUW'd. | 287 // Create and return a placeholder, which will later be RAUW'd. |
| 287 Value *V = new Argument(Ty); | 288 Value *V = new Argument(Ty); |
| 288 ValuePtrs[Idx] = V; | 289 ValuePtrs[Idx] = V; |
| 289 return V; | 290 return V; |
| 290 } | 291 } |
| 291 | 292 |
| 292 /// ResolveConstantForwardRefs - Once all constants are read, this method bulk | 293 /// ResolveConstantForwardRefs - Once all constants are read, this method bulk |
| 293 /// resolves any forward references. The idea behind this is that we sometimes | 294 /// resolves any forward references. The idea behind this is that we sometimes |
| 294 /// get constants (such as large arrays) which reference *many* forward ref | 295 /// get constants (such as large arrays) which reference *many* forward ref |
| 295 /// constants. Replacing each of these causes a lot of thrashing when | 296 /// constants. Replacing each of these causes a lot of thrashing when |
| 296 /// building/reuniquing the constant. Instead of doing this, we look at all the | 297 /// building/reuniquing the constant. Instead of doing this, we look at all the |
| 297 /// uses and rewrite all the place holders at once for any constant that uses | 298 /// uses and rewrite all the place holders at once for any constant that uses |
| 298 /// a placeholder. | 299 /// a placeholder. |
| 299 void BitcodeReaderValueList::ResolveConstantForwardRefs() { | 300 void NaClBitcodeReaderValueList::ResolveConstantForwardRefs() { |
| 300 // Sort the values by-pointer so that they are efficient to look up with a | 301 // Sort the values by-pointer so that they are efficient to look up with a |
| 301 // binary search. | 302 // binary search. |
| 302 std::sort(ResolveConstants.begin(), ResolveConstants.end()); | 303 std::sort(ResolveConstants.begin(), ResolveConstants.end()); |
| 303 | 304 |
| 304 SmallVector<Constant*, 64> NewOps; | 305 SmallVector<Constant*, 64> NewOps; |
| 305 | 306 |
| 306 while (!ResolveConstants.empty()) { | 307 while (!ResolveConstants.empty()) { |
| 307 Value *RealVal = operator[](ResolveConstants.back().second); | 308 Value *RealVal = operator[](ResolveConstants.back().second); |
| 308 Constant *Placeholder = ResolveConstants.back().first; | 309 Constant *Placeholder = ResolveConstants.back().first; |
| 309 ResolveConstants.pop_back(); | 310 ResolveConstants.pop_back(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 364 UserC->destroyConstant(); | 365 UserC->destroyConstant(); |
| 365 NewOps.clear(); | 366 NewOps.clear(); |
| 366 } | 367 } |
| 367 | 368 |
| 368 // Update all ValueHandles, they should be the only users at this point. | 369 // Update all ValueHandles, they should be the only users at this point. |
| 369 Placeholder->replaceAllUsesWith(RealVal); | 370 Placeholder->replaceAllUsesWith(RealVal); |
| 370 delete Placeholder; | 371 delete Placeholder; |
| 371 } | 372 } |
| 372 } | 373 } |
| 373 | 374 |
| 374 void BitcodeReaderMDValueList::AssignValue(Value *V, unsigned Idx) { | 375 void NaClBitcodeReaderMDValueList::AssignValue(Value *V, unsigned Idx) { |
| 375 if (Idx == size()) { | 376 if (Idx == size()) { |
| 376 push_back(V); | 377 push_back(V); |
| 377 return; | 378 return; |
| 378 } | 379 } |
| 379 | 380 |
| 380 if (Idx >= size()) | 381 if (Idx >= size()) |
| 381 resize(Idx+1); | 382 resize(Idx+1); |
| 382 | 383 |
| 383 WeakVH &OldV = MDValuePtrs[Idx]; | 384 WeakVH &OldV = MDValuePtrs[Idx]; |
| 384 if (OldV == 0) { | 385 if (OldV == 0) { |
| 385 OldV = V; | 386 OldV = V; |
| 386 return; | 387 return; |
| 387 } | 388 } |
| 388 | 389 |
| 389 // If there was a forward reference to this value, replace it. | 390 // If there was a forward reference to this value, replace it. |
| 390 MDNode *PrevVal = cast<MDNode>(OldV); | 391 MDNode *PrevVal = cast<MDNode>(OldV); |
| 391 OldV->replaceAllUsesWith(V); | 392 OldV->replaceAllUsesWith(V); |
| 392 MDNode::deleteTemporary(PrevVal); | 393 MDNode::deleteTemporary(PrevVal); |
| 393 // Deleting PrevVal sets Idx value in MDValuePtrs to null. Set new | 394 // Deleting PrevVal sets Idx value in MDValuePtrs to null. Set new |
| 394 // value for Idx. | 395 // value for Idx. |
| 395 MDValuePtrs[Idx] = V; | 396 MDValuePtrs[Idx] = V; |
| 396 } | 397 } |
| 397 | 398 |
| 398 Value *BitcodeReaderMDValueList::getValueFwdRef(unsigned Idx) { | 399 Value *NaClBitcodeReaderMDValueList::getValueFwdRef(unsigned Idx) { |
| 399 if (Idx >= size()) | 400 if (Idx >= size()) |
| 400 resize(Idx + 1); | 401 resize(Idx + 1); |
| 401 | 402 |
| 402 if (Value *V = MDValuePtrs[Idx]) { | 403 if (Value *V = MDValuePtrs[Idx]) { |
| 403 assert(V->getType()->isMetadataTy() && "Type mismatch in value table!"); | 404 assert(V->getType()->isMetadataTy() && "Type mismatch in value table!"); |
| 404 return V; | 405 return V; |
| 405 } | 406 } |
| 406 | 407 |
| 407 // Create and return a placeholder, which will later be RAUW'd. | 408 // Create and return a placeholder, which will later be RAUW'd. |
| 408 Value *V = MDNode::getTemporary(Context, ArrayRef<Value*>()); | 409 Value *V = MDNode::getTemporary(Context, ArrayRef<Value*>()); |
| 409 MDValuePtrs[Idx] = V; | 410 MDValuePtrs[Idx] = V; |
| 410 return V; | 411 return V; |
| 411 } | 412 } |
| 412 | 413 |
| 413 Type *BitcodeReader::getTypeByID(unsigned ID) { | 414 Type *NaClBitcodeReader::getTypeByID(unsigned ID) { |
| 414 // The type table size is always specified correctly. | 415 // The type table size is always specified correctly. |
| 415 if (ID >= TypeList.size()) | 416 if (ID >= TypeList.size()) |
| 416 return 0; | 417 return 0; |
| 417 | 418 |
| 418 if (Type *Ty = TypeList[ID]) | 419 if (Type *Ty = TypeList[ID]) |
| 419 return Ty; | 420 return Ty; |
| 420 | 421 |
| 421 // If we have a forward reference, the only possible case is when it is to a | 422 // If we have a forward reference, the only possible case is when it is to a |
| 422 // named struct. Just create a placeholder for now. | 423 // named struct. Just create a placeholder for now. |
| 423 return TypeList[ID] = StructType::create(Context); | 424 return TypeList[ID] = StructType::create(Context); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 441 unsigned Alignment = (EncodedAttrs & (0xffffULL << 16)) >> 16; | 442 unsigned Alignment = (EncodedAttrs & (0xffffULL << 16)) >> 16; |
| 442 assert((!Alignment || isPowerOf2_32(Alignment)) && | 443 assert((!Alignment || isPowerOf2_32(Alignment)) && |
| 443 "Alignment must be a power of two."); | 444 "Alignment must be a power of two."); |
| 444 | 445 |
| 445 if (Alignment) | 446 if (Alignment) |
| 446 B.addAlignmentAttr(Alignment); | 447 B.addAlignmentAttr(Alignment); |
| 447 B.addRawValue(((EncodedAttrs & (0xfffffULL << 32)) >> 11) | | 448 B.addRawValue(((EncodedAttrs & (0xfffffULL << 32)) >> 11) | |
| 448 (EncodedAttrs & 0xffff)); | 449 (EncodedAttrs & 0xffff)); |
| 449 } | 450 } |
| 450 | 451 |
| 451 bool BitcodeReader::ParseAttributeBlock() { | 452 bool NaClBitcodeReader::ParseAttributeBlock() { |
| 452 if (Stream.EnterSubBlock(bitc::PARAMATTR_BLOCK_ID)) | 453 if (Stream.EnterSubBlock(bitc::PARAMATTR_BLOCK_ID)) |
| 453 return Error("Malformed block record"); | 454 return Error("Malformed block record"); |
| 454 | 455 |
| 455 if (!MAttributes.empty()) | 456 if (!MAttributes.empty()) |
| 456 return Error("Multiple PARAMATTR blocks found!"); | 457 return Error("Multiple PARAMATTR blocks found!"); |
| 457 | 458 |
| 458 SmallVector<uint64_t, 64> Record; | 459 SmallVector<uint64_t, 64> Record; |
| 459 | 460 |
| 460 SmallVector<AttributeSet, 8> Attrs; | 461 SmallVector<AttributeSet, 8> Attrs; |
| 461 | 462 |
| 462 // Read all the records. | 463 // Read all the records. |
| 463 while (1) { | 464 while (1) { |
| 464 BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); | 465 BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); |
|
jvoung (off chromium)
2013/04/29 18:02:08
See question in header file about making it NaClBi
Karl
2013/04/29 20:44:37
Done.
| |
| 465 | 466 |
| 466 switch (Entry.Kind) { | 467 switch (Entry.Kind) { |
| 467 case BitstreamEntry::SubBlock: // Handled for us already. | 468 case BitstreamEntry::SubBlock: // Handled for us already. |
| 468 case BitstreamEntry::Error: | 469 case BitstreamEntry::Error: |
| 469 return Error("Error at end of PARAMATTR block"); | 470 return Error("Error at end of PARAMATTR block"); |
| 470 case BitstreamEntry::EndBlock: | 471 case BitstreamEntry::EndBlock: |
| 471 return false; | 472 return false; |
| 472 case BitstreamEntry::Record: | 473 case BitstreamEntry::Record: |
| 473 // The interesting case. | 474 // The interesting case. |
| 474 break; | 475 break; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 499 Attrs.push_back(MAttributeGroups[Record[i]]); | 500 Attrs.push_back(MAttributeGroups[Record[i]]); |
| 500 | 501 |
| 501 MAttributes.push_back(AttributeSet::get(Context, Attrs)); | 502 MAttributes.push_back(AttributeSet::get(Context, Attrs)); |
| 502 Attrs.clear(); | 503 Attrs.clear(); |
| 503 break; | 504 break; |
| 504 } | 505 } |
| 505 } | 506 } |
| 506 } | 507 } |
| 507 } | 508 } |
| 508 | 509 |
| 509 bool BitcodeReader::ParseAttributeGroupBlock() { | 510 bool NaClBitcodeReader::ParseAttributeGroupBlock() { |
| 510 if (Stream.EnterSubBlock(bitc::PARAMATTR_GROUP_BLOCK_ID)) | 511 if (Stream.EnterSubBlock(bitc::PARAMATTR_GROUP_BLOCK_ID)) |
| 511 return Error("Malformed block record"); | 512 return Error("Malformed block record"); |
| 512 | 513 |
| 513 if (!MAttributeGroups.empty()) | 514 if (!MAttributeGroups.empty()) |
| 514 return Error("Multiple PARAMATTR_GROUP blocks found!"); | 515 return Error("Multiple PARAMATTR_GROUP blocks found!"); |
| 515 | 516 |
| 516 SmallVector<uint64_t, 64> Record; | 517 SmallVector<uint64_t, 64> Record; |
| 517 | 518 |
| 518 // Read all the records. | 519 // Read all the records. |
| 519 while (1) { | 520 while (1) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 574 } | 575 } |
| 575 } | 576 } |
| 576 | 577 |
| 577 MAttributeGroups[GrpID] = AttributeSet::get(Context, Idx, B); | 578 MAttributeGroups[GrpID] = AttributeSet::get(Context, Idx, B); |
| 578 break; | 579 break; |
| 579 } | 580 } |
| 580 } | 581 } |
| 581 } | 582 } |
| 582 } | 583 } |
| 583 | 584 |
| 584 bool BitcodeReader::ParseTypeTable() { | 585 bool NaClBitcodeReader::ParseTypeTable() { |
| 585 if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW)) | 586 if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW)) |
| 586 return Error("Malformed block record"); | 587 return Error("Malformed block record"); |
| 587 | 588 |
| 588 return ParseTypeTableBody(); | 589 return ParseTypeTableBody(); |
| 589 } | 590 } |
| 590 | 591 |
| 591 bool BitcodeReader::ParseTypeTableBody() { | 592 bool NaClBitcodeReader::ParseTypeTableBody() { |
| 592 if (!TypeList.empty()) | 593 if (!TypeList.empty()) |
| 593 return Error("Multiple TYPE_BLOCKs found!"); | 594 return Error("Multiple TYPE_BLOCKs found!"); |
| 594 | 595 |
| 595 SmallVector<uint64_t, 64> Record; | 596 SmallVector<uint64_t, 64> Record; |
| 596 unsigned NumRecords = 0; | 597 unsigned NumRecords = 0; |
| 597 | 598 |
| 598 SmallString<64> TypeName; | 599 SmallString<64> TypeName; |
| 599 | 600 |
| 600 // Read all the records for this type table. | 601 // Read all the records for this type table. |
| 601 while (1) { | 602 while (1) { |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 800 } | 801 } |
| 801 | 802 |
| 802 if (NumRecords >= TypeList.size()) | 803 if (NumRecords >= TypeList.size()) |
| 803 return Error("invalid TYPE table"); | 804 return Error("invalid TYPE table"); |
| 804 assert(ResultTy && "Didn't read a type?"); | 805 assert(ResultTy && "Didn't read a type?"); |
| 805 assert(TypeList[NumRecords] == 0 && "Already read type?"); | 806 assert(TypeList[NumRecords] == 0 && "Already read type?"); |
| 806 TypeList[NumRecords++] = ResultTy; | 807 TypeList[NumRecords++] = ResultTy; |
| 807 } | 808 } |
| 808 } | 809 } |
| 809 | 810 |
| 810 bool BitcodeReader::ParseValueSymbolTable() { | 811 bool NaClBitcodeReader::ParseValueSymbolTable() { |
| 811 if (Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID)) | 812 if (Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID)) |
| 812 return Error("Malformed block record"); | 813 return Error("Malformed block record"); |
| 813 | 814 |
| 814 SmallVector<uint64_t, 64> Record; | 815 SmallVector<uint64_t, 64> Record; |
| 815 | 816 |
| 816 // Read all the records for this value table. | 817 // Read all the records for this value table. |
| 817 SmallString<128> ValueName; | 818 SmallString<128> ValueName; |
| 818 while (1) { | 819 while (1) { |
| 819 BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); | 820 BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); |
| 820 | 821 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 854 return Error("Invalid BB ID in VST_BBENTRY record"); | 855 return Error("Invalid BB ID in VST_BBENTRY record"); |
| 855 | 856 |
| 856 BB->setName(StringRef(ValueName.data(), ValueName.size())); | 857 BB->setName(StringRef(ValueName.data(), ValueName.size())); |
| 857 ValueName.clear(); | 858 ValueName.clear(); |
| 858 break; | 859 break; |
| 859 } | 860 } |
| 860 } | 861 } |
| 861 } | 862 } |
| 862 } | 863 } |
| 863 | 864 |
| 864 bool BitcodeReader::ParseMetadata() { | 865 bool NaClBitcodeReader::ParseMetadata() { |
| 865 unsigned NextMDValueNo = MDValueList.size(); | 866 unsigned NextMDValueNo = MDValueList.size(); |
| 866 | 867 |
| 867 if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID)) | 868 if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID)) |
| 868 return Error("Malformed block record"); | 869 return Error("Malformed block record"); |
| 869 | 870 |
| 870 SmallVector<uint64_t, 64> Record; | 871 SmallVector<uint64_t, 64> Record; |
| 871 | 872 |
| 872 // Read all the records. | 873 // Read all the records. |
| 873 while (1) { | 874 while (1) { |
| 874 BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); | 875 BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 954 if (!MDKindMap.insert(std::make_pair(Kind, NewKind)).second) | 955 if (!MDKindMap.insert(std::make_pair(Kind, NewKind)).second) |
| 955 return Error("Conflicting METADATA_KIND records"); | 956 return Error("Conflicting METADATA_KIND records"); |
| 956 break; | 957 break; |
| 957 } | 958 } |
| 958 } | 959 } |
| 959 } | 960 } |
| 960 } | 961 } |
| 961 | 962 |
| 962 /// decodeSignRotatedValue - Decode a signed value stored with the sign bit in | 963 /// decodeSignRotatedValue - Decode a signed value stored with the sign bit in |
| 963 /// the LSB for dense VBR encoding. | 964 /// the LSB for dense VBR encoding. |
| 964 uint64_t BitcodeReader::decodeSignRotatedValue(uint64_t V) { | 965 uint64_t NaClBitcodeReader::decodeSignRotatedValue(uint64_t V) { |
| 965 if ((V & 1) == 0) | 966 if ((V & 1) == 0) |
| 966 return V >> 1; | 967 return V >> 1; |
| 967 if (V != 1) | 968 if (V != 1) |
| 968 return -(V >> 1); | 969 return -(V >> 1); |
| 969 // There is no such thing as -0 with integers. "-0" really means MININT. | 970 // There is no such thing as -0 with integers. "-0" really means MININT. |
| 970 return 1ULL << 63; | 971 return 1ULL << 63; |
| 971 } | 972 } |
| 972 | 973 |
| 973 /// ResolveGlobalAndAliasInits - Resolve all of the initializers for global | 974 /// ResolveGlobalAndAliasInits - Resolve all of the initializers for global |
| 974 /// values and aliases that we can. | 975 /// values and aliases that we can. |
| 975 bool BitcodeReader::ResolveGlobalAndAliasInits() { | 976 bool NaClBitcodeReader::ResolveGlobalAndAliasInits() { |
| 976 std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitWorklist; | 977 std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitWorklist; |
| 977 std::vector<std::pair<GlobalAlias*, unsigned> > AliasInitWorklist; | 978 std::vector<std::pair<GlobalAlias*, unsigned> > AliasInitWorklist; |
| 978 | 979 |
| 979 GlobalInitWorklist.swap(GlobalInits); | 980 GlobalInitWorklist.swap(GlobalInits); |
| 980 AliasInitWorklist.swap(AliasInits); | 981 AliasInitWorklist.swap(AliasInits); |
| 981 | 982 |
| 982 while (!GlobalInitWorklist.empty()) { | 983 while (!GlobalInitWorklist.empty()) { |
| 983 unsigned ValID = GlobalInitWorklist.back().second; | 984 unsigned ValID = GlobalInitWorklist.back().second; |
| 984 if (ValID >= ValueList.size()) { | 985 if (ValID >= ValueList.size()) { |
| 985 // Not ready to resolve this yet, it requires something later in the file. | 986 // Not ready to resolve this yet, it requires something later in the file. |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1004 return Error("Alias initializer is not a constant!"); | 1005 return Error("Alias initializer is not a constant!"); |
| 1005 } | 1006 } |
| 1006 AliasInitWorklist.pop_back(); | 1007 AliasInitWorklist.pop_back(); |
| 1007 } | 1008 } |
| 1008 return false; | 1009 return false; |
| 1009 } | 1010 } |
| 1010 | 1011 |
| 1011 static APInt ReadWideAPInt(ArrayRef<uint64_t> Vals, unsigned TypeBits) { | 1012 static APInt ReadWideAPInt(ArrayRef<uint64_t> Vals, unsigned TypeBits) { |
| 1012 SmallVector<uint64_t, 8> Words(Vals.size()); | 1013 SmallVector<uint64_t, 8> Words(Vals.size()); |
| 1013 std::transform(Vals.begin(), Vals.end(), Words.begin(), | 1014 std::transform(Vals.begin(), Vals.end(), Words.begin(), |
| 1014 BitcodeReader::decodeSignRotatedValue); | 1015 NaClBitcodeReader::decodeSignRotatedValue); |
| 1015 | 1016 |
| 1016 return APInt(TypeBits, Words); | 1017 return APInt(TypeBits, Words); |
| 1017 } | 1018 } |
| 1018 | 1019 |
| 1019 bool BitcodeReader::ParseConstants() { | 1020 bool NaClBitcodeReader::ParseConstants() { |
| 1020 if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID)) | 1021 if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID)) |
| 1021 return Error("Malformed block record"); | 1022 return Error("Malformed block record"); |
| 1022 | 1023 |
| 1023 SmallVector<uint64_t, 64> Record; | 1024 SmallVector<uint64_t, 64> Record; |
| 1024 | 1025 |
| 1025 // Read all the records for this value table. | 1026 // Read all the records for this value table. |
| 1026 Type *CurTy = Type::getInt32Ty(Context); | 1027 Type *CurTy = Type::getInt32Ty(Context); |
| 1027 unsigned NextCstNo = ValueList.size(); | 1028 unsigned NextCstNo = ValueList.size(); |
| 1028 while (1) { | 1029 while (1) { |
| 1029 BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); | 1030 BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1404 } | 1405 } |
| 1405 break; | 1406 break; |
| 1406 } | 1407 } |
| 1407 } | 1408 } |
| 1408 | 1409 |
| 1409 ValueList.AssignValue(V, NextCstNo); | 1410 ValueList.AssignValue(V, NextCstNo); |
| 1410 ++NextCstNo; | 1411 ++NextCstNo; |
| 1411 } | 1412 } |
| 1412 } | 1413 } |
| 1413 | 1414 |
| 1414 bool BitcodeReader::ParseUseLists() { | 1415 bool NaClBitcodeReader::ParseUseLists() { |
| 1415 if (Stream.EnterSubBlock(bitc::USELIST_BLOCK_ID)) | 1416 if (Stream.EnterSubBlock(bitc::USELIST_BLOCK_ID)) |
| 1416 return Error("Malformed block record"); | 1417 return Error("Malformed block record"); |
| 1417 | 1418 |
| 1418 SmallVector<uint64_t, 64> Record; | 1419 SmallVector<uint64_t, 64> Record; |
| 1419 | 1420 |
| 1420 // Read all the records. | 1421 // Read all the records. |
| 1421 while (1) { | 1422 while (1) { |
| 1422 BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); | 1423 BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); |
| 1423 | 1424 |
| 1424 switch (Entry.Kind) { | 1425 switch (Entry.Kind) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1444 UseListRecords.push_back(Record); | 1445 UseListRecords.push_back(Record); |
| 1445 break; | 1446 break; |
| 1446 } | 1447 } |
| 1447 } | 1448 } |
| 1448 } | 1449 } |
| 1449 } | 1450 } |
| 1450 | 1451 |
| 1451 /// RememberAndSkipFunctionBody - When we see the block for a function body, | 1452 /// RememberAndSkipFunctionBody - When we see the block for a function body, |
| 1452 /// remember where it is and then skip it. This lets us lazily deserialize the | 1453 /// remember where it is and then skip it. This lets us lazily deserialize the |
| 1453 /// functions. | 1454 /// functions. |
| 1454 bool BitcodeReader::RememberAndSkipFunctionBody() { | 1455 bool NaClBitcodeReader::RememberAndSkipFunctionBody() { |
| 1455 // Get the function we are talking about. | 1456 // Get the function we are talking about. |
| 1456 if (FunctionsWithBodies.empty()) | 1457 if (FunctionsWithBodies.empty()) |
| 1457 return Error("Insufficient function protos"); | 1458 return Error("Insufficient function protos"); |
| 1458 | 1459 |
| 1459 Function *Fn = FunctionsWithBodies.back(); | 1460 Function *Fn = FunctionsWithBodies.back(); |
| 1460 FunctionsWithBodies.pop_back(); | 1461 FunctionsWithBodies.pop_back(); |
| 1461 | 1462 |
| 1462 // Save the current stream state. | 1463 // Save the current stream state. |
| 1463 uint64_t CurBit = Stream.GetCurrentBitNo(); | 1464 uint64_t CurBit = Stream.GetCurrentBitNo(); |
| 1464 DeferredFunctionInfo[Fn] = CurBit; | 1465 DeferredFunctionInfo[Fn] = CurBit; |
| 1465 | 1466 |
| 1466 // Skip over the function block for now. | 1467 // Skip over the function block for now. |
| 1467 if (Stream.SkipBlock()) | 1468 if (Stream.SkipBlock()) |
| 1468 return Error("Malformed block record"); | 1469 return Error("Malformed block record"); |
| 1469 return false; | 1470 return false; |
| 1470 } | 1471 } |
| 1471 | 1472 |
| 1472 bool BitcodeReader::GlobalCleanup() { | 1473 bool NaClBitcodeReader::GlobalCleanup() { |
| 1473 // Patch the initializers for globals and aliases up. | 1474 // Patch the initializers for globals and aliases up. |
| 1474 ResolveGlobalAndAliasInits(); | 1475 ResolveGlobalAndAliasInits(); |
| 1475 if (!GlobalInits.empty() || !AliasInits.empty()) | 1476 if (!GlobalInits.empty() || !AliasInits.empty()) |
| 1476 return Error("Malformed global initializer set"); | 1477 return Error("Malformed global initializer set"); |
| 1477 | 1478 |
| 1478 // Look for intrinsic functions which need to be upgraded at some point | 1479 // Look for intrinsic functions which need to be upgraded at some point |
| 1479 for (Module::iterator FI = TheModule->begin(), FE = TheModule->end(); | 1480 for (Module::iterator FI = TheModule->begin(), FE = TheModule->end(); |
| 1480 FI != FE; ++FI) { | 1481 FI != FE; ++FI) { |
| 1481 Function *NewFn; | 1482 Function *NewFn; |
| 1482 if (UpgradeIntrinsicFunction(FI, NewFn)) | 1483 if (UpgradeIntrinsicFunction(FI, NewFn)) |
| 1483 UpgradedIntrinsics.push_back(std::make_pair(FI, NewFn)); | 1484 UpgradedIntrinsics.push_back(std::make_pair(FI, NewFn)); |
| 1484 } | 1485 } |
| 1485 | 1486 |
| 1486 // Look for global variables which need to be renamed. | 1487 // Look for global variables which need to be renamed. |
| 1487 for (Module::global_iterator | 1488 for (Module::global_iterator |
| 1488 GI = TheModule->global_begin(), GE = TheModule->global_end(); | 1489 GI = TheModule->global_begin(), GE = TheModule->global_end(); |
| 1489 GI != GE; ++GI) | 1490 GI != GE; ++GI) |
| 1490 UpgradeGlobalVariable(GI); | 1491 UpgradeGlobalVariable(GI); |
| 1491 // Force deallocation of memory for these vectors to favor the client that | 1492 // Force deallocation of memory for these vectors to favor the client that |
| 1492 // want lazy deserialization. | 1493 // want lazy deserialization. |
| 1493 std::vector<std::pair<GlobalVariable*, unsigned> >().swap(GlobalInits); | 1494 std::vector<std::pair<GlobalVariable*, unsigned> >().swap(GlobalInits); |
| 1494 std::vector<std::pair<GlobalAlias*, unsigned> >().swap(AliasInits); | 1495 std::vector<std::pair<GlobalAlias*, unsigned> >().swap(AliasInits); |
| 1495 return false; | 1496 return false; |
| 1496 } | 1497 } |
| 1497 | 1498 |
| 1498 bool BitcodeReader::ParseModule(bool Resume) { | 1499 bool NaClBitcodeReader::ParseModule(bool Resume) { |
| 1499 if (Resume) | 1500 if (Resume) |
| 1500 Stream.JumpToBit(NextUnreadBit); | 1501 Stream.JumpToBit(NextUnreadBit); |
| 1501 else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) | 1502 else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) |
| 1502 return Error("Malformed block record"); | 1503 return Error("Malformed block record"); |
| 1503 | 1504 |
| 1504 SmallVector<uint64_t, 64> Record; | 1505 SmallVector<uint64_t, 64> Record; |
| 1505 std::vector<std::string> SectionTable; | 1506 std::vector<std::string> SectionTable; |
| 1506 std::vector<std::string> GCTable; | 1507 std::vector<std::string> GCTable; |
| 1507 | 1508 |
| 1508 // Read all the records for this module. | 1509 // Read all the records for this module. |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1783 // Trim down the value list to the specified size. | 1784 // Trim down the value list to the specified size. |
| 1784 if (Record.size() < 1 || Record[0] > ValueList.size()) | 1785 if (Record.size() < 1 || Record[0] > ValueList.size()) |
| 1785 return Error("Invalid MODULE_PURGEVALS record"); | 1786 return Error("Invalid MODULE_PURGEVALS record"); |
| 1786 ValueList.shrinkTo(Record[0]); | 1787 ValueList.shrinkTo(Record[0]); |
| 1787 break; | 1788 break; |
| 1788 } | 1789 } |
| 1789 Record.clear(); | 1790 Record.clear(); |
| 1790 } | 1791 } |
| 1791 } | 1792 } |
| 1792 | 1793 |
| 1793 bool BitcodeReader::ParseBitcodeInto(Module *M) { | 1794 bool NaClBitcodeReader::ParseBitcodeInto(Module *M) { |
| 1794 TheModule = 0; | 1795 TheModule = 0; |
| 1795 | 1796 |
| 1796 if (InitStream()) return true; | 1797 if (InitStream()) return true; |
| 1797 | 1798 |
| 1798 // Sniff for the signature. | 1799 // Sniff for the signature. |
| 1799 if (Stream.Read(8) != 'B' || | 1800 if (Stream.Read(8) != 'B' || |
| 1800 Stream.Read(8) != 'C' || | 1801 Stream.Read(8) != 'C' || |
| 1801 Stream.Read(4) != 0x0 || | 1802 Stream.Read(4) != 0x0 || |
| 1802 Stream.Read(4) != 0xC || | 1803 Stream.Read(4) != 0xC || |
| 1803 Stream.Read(4) != 0xE || | 1804 Stream.Read(4) != 0xE || |
| 1804 Stream.Read(4) != 0xD) | 1805 Stream.Read(4) != 0xD) |
| 1805 return Error("Invalid bitcode signature"); | 1806 return Error("Invalid bitcode signature"); |
| 1806 | 1807 |
| 1807 // We expect a number of well-defined blocks, though we don't necessarily | 1808 // We expect a number of well-defined blocks, though we don't necessarily |
| 1808 // need to understand them all. | 1809 // need to understand them all. |
| 1809 while (1) { | 1810 while (1) { |
| 1810 if (Stream.AtEndOfStream()) | 1811 if (Stream.AtEndOfStream()) |
| 1811 return false; | 1812 return false; |
| 1812 | 1813 |
| 1813 BitstreamEntry Entry = | 1814 BitstreamEntry Entry = |
| 1814 Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs); | 1815 Stream.advance(NaClBitstreamCursor::AF_DontAutoprocessAbbrevs); |
| 1815 | 1816 |
| 1816 switch (Entry.Kind) { | 1817 switch (Entry.Kind) { |
| 1817 case BitstreamEntry::Error: | 1818 case BitstreamEntry::Error: |
| 1818 Error("malformed module file"); | 1819 Error("malformed module file"); |
| 1819 return true; | 1820 return true; |
| 1820 case BitstreamEntry::EndBlock: | 1821 case BitstreamEntry::EndBlock: |
| 1821 return false; | 1822 return false; |
| 1822 | 1823 |
| 1823 case BitstreamEntry::SubBlock: | 1824 case BitstreamEntry::SubBlock: |
| 1824 switch (Entry.ID) { | 1825 switch (Entry.ID) { |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1850 if (Stream.getAbbrevIDWidth() == 2 && Entry.ID == 2 && | 1851 if (Stream.getAbbrevIDWidth() == 2 && Entry.ID == 2 && |
| 1851 Stream.Read(6) == 2 && Stream.Read(24) == 0xa0a0a && | 1852 Stream.Read(6) == 2 && Stream.Read(24) == 0xa0a0a && |
| 1852 Stream.AtEndOfStream()) | 1853 Stream.AtEndOfStream()) |
| 1853 return false; | 1854 return false; |
| 1854 | 1855 |
| 1855 return Error("Invalid record at top-level"); | 1856 return Error("Invalid record at top-level"); |
| 1856 } | 1857 } |
| 1857 } | 1858 } |
| 1858 } | 1859 } |
| 1859 | 1860 |
| 1860 bool BitcodeReader::ParseModuleTriple(std::string &Triple) { | 1861 bool NaClBitcodeReader::ParseModuleTriple(std::string &Triple) { |
| 1861 if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) | 1862 if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) |
| 1862 return Error("Malformed block record"); | 1863 return Error("Malformed block record"); |
| 1863 | 1864 |
| 1864 SmallVector<uint64_t, 64> Record; | 1865 SmallVector<uint64_t, 64> Record; |
| 1865 | 1866 |
| 1866 // Read all the records for this module. | 1867 // Read all the records for this module. |
| 1867 while (1) { | 1868 while (1) { |
| 1868 BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); | 1869 BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); |
| 1869 | 1870 |
| 1870 switch (Entry.Kind) { | 1871 switch (Entry.Kind) { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1886 if (ConvertToString(Record, 0, S)) | 1887 if (ConvertToString(Record, 0, S)) |
| 1887 return Error("Invalid MODULE_CODE_TRIPLE record"); | 1888 return Error("Invalid MODULE_CODE_TRIPLE record"); |
| 1888 Triple = S; | 1889 Triple = S; |
| 1889 break; | 1890 break; |
| 1890 } | 1891 } |
| 1891 } | 1892 } |
| 1892 Record.clear(); | 1893 Record.clear(); |
| 1893 } | 1894 } |
| 1894 } | 1895 } |
| 1895 | 1896 |
| 1896 bool BitcodeReader::ParseTriple(std::string &Triple) { | 1897 bool NaClBitcodeReader::ParseTriple(std::string &Triple) { |
| 1897 if (InitStream()) return true; | 1898 if (InitStream()) return true; |
| 1898 | 1899 |
| 1899 // Sniff for the signature. | 1900 // Sniff for the signature. |
| 1900 if (Stream.Read(8) != 'B' || | 1901 if (Stream.Read(8) != 'B' || |
| 1901 Stream.Read(8) != 'C' || | 1902 Stream.Read(8) != 'C' || |
| 1902 Stream.Read(4) != 0x0 || | 1903 Stream.Read(4) != 0x0 || |
| 1903 Stream.Read(4) != 0xC || | 1904 Stream.Read(4) != 0xC || |
| 1904 Stream.Read(4) != 0xE || | 1905 Stream.Read(4) != 0xE || |
| 1905 Stream.Read(4) != 0xD) | 1906 Stream.Read(4) != 0xD) |
| 1906 return Error("Invalid bitcode signature"); | 1907 return Error("Invalid bitcode signature"); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1929 continue; | 1930 continue; |
| 1930 | 1931 |
| 1931 case BitstreamEntry::Record: | 1932 case BitstreamEntry::Record: |
| 1932 Stream.skipRecord(Entry.ID); | 1933 Stream.skipRecord(Entry.ID); |
| 1933 continue; | 1934 continue; |
| 1934 } | 1935 } |
| 1935 } | 1936 } |
| 1936 } | 1937 } |
| 1937 | 1938 |
| 1938 /// ParseMetadataAttachment - Parse metadata attachments. | 1939 /// ParseMetadataAttachment - Parse metadata attachments. |
| 1939 bool BitcodeReader::ParseMetadataAttachment() { | 1940 bool NaClBitcodeReader::ParseMetadataAttachment() { |
| 1940 if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID)) | 1941 if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID)) |
| 1941 return Error("Malformed block record"); | 1942 return Error("Malformed block record"); |
| 1942 | 1943 |
| 1943 SmallVector<uint64_t, 64> Record; | 1944 SmallVector<uint64_t, 64> Record; |
| 1944 while (1) { | 1945 while (1) { |
| 1945 BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); | 1946 BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); |
| 1946 | 1947 |
| 1947 switch (Entry.Kind) { | 1948 switch (Entry.Kind) { |
| 1948 case BitstreamEntry::SubBlock: // Handled for us already. | 1949 case BitstreamEntry::SubBlock: // Handled for us already. |
| 1949 case BitstreamEntry::Error: | 1950 case BitstreamEntry::Error: |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1974 Value *Node = MDValueList.getValueFwdRef(Record[i+1]); | 1975 Value *Node = MDValueList.getValueFwdRef(Record[i+1]); |
| 1975 Inst->setMetadata(I->second, cast<MDNode>(Node)); | 1976 Inst->setMetadata(I->second, cast<MDNode>(Node)); |
| 1976 } | 1977 } |
| 1977 break; | 1978 break; |
| 1978 } | 1979 } |
| 1979 } | 1980 } |
| 1980 } | 1981 } |
| 1981 } | 1982 } |
| 1982 | 1983 |
| 1983 /// ParseFunctionBody - Lazily parse the specified function body block. | 1984 /// ParseFunctionBody - Lazily parse the specified function body block. |
| 1984 bool BitcodeReader::ParseFunctionBody(Function *F) { | 1985 bool NaClBitcodeReader::ParseFunctionBody(Function *F) { |
| 1985 if (Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID)) | 1986 if (Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID)) |
| 1986 return Error("Malformed block record"); | 1987 return Error("Malformed block record"); |
| 1987 | 1988 |
| 1988 InstructionList.clear(); | 1989 InstructionList.clear(); |
| 1989 unsigned ModuleValueListSize = ValueList.size(); | 1990 unsigned ModuleValueListSize = ValueList.size(); |
| 1990 unsigned ModuleMDValueListSize = MDValueList.size(); | 1991 unsigned ModuleMDValueListSize = MDValueList.size(); |
| 1991 | 1992 |
| 1992 // Add all the function arguments to the value table. | 1993 // Add all the function arguments to the value table. |
| 1993 for(Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I) | 1994 for(Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I) |
| 1994 ValueList.push_back(I); | 1995 ValueList.push_back(I); |
| (...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2856 } | 2857 } |
| 2857 | 2858 |
| 2858 // Trim the value list down to the size it was before we parsed this function. | 2859 // Trim the value list down to the size it was before we parsed this function. |
| 2859 ValueList.shrinkTo(ModuleValueListSize); | 2860 ValueList.shrinkTo(ModuleValueListSize); |
| 2860 MDValueList.shrinkTo(ModuleMDValueListSize); | 2861 MDValueList.shrinkTo(ModuleMDValueListSize); |
| 2861 std::vector<BasicBlock*>().swap(FunctionBBs); | 2862 std::vector<BasicBlock*>().swap(FunctionBBs); |
| 2862 return false; | 2863 return false; |
| 2863 } | 2864 } |
| 2864 | 2865 |
| 2865 /// FindFunctionInStream - Find the function body in the bitcode stream | 2866 /// FindFunctionInStream - Find the function body in the bitcode stream |
| 2866 bool BitcodeReader::FindFunctionInStream(Function *F, | 2867 bool NaClBitcodeReader::FindFunctionInStream(Function *F, |
| 2867 DenseMap<Function*, uint64_t>::iterator DeferredFunctionInfoIterator) { | 2868 DenseMap<Function*, uint64_t>::iterator DeferredFunctionInfoIterator) { |
| 2868 while (DeferredFunctionInfoIterator->second == 0) { | 2869 while (DeferredFunctionInfoIterator->second == 0) { |
| 2869 if (Stream.AtEndOfStream()) | 2870 if (Stream.AtEndOfStream()) |
| 2870 return Error("Could not find Function in stream"); | 2871 return Error("Could not find Function in stream"); |
| 2871 // ParseModule will parse the next body in the stream and set its | 2872 // ParseModule will parse the next body in the stream and set its |
| 2872 // position in the DeferredFunctionInfo map. | 2873 // position in the DeferredFunctionInfo map. |
| 2873 if (ParseModule(true)) return true; | 2874 if (ParseModule(true)) return true; |
| 2874 } | 2875 } |
| 2875 return false; | 2876 return false; |
| 2876 } | 2877 } |
| 2877 | 2878 |
| 2878 //===----------------------------------------------------------------------===// | 2879 //===----------------------------------------------------------------------===// |
| 2879 // GVMaterializer implementation | 2880 // GVMaterializer implementation |
| 2880 //===----------------------------------------------------------------------===// | 2881 //===----------------------------------------------------------------------===// |
| 2881 | 2882 |
| 2882 | 2883 |
| 2883 bool BitcodeReader::isMaterializable(const GlobalValue *GV) const { | 2884 bool NaClBitcodeReader::isMaterializable(const GlobalValue *GV) const { |
| 2884 if (const Function *F = dyn_cast<Function>(GV)) { | 2885 if (const Function *F = dyn_cast<Function>(GV)) { |
| 2885 return F->isDeclaration() && | 2886 return F->isDeclaration() && |
| 2886 DeferredFunctionInfo.count(const_cast<Function*>(F)); | 2887 DeferredFunctionInfo.count(const_cast<Function*>(F)); |
| 2887 } | 2888 } |
| 2888 return false; | 2889 return false; |
| 2889 } | 2890 } |
| 2890 | 2891 |
| 2891 bool BitcodeReader::Materialize(GlobalValue *GV, std::string *ErrInfo) { | 2892 bool NaClBitcodeReader::Materialize(GlobalValue *GV, std::string *ErrInfo) { |
| 2892 Function *F = dyn_cast<Function>(GV); | 2893 Function *F = dyn_cast<Function>(GV); |
| 2893 // If it's not a function or is already material, ignore the request. | 2894 // If it's not a function or is already material, ignore the request. |
| 2894 if (!F || !F->isMaterializable()) return false; | 2895 if (!F || !F->isMaterializable()) return false; |
| 2895 | 2896 |
| 2896 DenseMap<Function*, uint64_t>::iterator DFII = DeferredFunctionInfo.find(F); | 2897 DenseMap<Function*, uint64_t>::iterator DFII = DeferredFunctionInfo.find(F); |
| 2897 assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!"); | 2898 assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!"); |
| 2898 // If its position is recorded as 0, its body is somewhere in the stream | 2899 // If its position is recorded as 0, its body is somewhere in the stream |
| 2899 // but we haven't seen it yet. | 2900 // but we haven't seen it yet. |
| 2900 if (DFII->second == 0) | 2901 if (DFII->second == 0) |
| 2901 if (LazyStreamer && FindFunctionInStream(F, DFII)) return true; | 2902 if (LazyStreamer && FindFunctionInStream(F, DFII)) return true; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 2916 UE = I->first->use_end(); UI != UE; ) { | 2917 UE = I->first->use_end(); UI != UE; ) { |
| 2917 if (CallInst* CI = dyn_cast<CallInst>(*UI++)) | 2918 if (CallInst* CI = dyn_cast<CallInst>(*UI++)) |
| 2918 UpgradeIntrinsicCall(CI, I->second); | 2919 UpgradeIntrinsicCall(CI, I->second); |
| 2919 } | 2920 } |
| 2920 } | 2921 } |
| 2921 } | 2922 } |
| 2922 | 2923 |
| 2923 return false; | 2924 return false; |
| 2924 } | 2925 } |
| 2925 | 2926 |
| 2926 bool BitcodeReader::isDematerializable(const GlobalValue *GV) const { | 2927 bool NaClBitcodeReader::isDematerializable(const GlobalValue *GV) const { |
| 2927 const Function *F = dyn_cast<Function>(GV); | 2928 const Function *F = dyn_cast<Function>(GV); |
| 2928 if (!F || F->isDeclaration()) | 2929 if (!F || F->isDeclaration()) |
| 2929 return false; | 2930 return false; |
| 2930 // @LOCALMOD-START | 2931 // @LOCALMOD-START |
| 2931 // Don't dematerialize functions with BBs which have their address taken; | 2932 // Don't dematerialize functions with BBs which have their address taken; |
| 2932 // it will cause any referencing blockAddress constants to also be destroyed, | 2933 // it will cause any referencing blockAddress constants to also be destroyed, |
| 2933 // but because they are GVs, they need to stay around until PassManager | 2934 // but because they are GVs, they need to stay around until PassManager |
| 2934 // finalization. | 2935 // finalization. |
| 2935 for (Function::const_iterator BB = F->begin(); BB != F->end(); ++BB) { | 2936 for (Function::const_iterator BB = F->begin(); BB != F->end(); ++BB) { |
| 2936 if (BB->hasAddressTaken()) | 2937 if (BB->hasAddressTaken()) |
| 2937 return false; | 2938 return false; |
| 2938 } | 2939 } |
| 2939 // @LOCALMOD-END | 2940 // @LOCALMOD-END |
| 2940 return DeferredFunctionInfo.count(const_cast<Function*>(F)); | 2941 return DeferredFunctionInfo.count(const_cast<Function*>(F)); |
| 2941 } | 2942 } |
| 2942 | 2943 |
| 2943 void BitcodeReader::Dematerialize(GlobalValue *GV) { | 2944 void NaClBitcodeReader::Dematerialize(GlobalValue *GV) { |
| 2944 Function *F = dyn_cast<Function>(GV); | 2945 Function *F = dyn_cast<Function>(GV); |
| 2945 // If this function isn't dematerializable, this is a noop. | 2946 // If this function isn't dematerializable, this is a noop. |
| 2946 if (!F || !isDematerializable(F)) | 2947 if (!F || !isDematerializable(F)) |
| 2947 return; | 2948 return; |
| 2948 | 2949 |
| 2949 assert(DeferredFunctionInfo.count(F) && "No info to read function later?"); | 2950 assert(DeferredFunctionInfo.count(F) && "No info to read function later?"); |
| 2950 | 2951 |
| 2951 // Just forget the function body, we can remat it later. | 2952 // Just forget the function body, we can remat it later. |
| 2952 F->deleteBody(); | 2953 F->deleteBody(); |
| 2953 } | 2954 } |
| 2954 | 2955 |
| 2955 | 2956 |
| 2956 bool BitcodeReader::MaterializeModule(Module *M, std::string *ErrInfo) { | 2957 bool NaClBitcodeReader::MaterializeModule(Module *M, std::string *ErrInfo) { |
| 2957 assert(M == TheModule && | 2958 assert(M == TheModule && |
| 2958 "Can only Materialize the Module this BitcodeReader is attached to."); | 2959 "Can only Materialize the Module this NaClBitcodeReader is attached to. "); |
| 2959 // Iterate over the module, deserializing any functions that are still on | 2960 // Iterate over the module, deserializing any functions that are still on |
| 2960 // disk. | 2961 // disk. |
| 2961 for (Module::iterator F = TheModule->begin(), E = TheModule->end(); | 2962 for (Module::iterator F = TheModule->begin(), E = TheModule->end(); |
| 2962 F != E; ++F) | 2963 F != E; ++F) |
| 2963 if (F->isMaterializable() && | 2964 if (F->isMaterializable() && |
| 2964 Materialize(F, ErrInfo)) | 2965 Materialize(F, ErrInfo)) |
| 2965 return true; | 2966 return true; |
| 2966 | 2967 |
| 2967 // At this point, if there are any function bodies, the current bit is | 2968 // At this point, if there are any function bodies, the current bit is |
| 2968 // pointing to the END_BLOCK record after them. Now make sure the rest | 2969 // pointing to the END_BLOCK record after them. Now make sure the rest |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 2985 if (!I->first->use_empty()) | 2986 if (!I->first->use_empty()) |
| 2986 I->first->replaceAllUsesWith(I->second); | 2987 I->first->replaceAllUsesWith(I->second); |
| 2987 I->first->eraseFromParent(); | 2988 I->first->eraseFromParent(); |
| 2988 } | 2989 } |
| 2989 } | 2990 } |
| 2990 std::vector<std::pair<Function*, Function*> >().swap(UpgradedIntrinsics); | 2991 std::vector<std::pair<Function*, Function*> >().swap(UpgradedIntrinsics); |
| 2991 | 2992 |
| 2992 return false; | 2993 return false; |
| 2993 } | 2994 } |
| 2994 | 2995 |
| 2995 bool BitcodeReader::InitStream() { | 2996 bool NaClBitcodeReader::InitStream() { |
| 2996 if (LazyStreamer) return InitLazyStream(); | 2997 if (LazyStreamer) return InitLazyStream(); |
| 2997 return InitStreamFromBuffer(); | 2998 return InitStreamFromBuffer(); |
| 2998 } | 2999 } |
| 2999 | 3000 |
| 3000 bool BitcodeReader::InitStreamFromBuffer() { | 3001 bool NaClBitcodeReader::InitStreamFromBuffer() { |
| 3001 const unsigned char *BufPtr = (const unsigned char*)Buffer->getBufferStart(); | 3002 const unsigned char *BufPtr = (const unsigned char*)Buffer->getBufferStart(); |
| 3002 const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); | 3003 const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); |
| 3003 | 3004 |
| 3004 if (Buffer->getBufferSize() & 3) { | 3005 if (Buffer->getBufferSize() & 3) { |
| 3005 if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd)) | 3006 if (!isNaClRawBitcode(BufPtr, BufEnd) && |
| 3007 !isNaClBitcodeWrapper(BufPtr, BufEnd)) | |
| 3006 return Error("Invalid bitcode signature"); | 3008 return Error("Invalid bitcode signature"); |
| 3007 else | 3009 else |
| 3008 return Error("Bitcode stream should be a multiple of 4 bytes in length"); | 3010 return Error("Bitcode stream should be a multiple of 4 bytes in length"); |
| 3009 } | 3011 } |
| 3010 | 3012 |
| 3011 // If we have a wrapper header, parse it and ignore the non-bc file contents. | 3013 // If we have a wrapper header, parse it and ignore the non-bc file contents. |
| 3012 // The magic number is 0x0B17C0DE stored in little endian. | 3014 // The magic number is 0x0B17C0DE stored in little endian. |
| 3013 if (isBitcodeWrapper(BufPtr, BufEnd)) | 3015 if (isNaClBitcodeWrapper(BufPtr, BufEnd)) |
| 3014 if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true)) | 3016 if (SkipNaClBitcodeWrapperHeader(BufPtr, BufEnd, true)) |
| 3015 return Error("Invalid bitcode wrapper header"); | 3017 return Error("Invalid bitcode wrapper header"); |
| 3016 | 3018 |
| 3017 StreamFile.reset(new BitstreamReader(BufPtr, BufEnd)); | 3019 StreamFile.reset(new NaClBitstreamReader(BufPtr, BufEnd)); |
| 3018 Stream.init(*StreamFile); | 3020 Stream.init(*StreamFile); |
| 3019 | 3021 |
| 3020 return false; | 3022 return false; |
| 3021 } | 3023 } |
| 3022 | 3024 |
| 3023 bool BitcodeReader::InitLazyStream() { | 3025 bool NaClBitcodeReader::InitLazyStream() { |
| 3024 // Check and strip off the bitcode wrapper; BitstreamReader expects never to | 3026 // Check and strip off the bitcode wrapper; NaClBitstreamReader expects |
| 3025 // see it. | 3027 // never to see it. |
| 3026 StreamingMemoryObject *Bytes = new StreamingMemoryObject(LazyStreamer); | 3028 StreamingMemoryObject *Bytes = new StreamingMemoryObject(LazyStreamer); |
| 3027 StreamFile.reset(new BitstreamReader(Bytes)); | 3029 StreamFile.reset(new NaClBitstreamReader(Bytes)); |
| 3028 Stream.init(*StreamFile); | 3030 Stream.init(*StreamFile); |
| 3029 | 3031 |
| 3030 unsigned char buf[16]; | 3032 unsigned char buf[16]; |
| 3031 if (Bytes->readBytes(0, 16, buf, NULL) == -1) | 3033 if (Bytes->readBytes(0, 16, buf, NULL) == -1) |
| 3032 return Error("Bitcode stream must be at least 16 bytes in length"); | 3034 return Error("Bitcode stream must be at least 16 bytes in length"); |
| 3033 | 3035 |
| 3034 if (!isBitcode(buf, buf + 16)) | 3036 if (!isNaClBitcode(buf, buf + 16)) |
| 3035 return Error("Invalid bitcode signature"); | 3037 return Error("Invalid bitcode signature"); |
| 3036 | 3038 |
| 3037 if (isBitcodeWrapper(buf, buf + 4)) { | 3039 if (isNaClBitcodeWrapper(buf, buf + 4)) { |
| 3038 const unsigned char *bitcodeStart = buf; | 3040 const unsigned char *bitcodeStart = buf; |
| 3039 const unsigned char *bitcodeEnd = buf + 16; | 3041 const unsigned char *bitcodeEnd = buf + 16; |
| 3040 SkipBitcodeWrapperHeader(bitcodeStart, bitcodeEnd, false); | 3042 SkipNaClBitcodeWrapperHeader(bitcodeStart, bitcodeEnd, false); |
| 3041 Bytes->dropLeadingBytes(bitcodeStart - buf); | 3043 Bytes->dropLeadingBytes(bitcodeStart - buf); |
| 3042 Bytes->setKnownObjectSize(bitcodeEnd - bitcodeStart); | 3044 Bytes->setKnownObjectSize(bitcodeEnd - bitcodeStart); |
| 3043 } | 3045 } |
| 3044 return false; | 3046 return false; |
| 3045 } | 3047 } |
| 3046 | 3048 |
| 3047 //===----------------------------------------------------------------------===// | 3049 //===----------------------------------------------------------------------===// |
| 3048 // External interface | 3050 // External interface |
| 3049 //===----------------------------------------------------------------------===// | 3051 //===----------------------------------------------------------------------===// |
| 3050 | 3052 |
| 3051 /// getLazyBitcodeModule - lazy function-at-a-time loading from a file. | 3053 /// getNaClLazyBitcodeModule - lazy function-at-a-time loading from a file. |
| 3052 /// | 3054 /// |
| 3053 Module *llvm::getLazyBitcodeModule(MemoryBuffer *Buffer, | 3055 Module *llvm::getNaClLazyBitcodeModule(MemoryBuffer *Buffer, |
| 3054 LLVMContext& Context, | 3056 » » » » LLVMContext& Context, |
|
jvoung (off chromium)
2013/04/29 18:02:08
tabs
Karl
2013/04/29 20:44:37
Done.
| |
| 3055 std::string *ErrMsg) { | 3057 » » » » std::string *ErrMsg) { |
| 3056 Module *M = new Module(Buffer->getBufferIdentifier(), Context); | 3058 Module *M = new Module(Buffer->getBufferIdentifier(), Context); |
| 3057 BitcodeReader *R = new BitcodeReader(Buffer, Context); | 3059 NaClBitcodeReader *R = new NaClBitcodeReader(Buffer, Context); |
| 3058 M->setMaterializer(R); | 3060 M->setMaterializer(R); |
| 3059 if (R->ParseBitcodeInto(M)) { | 3061 if (R->ParseBitcodeInto(M)) { |
| 3060 if (ErrMsg) | 3062 if (ErrMsg) |
| 3061 *ErrMsg = R->getErrorString(); | 3063 *ErrMsg = R->getErrorString(); |
| 3062 | 3064 |
| 3063 delete M; // Also deletes R. | 3065 delete M; // Also deletes R. |
| 3064 return 0; | 3066 return 0; |
| 3065 } | 3067 } |
| 3066 // Have the BitcodeReader dtor delete 'Buffer'. | 3068 // Have the NaClBitcodeReader dtor delete 'Buffer'. |
| 3067 R->setBufferOwned(true); | 3069 R->setBufferOwned(true); |
| 3068 | 3070 |
| 3069 R->materializeForwardReferencedFunctions(); | 3071 R->materializeForwardReferencedFunctions(); |
| 3070 | 3072 |
| 3071 M->convertMetadataToLibraryList(); // @LOCALMOD | 3073 M->convertMetadataToLibraryList(); // @LOCALMOD |
| 3072 | 3074 |
| 3073 return M; | 3075 return M; |
| 3074 } | 3076 } |
| 3075 | 3077 |
| 3076 | 3078 |
| 3077 Module *llvm::getStreamedBitcodeModule(const std::string &name, | 3079 Module *llvm::getNaClStreamedBitcodeModule(const std::string &name, |
| 3078 DataStreamer *streamer, | 3080 » » » » » DataStreamer *streamer, |
|
jvoung (off chromium)
2013/04/29 18:02:08
tabs!
Karl
2013/04/29 20:44:37
Done.
| |
| 3079 LLVMContext &Context, | 3081 » » » » » LLVMContext &Context, |
| 3080 std::string *ErrMsg) { | 3082 » » » » » std::string *ErrMsg) { |
| 3081 Module *M = new Module(name, Context); | 3083 Module *M = new Module(name, Context); |
| 3082 BitcodeReader *R = new BitcodeReader(streamer, Context); | 3084 NaClBitcodeReader *R = new NaClBitcodeReader(streamer, Context); |
| 3083 M->setMaterializer(R); | 3085 M->setMaterializer(R); |
| 3084 if (R->ParseBitcodeInto(M)) { | 3086 if (R->ParseBitcodeInto(M)) { |
| 3085 if (ErrMsg) | 3087 if (ErrMsg) |
| 3086 *ErrMsg = R->getErrorString(); | 3088 *ErrMsg = R->getErrorString(); |
| 3087 delete M; // Also deletes R. | 3089 delete M; // Also deletes R. |
| 3088 return 0; | 3090 return 0; |
| 3089 } | 3091 } |
| 3090 R->setBufferOwned(false); // no buffer to delete | 3092 R->setBufferOwned(false); // no buffer to delete |
| 3091 | 3093 |
| 3092 R->materializeForwardReferencedFunctions(); | 3094 R->materializeForwardReferencedFunctions(); |
| 3093 | 3095 |
| 3094 M->convertMetadataToLibraryList(); // @LOCALMOD | 3096 M->convertMetadataToLibraryList(); // @LOCALMOD |
| 3095 | 3097 |
| 3096 return M; | 3098 return M; |
| 3097 } | 3099 } |
| 3098 | 3100 |
| 3099 /// ParseBitcodeFile - Read the specified bitcode file, returning the module. | 3101 /// NaClParseBitcodeFile - Read the specified bitcode file, returning the module . |
| 3100 /// If an error occurs, return null and fill in *ErrMsg if non-null. | 3102 /// If an error occurs, return null and fill in *ErrMsg if non-null. |
| 3101 Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context, | 3103 Module *llvm::NaClParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context, |
| 3102 std::string *ErrMsg){ | 3104 » » » » std::string *ErrMsg){ |
|
jvoung (off chromium)
2013/04/29 18:02:08
tabs
Karl
2013/04/29 20:44:37
Done.
| |
| 3103 Module *M = getLazyBitcodeModule(Buffer, Context, ErrMsg); | 3105 Module *M = getNaClLazyBitcodeModule(Buffer, Context, ErrMsg); |
| 3104 if (!M) return 0; | 3106 if (!M) return 0; |
| 3105 | 3107 |
| 3106 // Don't let the BitcodeReader dtor delete 'Buffer', regardless of whether | 3108 // Don't let the NaClBitcodeReader dtor delete 'Buffer', regardless of whether |
| 3107 // there was an error. | 3109 // there was an error. |
| 3108 static_cast<BitcodeReader*>(M->getMaterializer())->setBufferOwned(false); | 3110 static_cast<NaClBitcodeReader*>(M->getMaterializer())->setBufferOwned(false); |
| 3109 | 3111 |
| 3110 // Read in the entire module, and destroy the BitcodeReader. | 3112 // Read in the entire module, and destroy the NaClBitcodeReader. |
| 3111 if (M->MaterializeAllPermanently(ErrMsg)) { | 3113 if (M->MaterializeAllPermanently(ErrMsg)) { |
| 3112 delete M; | 3114 delete M; |
| 3113 return 0; | 3115 return 0; |
| 3114 } | 3116 } |
| 3115 | 3117 |
| 3116 // TODO: Restore the use-lists to the in-memory state when the bitcode was | 3118 // TODO: Restore the use-lists to the in-memory state when the bitcode was |
| 3117 // written. We must defer until the Module has been fully materialized. | 3119 // written. We must defer until the Module has been fully materialized. |
| 3118 | 3120 |
| 3119 return M; | 3121 return M; |
| 3120 } | 3122 } |
| 3121 | |
| 3122 std::string llvm::getBitcodeTargetTriple(MemoryBuffer *Buffer, | |
| 3123 LLVMContext& Context, | |
| 3124 std::string *ErrMsg) { | |
| 3125 BitcodeReader *R = new BitcodeReader(Buffer, Context); | |
| 3126 // Don't let the BitcodeReader dtor delete 'Buffer'. | |
| 3127 R->setBufferOwned(false); | |
| 3128 | |
| 3129 std::string Triple(""); | |
| 3130 if (R->ParseTriple(Triple)) | |
|
jvoung (off chromium)
2013/04/29 18:02:08
Any reason this is removed?
The NaClBitcodeReader
Karl
2013/04/29 20:44:37
As far as I can tell, only lto uses it, so thought
jvoung (off chromium)
2013/04/29 21:49:34
Would have been a bit cleaner to do that separatel
| |
| 3131 if (ErrMsg) | |
| 3132 *ErrMsg = R->getErrorString(); | |
| 3133 | |
| 3134 delete R; | |
| 3135 return Triple; | |
| 3136 } | |
| OLD | NEW |