aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/BasicBlock.h6
-rw-r--r--include/llvm/Bitcode/LLVMBitCodes.h5
-rw-r--r--lib/AsmParser/LLLexer.cpp2
-rw-r--r--lib/AsmParser/LLParser.cpp5
-rw-r--r--lib/AsmParser/LLToken.h3
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp9
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp32
-rw-r--r--lib/VMCore/AsmWriter.cpp7
-rw-r--r--lib/VMCore/BasicBlock.cpp5
-rw-r--r--test/Feature/bb_attrs.ll29
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
+}