diff --git a/include/llvm/BasicBlock.h b/include/llvm/BasicBlock.h index 7e7c9e76943..3336b3610d3 100644 --- a/include/llvm/BasicBlock.h +++ b/include/llvm/BasicBlock.h @@ -74,6 +74,7 @@ public: private: InstListType InstList; Function *Parent; + bool IsLandingPad; void setParent(Function *parent); friend class SymbolTableListTraits; @@ -138,6 +139,11 @@ public: return const_cast(this)->getFirstNonPHIOrDbg(); } + /// isLandingPad - True if this basic block is a landing pad for exception + /// handling. + bool isLandingPad() const { return IsLandingPad; } + void setIsLandingPad(bool Val = true) { IsLandingPad = Val; } + /// removeFromParent - This method unlinks 'this' from the containing /// function, but does not delete it. /// diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index 7692bd28720..dcfbe5a6b4c 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -106,8 +106,9 @@ namespace bitc { // The value symbol table only has one code (VST_ENTRY_CODE). enum ValueSymtabCodes { - VST_CODE_ENTRY = 1, // VST_ENTRY: [valid, namechar x N] - VST_CODE_BBENTRY = 2 // VST_BBENTRY: [bbid, namechar x N] + VST_CODE_ENTRY = 1, // VST_ENTRY: [valid, namechar x N] + VST_CODE_BBENTRY = 2, // VST_BBENTRY: [bbid, namechar x N] + VST_CODE_LPADENTRY = 3 // VST_LPADENTRY: [lpadid, namechar x N] }; enum MetadataCodes { diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 857fa1ef626..da26cb82106 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -587,6 +587,8 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(x); KEYWORD(blockaddress); + + KEYWORD(landingpad); #undef KEYWORD // Keywords for types. diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 0c3237a6799..afd10a0826f 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -2918,6 +2918,11 @@ bool LLParser::ParseBasicBlock(PerFunctionState &PFS) { BasicBlock *BB = PFS.DefineBB(Name, NameLoc); if (BB == 0) return true; + if (Lex.getKind() == lltok::kw_landingpad) { + BB->setIsLandingPad(); + Lex.Lex(); + } + std::string NameStr; // Parse the instructions in this block until we get a terminator. diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index 576da191aec..53cf8d87f35 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -125,6 +125,9 @@ namespace lltok { kw_extractelement, kw_insertelement, kw_shufflevector, kw_getresult, kw_extractvalue, kw_insertvalue, kw_blockaddress, + // Basic block attribute. + kw_landingpad, + // Unsigned Valued tokens (UIntVal). GlobalID, // @42 LocalVarID, // %42 diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 8223f76bbbc..235519850f0 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -714,7 +714,8 @@ bool BitcodeReader::ParseValueSymbolTable() { // Read a record. Record.clear(); - switch (Stream.ReadRecord(Code, Record)) { + unsigned VSTCode = Stream.ReadRecord(Code, Record); + switch (VSTCode) { default: // Default behavior: unknown type. break; case bitc::VST_CODE_ENTRY: { // VST_ENTRY: [valueid, namechar x N] @@ -729,13 +730,17 @@ bool BitcodeReader::ParseValueSymbolTable() { ValueName.clear(); break; } - case bitc::VST_CODE_BBENTRY: { + case bitc::VST_CODE_BBENTRY: + case bitc::VST_CODE_LPADENTRY: { if (ConvertToString(Record, 1, ValueName)) return Error("Invalid VST_BBENTRY record"); BasicBlock *BB = getBasicBlock(Record[0]); if (BB == 0) return Error("Invalid BB ID in VST_BBENTRY record"); + if (VSTCode == bitc::VST_CODE_LPADENTRY) + BB->setIsLandingPad(true); + BB->setName(StringRef(ValueName.data(), ValueName.size())); ValueName.clear(); break; diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index e34137f6155..51c13bd5016 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -40,6 +40,7 @@ enum { VST_ENTRY_7_ABBREV, VST_ENTRY_6_ABBREV, VST_BBENTRY_6_ABBREV, + VST_LPADENTRY_6_ABBREV, // CONSTANTS_BLOCK abbrev id's. CONSTANTS_SETTYPE_ABBREV = bitc::FIRST_APPLICATION_ABBREV, @@ -1179,13 +1180,20 @@ static void WriteValueSymbolTable(const ValueSymbolTable &VST, unsigned AbbrevToUse = VST_ENTRY_8_ABBREV; - // VST_ENTRY: [valueid, namechar x N] - // VST_BBENTRY: [bbid, namechar x N] + // VST_ENTRY: [valueid, namechar x N] + // VST_BBENTRY: [bbid, namechar x N] + // VST_LPADENTRY: [lpadid, namechar x N] unsigned Code; - if (isa(SI->getValue())) { - Code = bitc::VST_CODE_BBENTRY; - if (isChar6) - AbbrevToUse = VST_BBENTRY_6_ABBREV; + if (const BasicBlock *BB = dyn_cast(SI->getValue())) { + if (BB->isLandingPad()) { + Code = bitc::VST_CODE_LPADENTRY; + if (isChar6) + AbbrevToUse = VST_LPADENTRY_6_ABBREV; + } else { + Code = bitc::VST_CODE_BBENTRY; + if (isChar6) + AbbrevToUse = VST_BBENTRY_6_ABBREV; + } } else { Code = bitc::VST_CODE_ENTRY; if (isChar6) @@ -1366,8 +1374,16 @@ static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) { Abbv) != VST_BBENTRY_6_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } - - + { // 6-bit char6 VST_LPADENTRY strings. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_LPADENTRY)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); + if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID, + Abbv) != VST_LPADENTRY_6_ABBREV) + llvm_unreachable("Unexpected abbrev ordering!"); + } { // SETTYPE abbrev for CONSTANTS_BLOCK. BitCodeAbbrev *Abbv = new BitCodeAbbrev(); diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index ffd367a7ada..a92c9bc668d 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -1687,8 +1687,13 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { Out << "\n"; PrintLLVMName(Out, BB->getName(), LabelPrefix); Out << ':'; + if (BB->isLandingPad()) + Out << " landingpad"; } else if (!BB->use_empty()) { // Don't print block # of no uses... - Out << "\n;