Beginning of the Great Exception Handling Rewrite.

* 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.)

llvm-svn: 129235
This commit is contained in:
Bill Wendling 2011-04-10 00:04:27 +00:00
parent 7605c67ada
commit 62d49461b6
10 changed files with 87 additions and 16 deletions

View File

@ -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.
///

View File

@ -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 {

View File

@ -587,6 +587,8 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(x);
KEYWORD(blockaddress);
KEYWORD(landingpad);
#undef KEYWORD
// Keywords for types.

View File

@ -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.

View File

@ -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

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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

29
test/Feature/bb_attrs.ll Normal file
View File

@ -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
}