diff options
Diffstat (limited to 'contrib/llvm/lib/Bitcode/Reader')
| -rw-r--r-- | contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 206 | 
1 files changed, 110 insertions, 96 deletions
diff --git a/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index e3990403bd71..4ffee38c8eb8 100644 --- a/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -28,6 +28,10 @@  #include "llvm/OperandTraits.h"  using namespace llvm; +enum { +  SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex +}; +  void BitcodeReader::materializeForwardReferencedFunctions() {    while (!BlockAddrFwdRefs.empty()) {      Function *F = BlockAddrFwdRefs.begin()->first; @@ -57,7 +61,7 @@ void BitcodeReader::FreeState() {  /// ConvertToString - Convert a string from a record into an std::string, return  /// true on failure.  template<typename StrTy> -static bool ConvertToString(SmallVector<uint64_t, 64> &Record, unsigned Idx, +static bool ConvertToString(ArrayRef<uint64_t> Record, unsigned Idx,                              StrTy &Result) {    if (Idx > Record.size())      return true; @@ -98,6 +102,17 @@ static GlobalValue::VisibilityTypes GetDecodedVisibility(unsigned Val) {    }  } +static GlobalVariable::ThreadLocalMode GetDecodedThreadLocalMode(unsigned Val) { +  switch (Val) { +    case 0: return GlobalVariable::NotThreadLocal; +    default: // Map unknown non-zero value to general dynamic. +    case 1: return GlobalVariable::GeneralDynamicTLSModel; +    case 2: return GlobalVariable::LocalDynamicTLSModel; +    case 3: return GlobalVariable::InitialExecTLSModel; +    case 4: return GlobalVariable::LocalExecTLSModel; +  } +} +  static int GetDecodedCastOpcode(unsigned Val) {    switch (Val) {    default: return -1; @@ -458,61 +473,19 @@ bool BitcodeReader::ParseAttributeBlock() {        if (Record.size() & 1)          return Error("Invalid ENTRY record"); -      // FIXME : Remove this autoupgrade code in LLVM 3.0. -      // If Function attributes are using index 0 then transfer them -      // to index ~0. Index 0 is used for return value attributes but used to be -      // used for function attributes. -      Attributes RetAttribute; -      Attributes FnAttribute;        for (unsigned i = 0, e = Record.size(); i != e; i += 2) { -        // FIXME: remove in LLVM 3.0 -        // The alignment is stored as a 16-bit raw value from bits 31--16. -        // We shift the bits above 31 down by 11 bits. - -        unsigned Alignment = (Record[i+1] & (0xffffull << 16)) >> 16; -        if (Alignment && !isPowerOf2_32(Alignment)) -          return Error("Alignment is not a power of two."); - -        Attributes ReconstitutedAttr(Record[i+1] & 0xffff); -        if (Alignment) -          ReconstitutedAttr |= Attribute::constructAlignmentFromInt(Alignment); -        ReconstitutedAttr |= -            Attributes((Record[i+1] & (0xffffull << 32)) >> 11); - +        Attributes ReconstitutedAttr = +          Attribute::decodeLLVMAttributesForBitcode(Record[i+1]);          Record[i+1] = ReconstitutedAttr.Raw(); -        if (Record[i] == 0) -          RetAttribute = ReconstitutedAttr; -        else if (Record[i] == ~0U) -          FnAttribute = ReconstitutedAttr; -      } - -      Attributes OldRetAttrs = (Attribute::NoUnwind|Attribute::NoReturn| -                              Attribute::ReadOnly|Attribute::ReadNone); - -      if (FnAttribute == Attribute::None && RetAttribute != Attribute::None && -          (RetAttribute & OldRetAttrs)) { -        if (FnAttribute == Attribute::None) { // add a slot so they get added. -          Record.push_back(~0U); -          Record.push_back(0); -        } - -        FnAttribute  |= RetAttribute & OldRetAttrs; -        RetAttribute &= ~OldRetAttrs;        }        for (unsigned i = 0, e = Record.size(); i != e; i += 2) { -        if (Record[i] == 0) { -          if (RetAttribute != Attribute::None) -            Attrs.push_back(AttributeWithIndex::get(0, RetAttribute)); -        } else if (Record[i] == ~0U) { -          if (FnAttribute != Attribute::None) -            Attrs.push_back(AttributeWithIndex::get(~0U, FnAttribute)); -        } else if (Attributes(Record[i+1]) != Attribute::None) +        if (Attributes(Record[i+1]) != Attribute::None)            Attrs.push_back(AttributeWithIndex::get(Record[i],                                                    Attributes(Record[i+1])));        } -      MAttributes.push_back(AttrListPtr::get(Attrs.begin(), Attrs.end())); +      MAttributes.push_back(AttrListPtr::get(Attrs));        Attrs.clear();        break;      } @@ -621,7 +594,7 @@ bool BitcodeReader::ParseTypeTableBody() {        break;      }      case bitc::TYPE_CODE_FUNCTION_OLD: { -      // FIXME: attrid is dead, remove it in LLVM 3.0 +      // FIXME: attrid is dead, remove it in LLVM 4.0        // FUNCTION: [vararg, attrid, retty, paramty x N]        if (Record.size() < 3)          return Error("Invalid FUNCTION type record"); @@ -851,11 +824,7 @@ bool BitcodeReader::ParseMetadata() {        break;      case bitc::METADATA_NAME: {        // Read named of the named metadata. -      unsigned NameLength = Record.size(); -      SmallString<8> Name; -      Name.resize(NameLength); -      for (unsigned i = 0; i != NameLength; ++i) -        Name[i] = Record[i]; +      SmallString<8> Name(Record.begin(), Record.end());        Record.clear();        Code = Stream.ReadCode(); @@ -899,26 +868,18 @@ bool BitcodeReader::ParseMetadata() {        break;      }      case bitc::METADATA_STRING: { -      unsigned MDStringLength = Record.size(); -      SmallString<8> String; -      String.resize(MDStringLength); -      for (unsigned i = 0; i != MDStringLength; ++i) -        String[i] = Record[i]; -      Value *V = MDString::get(Context, -                               StringRef(String.data(), String.size())); +      SmallString<8> String(Record.begin(), Record.end()); +      Value *V = MDString::get(Context, String);        MDValueList.AssignValue(V, NextMDValueNo++);        break;      }      case bitc::METADATA_KIND: { -      unsigned RecordLength = Record.size(); -      if (Record.empty() || RecordLength < 2) +      if (Record.size() < 2)          return Error("Invalid METADATA_KIND record"); -      SmallString<8> Name; -      Name.resize(RecordLength-1); +        unsigned Kind = Record[0]; -      for (unsigned i = 1; i != RecordLength; ++i) -        Name[i-1] = Record[i]; -       +      SmallString<8> Name(Record.begin()+1, Record.end()); +        unsigned NewKind = TheModule->getMDKindID(Name.str());        if (!MDKindMap.insert(std::make_pair(Kind, NewKind)).second)          return Error("Conflicting METADATA_KIND records"); @@ -977,6 +938,14 @@ bool BitcodeReader::ResolveGlobalAndAliasInits() {    return false;  } +static APInt ReadWideAPInt(ArrayRef<uint64_t> Vals, unsigned TypeBits) { +  SmallVector<uint64_t, 8> Words(Vals.size()); +  std::transform(Vals.begin(), Vals.end(), Words.begin(), +                 DecodeSignRotatedValue); + +  return APInt(TypeBits, Words); +} +  bool BitcodeReader::ParseConstants() {    if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID))      return Error("Malformed block record"); @@ -1032,14 +1001,10 @@ bool BitcodeReader::ParseConstants() {        if (!CurTy->isIntegerTy() || Record.empty())          return Error("Invalid WIDE_INTEGER record"); -      unsigned NumWords = Record.size(); -      SmallVector<uint64_t, 8> Words; -      Words.resize(NumWords); -      for (unsigned i = 0; i != NumWords; ++i) -        Words[i] = DecodeSignRotatedValue(Record[i]); -      V = ConstantInt::get(Context, -                           APInt(cast<IntegerType>(CurTy)->getBitWidth(), -                                 Words)); +      APInt VInt = ReadWideAPInt(Record, +                                 cast<IntegerType>(CurTy)->getBitWidth()); +      V = ConstantInt::get(Context, VInt); +              break;      }      case bitc::CST_CODE_FLOAT: {    // FLOAT: [fpval] @@ -1098,10 +1063,7 @@ bool BitcodeReader::ParseConstants() {        if (Record.empty())          return Error("Invalid CST_STRING record"); -      unsigned Size = Record.size(); -      SmallString<16> Elts; -      for (unsigned i = 0; i != Size; ++i) -        Elts.push_back(Record[i]); +      SmallString<16> Elts(Record.begin(), Record.end());        V = ConstantDataArray::getString(Context, Elts,                                         BitCode == bitc::CST_CODE_CSTRING);        break; @@ -1138,23 +1100,16 @@ bool BitcodeReader::ParseConstants() {          else            V = ConstantDataArray::get(Context, Elts);        } else if (EltTy->isFloatTy()) { -        SmallVector<float, 16> Elts; -        for (unsigned i = 0; i != Size; ++i) { -          union { uint32_t I; float F; }; -          I = Record[i]; -          Elts.push_back(F); -        } +        SmallVector<float, 16> Elts(Size); +        std::transform(Record.begin(), Record.end(), Elts.begin(), BitsToFloat);          if (isa<VectorType>(CurTy))            V = ConstantDataVector::get(Context, Elts);          else            V = ConstantDataArray::get(Context, Elts);        } else if (EltTy->isDoubleTy()) { -        SmallVector<double, 16> Elts; -        for (unsigned i = 0; i != Size; ++i) { -          union { uint64_t I; double F; }; -          I = Record[i]; -          Elts.push_back(F); -        } +        SmallVector<double, 16> Elts(Size); +        std::transform(Record.begin(), Record.end(), Elts.begin(), +                       BitsToDouble);          if (isa<VectorType>(CurTy))            V = ConstantDataVector::get(Context, Elts);          else @@ -1600,9 +1555,10 @@ bool BitcodeReader::ParseModule(bool Resume) {        GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility;        if (Record.size() > 6)          Visibility = GetDecodedVisibility(Record[6]); -      bool isThreadLocal = false; + +      GlobalVariable::ThreadLocalMode TLM = GlobalVariable::NotThreadLocal;        if (Record.size() > 7) -        isThreadLocal = Record[7]; +        TLM = GetDecodedThreadLocalMode(Record[7]);        bool UnnamedAddr = false;        if (Record.size() > 8) @@ -1610,12 +1566,11 @@ bool BitcodeReader::ParseModule(bool Resume) {        GlobalVariable *NewGV =          new GlobalVariable(*TheModule, Ty, isConstant, Linkage, 0, "", 0, -                           isThreadLocal, AddressSpace); +                           TLM, AddressSpace);        NewGV->setAlignment(Alignment);        if (!Section.empty())          NewGV->setSection(Section);        NewGV->setVisibility(Visibility); -      NewGV->setThreadLocal(isThreadLocal);        NewGV->setUnnamedAddr(UnnamedAddr);        ValueList.push_back(NewGV); @@ -1732,7 +1687,7 @@ bool BitcodeReader::ParseBitcodeInto(Module *M) {        // have to read and ignore these final 4 bytes :-(        if (Stream.GetAbbrevIDWidth() == 2 && Code == 2 &&            Stream.Read(6) == 2 && Stream.Read(24) == 0xa0a0a && -	  Stream.AtEndOfStream()) +          Stream.AtEndOfStream())          return false;        return Error("Invalid record at top-level"); @@ -2271,6 +2226,65 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {        break;      }      case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...] +      // Check magic  +      if ((Record[0] >> 16) == SWITCH_INST_MAGIC) { +        // New SwitchInst format with case ranges. +         +        Type *OpTy = getTypeByID(Record[1]); +        unsigned ValueBitWidth = cast<IntegerType>(OpTy)->getBitWidth(); + +        Value *Cond = getFnValueByID(Record[2], OpTy); +        BasicBlock *Default = getBasicBlock(Record[3]); +        if (OpTy == 0 || Cond == 0 || Default == 0) +          return Error("Invalid SWITCH record"); + +        unsigned NumCases = Record[4]; +         +        SwitchInst *SI = SwitchInst::Create(Cond, Default, NumCases); +        InstructionList.push_back(SI); +         +        unsigned CurIdx = 5; +        for (unsigned i = 0; i != NumCases; ++i) { +          IntegersSubsetToBB CaseBuilder; +          unsigned NumItems = Record[CurIdx++]; +          for (unsigned ci = 0; ci != NumItems; ++ci) { +            bool isSingleNumber = Record[CurIdx++]; +             +            APInt Low; +            unsigned ActiveWords = 1; +            if (ValueBitWidth > 64) +              ActiveWords = Record[CurIdx++]; +            Low = ReadWideAPInt(makeArrayRef(&Record[CurIdx], ActiveWords), +                                ValueBitWidth); +            CurIdx += ActiveWords; + +            if (!isSingleNumber) { +              ActiveWords = 1; +              if (ValueBitWidth > 64) +                ActiveWords = Record[CurIdx++]; +              APInt High = +                  ReadWideAPInt(makeArrayRef(&Record[CurIdx], ActiveWords), +                                ValueBitWidth); +               +              CaseBuilder.add(IntItem::fromType(OpTy, Low), +                              IntItem::fromType(OpTy, High)); +              CurIdx += ActiveWords; +            } else +              CaseBuilder.add(IntItem::fromType(OpTy, Low)); +          } +          BasicBlock *DestBB = getBasicBlock(Record[CurIdx++]); +          IntegersSubset Case = CaseBuilder.getCase();  +          SI->addCase(Case, DestBB); +        } +        uint16_t Hash = SI->hash(); +        if (Hash != (Record[0] & 0xFFFF)) +          return Error("Invalid SWITCH record"); +        I = SI; +        break; +      } +       +      // Old SwitchInst format without case ranges. +              if (Record.size() < 3 || (Record.size() & 1) == 0)          return Error("Invalid SWITCH record");        Type *OpTy = getTypeByID(Record[0]);  | 
