diff options
-rw-r--r-- | include/llvm/BasicBlock.h | 6 | ||||
-rw-r--r-- | include/llvm/Bitcode/LLVMBitCodes.h | 5 | ||||
-rw-r--r-- | lib/AsmParser/LLLexer.cpp | 2 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 5 | ||||
-rw-r--r-- | lib/AsmParser/LLToken.h | 3 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 9 | ||||
-rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 32 | ||||
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 7 | ||||
-rw-r--r-- | lib/VMCore/BasicBlock.cpp | 5 | ||||
-rw-r--r-- | test/Feature/bb_attrs.ll | 29 |
10 files changed, 87 insertions, 16 deletions
diff --git a/include/llvm/BasicBlock.h b/include/llvm/BasicBlock.h index 7e7c9e7694..3336b3610d 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<BasicBlock, Function>; @@ -138,6 +139,11 @@ public: return const_cast<BasicBlock*>(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 7692bd2872..dcfbe5a6b4 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 857fa1ef62..da26cb8210 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 0c3237a679..afd10a0826 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 576da191ae..53cf8d87f3 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 8223f76bbb..235519850f 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 e34137f615..51c13bd501 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<BasicBlock>(SI->getValue())) { - Code = bitc::VST_CODE_BBENTRY; - if (isChar6) - AbbrevToUse = VST_BBENTRY_6_ABBREV; + if (const BasicBlock *BB = dyn_cast<BasicBlock>(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 ffd367a7ad..a92c9bc668 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; <label>:"; + Out << '\n'; + if (BB->isLandingPad()) + Out << "landingpad "; + Out << "; <label>:"; int Slot = Machine.getLocalSlot(BB); if (Slot != -1) Out << Slot; diff --git a/lib/VMCore/BasicBlock.cpp b/lib/VMCore/BasicBlock.cpp index 955a0285b2..b46fab590f 100644 --- a/lib/VMCore/BasicBlock.cpp +++ b/lib/VMCore/BasicBlock.cpp @@ -38,10 +38,10 @@ LLVMContext &BasicBlock::getContext() const { // are not in the public header file... template class llvm::SymbolTableListTraits<Instruction, BasicBlock>; - BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent, BasicBlock *InsertBefore) - : Value(Type::getLabelTy(C), Value::BasicBlockVal), Parent(0) { + : Value(Type::getLabelTy(C), Value::BasicBlockVal), Parent(0), + IsLandingPad(false) { // Make sure that we get added to a function LeakDetector::addGarbageObject(this); @@ -57,7 +57,6 @@ BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent, setName(Name); } - BasicBlock::~BasicBlock() { // If the address of the block is taken and it is being deleted (e.g. because // it is dead), this means that there is either a dangling constant expr diff --git a/test/Feature/bb_attrs.ll b/test/Feature/bb_attrs.ll new file mode 100644 index 0000000000..af2af31d69 --- /dev/null +++ b/test/Feature/bb_attrs.ll @@ -0,0 +1,29 @@ +; RUN: llvm-as < %s | llvm-dis > %t1.ll +; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll +; RUN: diff %t1.ll %t2.ll + +; Test for basic block attributes. + +define i32 @f1(i32 %a) { +entry: + %cmp = icmp slt i32 %a, 37 + br i1 %cmp, label %bb, label %lpad + +bb: + ret i32 37 + +lpad: landingpad + ret i32 927 +} + +define i32 @f2(i32 %a) { +; entry : 0 + %1 = icmp slt i32 %a, 37 + br i1 %1, label %2, label %3 + +; bb : 2 + ret i32 37 + +landingpad ; bb : 3 + ret i32 927 +} |