Skip to content

Commit

Permalink
Beginning of the Great Exception Handling Rewrite.
Browse files Browse the repository at this point in the history
* Add a "landing pad" attribute to the BasicBlock.
* Modify the bitcode reader and writer to handle said attribute.

Later: The verifier will ensure that the landing pad attribute is used in the
appropriate manner. I.e., not applied to the entry block, and applied only to
basic blocks that are branched to via a `dispatch' instruction.

(This is a work-in-progress.)


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129235 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
isanbard committed Apr 10, 2011
1 parent b1145c8 commit d7bb295
Show file tree
Hide file tree
Showing 10 changed files with 87 additions and 16 deletions.
6 changes: 6 additions & 0 deletions include/llvm/BasicBlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class BasicBlock : public Value, // Basic blocks are data objects also
private:
InstListType InstList;
Function *Parent;
bool IsLandingPad;

void setParent(Function *parent);
friend class SymbolTableListTraits<BasicBlock, Function>;
Expand Down Expand Up @@ -138,6 +139,11 @@ class BasicBlock : public Value, // Basic blocks are data objects also
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.
///
Expand Down
5 changes: 3 additions & 2 deletions include/llvm/Bitcode/LLVMBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions lib/AsmParser/LLLexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,8 @@ lltok::Kind LLLexer::LexIdentifier() {

KEYWORD(x);
KEYWORD(blockaddress);

KEYWORD(landingpad);
#undef KEYWORD

// Keywords for types.
Expand Down
5 changes: 5 additions & 0 deletions lib/AsmParser/LLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 3 additions & 0 deletions lib/AsmParser/LLToken.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 7 additions & 2 deletions lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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;
Expand Down
32 changes: 24 additions & 8 deletions lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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();
Expand Down
7 changes: 6 additions & 1 deletion lib/VMCore/AsmWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 2 additions & 3 deletions lib/VMCore/BasicBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
Expand Down
29 changes: 29 additions & 0 deletions test/Feature/bb_attrs.ll
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit d7bb295

Please sign in to comment.