X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FBitcode%2FWriter%2FBitcodeWriter.cpp;h=1090234fefe342883b1efb732b00e139ef128a16;hb=daaec40323619188f16f744af624de4b30755f56;hp=97caefb4c494aa8866a0df21eac511c9fc411952;hpb=13146c7e3b143f021e3e58a7bdb642e43f8e7b57;p=oota-llvm.git diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 97caefb4c49..1090234fefe 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -162,6 +162,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_ALIGNMENT; case Attribute::AlwaysInline: return bitc::ATTR_KIND_ALWAYS_INLINE; + case Attribute::ArgMemOnly: + return bitc::ATTR_KIND_ARGMEMONLY; case Attribute::Builtin: return bitc::ATTR_KIND_BUILTIN; case Attribute::ByVal: @@ -232,6 +234,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_STACK_PROTECT_REQ; case Attribute::StackProtectStrong: return bitc::ATTR_KIND_STACK_PROTECT_STRONG; + case Attribute::SafeStack: + return bitc::ATTR_KIND_SAFESTACK; case Attribute::StructRet: return bitc::ATTR_KIND_STRUCT_RET; case Attribute::SanitizeAddress: @@ -401,6 +405,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { case Type::LabelTyID: Code = bitc::TYPE_CODE_LABEL; break; case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break; case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break; + case Type::TokenTyID: Code = bitc::TYPE_CODE_TOKEN; break; case Type::IntegerTyID: // INTEGER: [width] Code = bitc::TYPE_CODE_INTEGER; @@ -693,7 +698,7 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, for (const Function &F : *M) { // FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment, // section, visibility, gc, unnamed_addr, prologuedata, - // dllstorageclass, comdat, prefixdata] + // dllstorageclass, comdat, prefixdata, personalityfn] Vals.push_back(VE.getTypeID(F.getFunctionType())); Vals.push_back(F.getCallingConv()); Vals.push_back(F.isDeclaration()); @@ -710,6 +715,8 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, Vals.push_back(F.hasComdat() ? VE.getComdatID(F.getComdat()) : 0); Vals.push_back(F.hasPrefixData() ? (VE.getValueID(F.getPrefixData()) + 1) : 0); + Vals.push_back( + F.hasPersonalityFn() ? (VE.getValueID(F.getPersonalityFn()) + 1) : 0); unsigned AbbrevToUse = 0; Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse); @@ -937,7 +944,8 @@ static void WriteDICompileUnit(const DICompileUnit *N, BitstreamWriter &Stream, SmallVectorImpl &Record, unsigned Abbrev) { - Record.push_back(N->isDistinct()); + assert(N->isDistinct() && "Expected distinct compile units"); + Record.push_back(/* IsDistinct */ true); Record.push_back(N->getSourceLanguage()); Record.push_back(VE.getMetadataOrNullID(N->getFile())); Record.push_back(VE.getMetadataOrNullID(N->getRawProducer())); @@ -1028,6 +1036,17 @@ static void WriteDINamespace(const DINamespace *N, const ValueEnumerator &VE, Record.clear(); } +static void WriteDIModule(const DIModule *N, const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl &Record, unsigned Abbrev) { + Record.push_back(N->isDistinct()); + for (auto &I : N->operands()) + Record.push_back(VE.getMetadataOrNullID(I)); + + Stream.EmitRecord(bitc::METADATA_MODULE, Record, Abbrev); + Record.clear(); +} + static void WriteDITemplateTypeParameter(const DITemplateTypeParameter *N, const ValueEnumerator &VE, BitstreamWriter &Stream, @@ -1083,7 +1102,6 @@ static void WriteDILocalVariable(const DILocalVariable *N, SmallVectorImpl &Record, unsigned Abbrev) { Record.push_back(N->isDistinct()); - Record.push_back(N->getTag()); Record.push_back(VE.getMetadataOrNullID(N->getScope())); Record.push_back(VE.getMetadataOrNullID(N->getRawName())); Record.push_back(VE.getMetadataOrNullID(N->getFile())); @@ -1515,8 +1533,8 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, } else if (isa(C) || isa(C) || isa(C)) { Code = bitc::CST_CODE_AGGREGATE; - for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) - Record.push_back(VE.getValueID(C->getOperand(i))); + for (const Value *Op : C->operands()) + Record.push_back(VE.getValueID(Op)); AbbrevToUse = AggregateAbbrev; } else if (const ConstantExpr *CE = dyn_cast(C)) { switch (CE->getOpcode()) { @@ -1744,13 +1762,17 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, pushValue(I.getOperand(2), InstID, Vals, VE); break; case Instruction::ICmp: - case Instruction::FCmp: + case Instruction::FCmp: { // compare returning Int1Ty or vector of Int1Ty Code = bitc::FUNC_CODE_INST_CMP2; PushValueAndType(I.getOperand(0), InstID, Vals, VE); pushValue(I.getOperand(1), InstID, Vals, VE); Vals.push_back(cast(I).getPredicate()); + uint64_t Flags = GetOptimizationFlags(&I); + if (Flags != 0) + Vals.push_back(Flags); break; + } case Instruction::Ret: { @@ -1830,6 +1852,68 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, Code = bitc::FUNC_CODE_INST_RESUME; PushValueAndType(I.getOperand(0), InstID, Vals, VE); break; + case Instruction::CleanupRet: { + Code = bitc::FUNC_CODE_INST_CLEANUPRET; + const auto &CRI = cast(I); + pushValue(CRI.getCleanupPad(), InstID, Vals, VE); + if (CRI.hasUnwindDest()) + Vals.push_back(VE.getValueID(CRI.getUnwindDest())); + break; + } + case Instruction::CatchRet: { + Code = bitc::FUNC_CODE_INST_CATCHRET; + const auto &CRI = cast(I); + pushValue(CRI.getCatchPad(), InstID, Vals, VE); + Vals.push_back(VE.getValueID(CRI.getSuccessor())); + break; + } + case Instruction::CatchPad: { + Code = bitc::FUNC_CODE_INST_CATCHPAD; + const auto &CPI = cast(I); + Vals.push_back(VE.getValueID(CPI.getNormalDest())); + Vals.push_back(VE.getValueID(CPI.getUnwindDest())); + unsigned NumArgOperands = CPI.getNumArgOperands(); + Vals.push_back(NumArgOperands); + for (unsigned Op = 0; Op != NumArgOperands; ++Op) + PushValueAndType(CPI.getArgOperand(Op), InstID, Vals, VE); + break; + } + case Instruction::TerminatePad: { + Code = bitc::FUNC_CODE_INST_TERMINATEPAD; + const auto &TPI = cast(I); + Vals.push_back(TPI.hasUnwindDest()); + if (TPI.hasUnwindDest()) + Vals.push_back(VE.getValueID(TPI.getUnwindDest())); + unsigned NumArgOperands = TPI.getNumArgOperands(); + Vals.push_back(NumArgOperands); + for (unsigned Op = 0; Op != NumArgOperands; ++Op) + PushValueAndType(TPI.getArgOperand(Op), InstID, Vals, VE); + break; + } + case Instruction::CleanupPad: { + Code = bitc::FUNC_CODE_INST_CLEANUPPAD; + const auto &CPI = cast(I); + unsigned NumOperands = CPI.getNumOperands(); + Vals.push_back(NumOperands); + for (unsigned Op = 0; Op != NumOperands; ++Op) + PushValueAndType(CPI.getOperand(Op), InstID, Vals, VE); + break; + } + case Instruction::CatchEndPad: { + Code = bitc::FUNC_CODE_INST_CATCHENDPAD; + const auto &CEPI = cast(I); + if (CEPI.hasUnwindDest()) + Vals.push_back(VE.getValueID(CEPI.getUnwindDest())); + break; + } + case Instruction::CleanupEndPad: { + Code = bitc::FUNC_CODE_INST_CLEANUPENDPAD; + const auto &CEPI = cast(I); + pushValue(CEPI.getCleanupPad(), InstID, Vals, VE); + if (CEPI.hasUnwindDest()) + Vals.push_back(VE.getValueID(CEPI.getUnwindDest())); + break; + } case Instruction::Unreachable: Code = bitc::FUNC_CODE_INST_UNREACHABLE; AbbrevToUse = FUNCTION_INST_UNREACHABLE_ABBREV; @@ -1857,7 +1941,6 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, const LandingPadInst &LP = cast(I); Code = bitc::FUNC_CODE_INST_LANDINGPAD; Vals.push_back(VE.getTypeID(LP.getType())); - PushValueAndType(LP.getPersonalityFn(), InstID, Vals, VE); Vals.push_back(LP.isCleanup()); Vals.push_back(LP.getNumClauses()); for (unsigned I = 0, E = LP.getNumClauses(); I != E; ++I) { @@ -1882,6 +1965,8 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, assert(AlignRecord < 1 << 5 && "alignment greater than 1 << 64"); AlignRecord |= AI.isUsedWithInAlloca() << 5; AlignRecord |= 1 << 6; + // Reserve bit 7 for SwiftError flag. + // AlignRecord |= AI.isSwiftError() << 7; Vals.push_back(AlignRecord); break; } @@ -1988,6 +2073,24 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, Vals.clear(); } +enum StringEncoding { SE_Char6, SE_Fixed7, SE_Fixed8 }; + +/// Determine the encoding to use for the given string name and length. +static StringEncoding getStringEncoding(const char *Str, unsigned StrLen) { + bool isChar6 = true; + for (const char *C = Str, *E = C + StrLen; C != E; ++C) { + if (isChar6) + isChar6 = BitCodeAbbrevOp::isChar6(*C); + if ((unsigned char)*C & 128) + // don't bother scanning the rest. + return SE_Fixed8; + } + if (isChar6) + return SE_Char6; + else + return SE_Fixed7; +} + // Emit names for globals/functions etc. static void WriteValueSymbolTable(const ValueSymbolTable &VST, const ValueEnumerator &VE, @@ -1999,42 +2102,30 @@ static void WriteValueSymbolTable(const ValueSymbolTable &VST, // FIXME: We know if the type names can use 7-bit ascii. SmallVector NameVals; - for (ValueSymbolTable::const_iterator SI = VST.begin(), SE = VST.end(); - SI != SE; ++SI) { - - const ValueName &Name = *SI; + for (const ValueName &Name : VST) { // Figure out the encoding to use for the name. - bool is7Bit = true; - bool isChar6 = true; - for (const char *C = Name.getKeyData(), *E = C+Name.getKeyLength(); - C != E; ++C) { - if (isChar6) - isChar6 = BitCodeAbbrevOp::isChar6(*C); - if ((unsigned char)*C & 128) { - is7Bit = false; - break; // don't bother scanning the rest. - } - } + StringEncoding Bits = + getStringEncoding(Name.getKeyData(), Name.getKeyLength()); unsigned AbbrevToUse = VST_ENTRY_8_ABBREV; // VST_ENTRY: [valueid, namechar x N] // VST_BBENTRY: [bbid, namechar x N] unsigned Code; - if (isa(SI->getValue())) { + if (isa(Name.getValue())) { Code = bitc::VST_CODE_BBENTRY; - if (isChar6) + if (Bits == SE_Char6) AbbrevToUse = VST_BBENTRY_6_ABBREV; } else { Code = bitc::VST_CODE_ENTRY; - if (isChar6) + if (Bits == SE_Char6) AbbrevToUse = VST_ENTRY_6_ABBREV; - else if (is7Bit) + else if (Bits == SE_Fixed7) AbbrevToUse = VST_ENTRY_7_ABBREV; } - NameVals.push_back(VE.getValueID(SI->getValue())); + NameVals.push_back(VE.getValueID(Name.getValue())); for (const char *P = Name.getKeyData(), *E = Name.getKeyData()+Name.getKeyLength(); P != E; ++P) NameVals.push_back((unsigned char)*P); @@ -2403,10 +2494,7 @@ enum { static void WriteInt32ToBuffer(uint32_t Value, SmallVectorImpl &Buffer, uint32_t &Position) { - Buffer[Position + 0] = (unsigned char) (Value >> 0); - Buffer[Position + 1] = (unsigned char) (Value >> 8); - Buffer[Position + 2] = (unsigned char) (Value >> 16); - Buffer[Position + 3] = (unsigned char) (Value >> 24); + support::endian::write32le(&Buffer[Position], Value); Position += 4; }