[llvm-commits] [llvm] r47802 - in /llvm/trunk: include/llvm/BasicBlock.h include/llvm/Bitcode/LLVMBitCodes.h lib/AsmParser/LLLexer.cpp lib/AsmParser/llvmAsmParser.y lib/Bitcode/Reader/BitcodeReader.cpp lib/Bitcode/Writer/BitcodeWriter.cpp lib/VMCore/AsmWriter.cpp lib/VMCore/BasicBlock.cpp test/Feature/unwindto.ll tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
Nick Lewycky
nicholas at mxc.ca
Sat Mar 1 18:48:10 PST 2008
Author: nicholas
Date: Sat Mar 1 20:48:09 2008
New Revision: 47802
URL: http://llvm.org/viewvc/llvm-project?rev=47802&view=rev
Log:
Add an unwind_to field to basic blocks, making them Users instead of Values.
This is the first checkin for PR1269, the new EH infrastructure.
Added:
llvm/trunk/test/Feature/unwindto.ll
Modified:
llvm/trunk/include/llvm/BasicBlock.h
llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
llvm/trunk/lib/AsmParser/LLLexer.cpp
llvm/trunk/lib/AsmParser/llvmAsmParser.y
llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
llvm/trunk/lib/VMCore/AsmWriter.cpp
llvm/trunk/lib/VMCore/BasicBlock.cpp
llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
Modified: llvm/trunk/include/llvm/BasicBlock.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BasicBlock.h?rev=47802&r1=47801&r2=47802&view=diff
==============================================================================
--- llvm/trunk/include/llvm/BasicBlock.h (original)
+++ llvm/trunk/include/llvm/BasicBlock.h Sat Mar 1 20:48:09 2008
@@ -49,13 +49,14 @@
/// modifying a program. However, the verifier will ensure that basic blocks
/// are "well formed".
/// @brief LLVM Basic Block Representation
-class BasicBlock : public Value { // Basic blocks are data objects also
+class BasicBlock : public User { // Basic blocks are data objects also
public:
typedef iplist<Instruction> InstListType;
private :
InstListType InstList;
BasicBlock *Prev, *Next; // Next and Prev links for our intrusive linked list
Function *Parent;
+ Use unwindDest;
void setParent(Function *parent);
void setNext(BasicBlock *N) { Next = N; }
@@ -75,9 +76,20 @@
/// InsertBefore is null), or before the specified basic block.
///
explicit BasicBlock(const std::string &Name = "", Function *Parent = 0,
- BasicBlock *InsertBefore = 0);
+ BasicBlock *InsertBefore = 0, BasicBlock *unwindDest = 0);
~BasicBlock();
+ /// getUnwindDest - Returns the BasicBlock that flow will enter if an unwind
+ /// instruction occurs in this block. May be null, in which case unwinding
+ /// is undefined in this block.
+ const BasicBlock *getUnwindDest() const;
+ BasicBlock *getUnwindDest();
+
+ /// setUnwindDest - Set which BasicBlock flow will enter if an unwind is
+ /// executed within this block. It may be set to null if unwinding is not
+ /// permitted in this block.
+ void setUnwindDest(BasicBlock *unwindDest);
+
/// getParent - Return the enclosing method, or null if none
///
const Function *getParent() const { return Parent; }
Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h?rev=47802&r1=47801&r2=47802&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h (original)
+++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h Sat Mar 1 20:48:09 2008
@@ -202,7 +202,9 @@
// this is so information only available in the pointer type (e.g. address
// spaces) is retained.
FUNC_CODE_INST_STORE2 = 24, // STORE: [ptrty,ptr,val, align, vol]
- FUNC_CODE_INST_GETRESULT = 25 // GETRESULT: [ty, opval, n]
+ FUNC_CODE_INST_GETRESULT = 25, // GETRESULT: [ty, opval, n]
+
+ FUNC_CODE_INST_BB_UNWINDDEST = 26 // BB_UNWINDDEST: [bb#]
};
} // End bitc namespace
} // End llvm namespace
Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=47802&r1=47801&r2=47802&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLLexer.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLLexer.cpp Sat Mar 1 20:48:09 2008
@@ -474,6 +474,7 @@
KEYWORD("asm", ASM_TOK);
KEYWORD("sideeffect", SIDEEFFECT);
KEYWORD("gc", GC);
+ KEYWORD("unwind_to", UNWIND_TO);
KEYWORD("cc", CC_TOK);
KEYWORD("ccc", CCC_TOK);
Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.y
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/llvmAsmParser.y?rev=47802&r1=47801&r2=47802&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/llvmAsmParser.y (original)
+++ llvm/trunk/lib/AsmParser/llvmAsmParser.y Sat Mar 1 20:48:09 2008
@@ -518,7 +518,7 @@
/// defineBBVal - This is a definition of a new basic block with the specified
/// identifier which must be the same as CurFun.NextValNum, if its numeric.
-static BasicBlock *defineBBVal(const ValID &ID) {
+static BasicBlock *defineBBVal(const ValID &ID, BasicBlock *unwindDest) {
assert(inFunctionScope() && "Can't get basic block at global scope!");
BasicBlock *BB = 0;
@@ -548,21 +548,19 @@
assert(ID.Num == CurFun.NextValNum && "Invalid new block number");
InsertValue(BB);
}
-
- ID.destroy();
- return BB;
- }
-
- // We haven't seen this BB before and its first mention is a definition.
- // Just create it and return it.
- std::string Name (ID.Type == ValID::LocalName ? ID.getName() : "");
- BB = new BasicBlock(Name, CurFun.CurrentFunction);
- if (ID.Type == ValID::LocalID) {
- assert(ID.Num == CurFun.NextValNum && "Invalid new block number");
- InsertValue(BB);
+ } else {
+ // We haven't seen this BB before and its first mention is a definition.
+ // Just create it and return it.
+ std::string Name (ID.Type == ValID::LocalName ? ID.getName() : "");
+ BB = new BasicBlock(Name, CurFun.CurrentFunction);
+ if (ID.Type == ValID::LocalID) {
+ assert(ID.Num == CurFun.NextValNum && "Invalid new block number");
+ InsertValue(BB);
+ }
}
- ID.destroy(); // Free strdup'd memory
+ ID.destroy();
+ BB->setUnwindDest(unwindDest);
return BB;
}
@@ -1066,7 +1064,7 @@
%token OPAQUE EXTERNAL TARGET TRIPLE ALIGN ADDRSPACE
%token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
%token CC_TOK CCC_TOK FASTCC_TOK COLDCC_TOK X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
-%token DATALAYOUT
+%token DATALAYOUT UNWIND_TO
%type <UIntVal> OptCallingConv
%type <ParamAttrs> OptParamAttrs ParamAttr
%type <ParamAttrs> OptFuncAttrs FuncAttr
@@ -2568,14 +2566,22 @@
CHECK_FOR_ERROR
}
| /* empty */ { // Empty space between instruction lists
- $$ = defineBBVal(ValID::createLocalID(CurFun.NextValNum));
+ $$ = defineBBVal(ValID::createLocalID(CurFun.NextValNum), 0);
+ CHECK_FOR_ERROR
+ }
+ | UNWIND_TO ValueRef { // Only the unwind to block
+ $$ = defineBBVal(ValID::createLocalID(CurFun.NextValNum), getBBVal($2));
CHECK_FOR_ERROR
}
| LABELSTR { // Labelled (named) basic block
- $$ = defineBBVal(ValID::createLocalName(*$1));
+ $$ = defineBBVal(ValID::createLocalName(*$1), 0);
+ delete $1;
+ CHECK_FOR_ERROR
+ }
+ | LABELSTR UNWIND_TO ValueRef {
+ $$ = defineBBVal(ValID::createLocalName(*$1), getBBVal($3));
delete $1;
CHECK_FOR_ERROR
-
};
BBTerminatorInst :
Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=47802&r1=47801&r2=47802&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Sat Mar 1 20:48:09 2008
@@ -1216,6 +1216,15 @@
CurBB = FunctionBBs[0];
continue;
+ case bitc::FUNC_CODE_INST_BB_UNWINDDEST: // BB_UNWINDDEST: [bb#]
+ if (CurBB->getUnwindDest())
+ return Error("Only permit one BB_UNWINDDEST per BB");
+ if (Record.size() != 1)
+ return Error("Invalid BB_UNWINDDEST record");
+
+ CurBB->setUnwindDest(getBasicBlock(Record[0]));
+ continue;
+
case bitc::FUNC_CODE_INST_BINOP: { // BINOP: [opval, ty, opval, opcode]
unsigned OpNum = 0;
Value *LHS, *RHS;
Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=47802&r1=47801&r2=47802&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Sat Mar 1 20:48:09 2008
@@ -969,13 +969,20 @@
unsigned InstID = CstEnd;
// Finally, emit all the instructions, in order.
- for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+ for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
+ if (const BasicBlock *unwindDest = BB->getUnwindDest()) {
+ Vals.push_back(VE.getValueID(unwindDest));
+ Stream.EmitRecord(bitc::FUNC_CODE_INST_BB_UNWINDDEST, Vals);
+ Vals.clear();
+ }
+
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
I != E; ++I) {
WriteInstruction(*I, InstID, VE, Stream, Vals);
if (I->getType() != Type::VoidTy)
++InstID;
}
+ }
// Emit names for all the instructions etc.
WriteValueSymbolTable(F.getValueSymbolTable(), VE, Stream);
Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=47802&r1=47801&r2=47802&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/AsmWriter.cpp (original)
+++ llvm/trunk/lib/VMCore/AsmWriter.cpp Sat Mar 1 20:48:09 2008
@@ -1130,7 +1130,7 @@
if (F->isDeclaration()) {
Out << "\n";
} else {
- Out << " {";
+ Out << " {\n";
// Output all of its basic blocks... for the function
for (Function::const_iterator I = F->begin(), E = F->end(); I != E; ++I)
@@ -1162,10 +1162,19 @@
/// printBasicBlock - This member is called for each basic block in a method.
///
void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
- if (BB->hasName()) { // Print out the label if it exists...
- Out << "\n" << getLLVMName(BB->getName(), LabelPrefix) << ':';
- } else if (!BB->use_empty()) { // Don't print block # of no uses...
- Out << "\n; <label>:";
+ if (BB->hasName()) // Print out the label if it exists...
+ Out << getLLVMName(BB->getName(), LabelPrefix) << ':';
+
+ if (const BasicBlock* unwindDest = BB->getUnwindDest()) {
+ if (BB->hasName())
+ Out << ' ';
+
+ Out << "unwind_to";
+ writeOperand(unwindDest, false);
+ }
+
+ if (!BB->hasName() && !BB->use_empty()) { // Don't print block # of no uses...
+ Out << "; <label>:";
int Slot = Machine.getLocalSlot(BB);
if (Slot != -1)
Out << Slot;
@@ -1194,7 +1203,9 @@
}
}
- Out << "\n";
+ if (BB->hasName() || !BB->use_empty() || BB->getUnwindDest() ||
+ BB != &BB->getParent()->getEntryBlock())
+ Out << "\n";
if (AnnotationWriter) AnnotationWriter->emitBasicBlockStartAnnot(BB, Out);
Modified: llvm/trunk/lib/VMCore/BasicBlock.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/BasicBlock.cpp?rev=47802&r1=47801&r2=47802&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/BasicBlock.cpp (original)
+++ llvm/trunk/lib/VMCore/BasicBlock.cpp Sat Mar 1 20:48:09 2008
@@ -70,8 +70,8 @@
BasicBlock::BasicBlock(const std::string &Name, Function *NewParent,
- BasicBlock *InsertBefore)
- : Value(Type::LabelTy, Value::BasicBlockVal), Parent(0) {
+ BasicBlock *InsertBefore, BasicBlock *Dest)
+ : User(Type::LabelTy, Value::BasicBlockVal, &unwindDest, 0), Parent(0) {
// Make sure that we get added to a function
LeakDetector::addGarbageObject(this);
@@ -85,6 +85,8 @@
}
setName(Name);
+ unwindDest.init(NULL, this);
+ setUnwindDest(Dest);
}
@@ -113,6 +115,19 @@
getParent()->getBasicBlockList().erase(this);
}
+const BasicBlock *BasicBlock::getUnwindDest() const {
+ return cast_or_null<const BasicBlock>(unwindDest.get());
+}
+
+BasicBlock *BasicBlock::getUnwindDest() {
+ return cast_or_null<BasicBlock>(unwindDest.get());
+}
+
+void BasicBlock::setUnwindDest(BasicBlock *dest) {
+ NumOperands = unwindDest ? 1 : 0;
+ unwindDest.set(dest);
+}
+
/// moveBefore - Unlink this basic block from its current function and
/// insert it into the function that MovePos lives in, right before MovePos.
void BasicBlock::moveBefore(BasicBlock *MovePos) {
@@ -151,6 +166,7 @@
}
void BasicBlock::dropAllReferences() {
+ setUnwindDest(NULL);
for(iterator I = begin(), E = end(); I != E; ++I)
I->dropAllReferences();
}
@@ -177,6 +193,9 @@
find(pred_begin(this), pred_end(this), Pred) != pred_end(this)) &&
"removePredecessor: BB is not a predecessor!");
+ if (Pred == getUnwindDest())
+ setUnwindDest(NULL);
+
if (InstList.empty()) return;
PHINode *APN = dyn_cast<PHINode>(&front());
if (!APN) return; // Quick exit.
Added: llvm/trunk/test/Feature/unwindto.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/unwindto.ll?rev=47802&view=auto
==============================================================================
--- llvm/trunk/test/Feature/unwindto.ll (added)
+++ llvm/trunk/test/Feature/unwindto.ll Sat Mar 1 20:48:09 2008
@@ -0,0 +1,48 @@
+; RUN: llvm-as < %s | llvm-dis | llvm-as -disable-output
+; PR1269
+; END
+; http://nondot.org/sabre/LLVMNotes/ExceptionHandlingChanges.txt
+
+define i1 @test1(i8 %i, i8 %j) {
+entry: unwind_to %target
+ %tmp = sub i8 %i, %j ; <i8> [#uses=1]
+ %b = icmp eq i8 %tmp, 0 ; <i1> [#uses=1]
+ ret i1 %b
+target:
+ ret i1 false
+}
+
+define i1 @test2(i8 %i, i8 %j) {
+unwind_to %1
+ %tmp = sub i8 %i, %j ; <i8> [#uses=1]
+ %b = icmp eq i8 %tmp, 0 ; <i1> [#uses=1]
+ ret i1 %b
+ ; No predecessors!
+ ret i1 false
+}
+
+define i1 @test3(i8 %i, i8 %j) {
+unwind_to %1
+ %tmp = sub i8 %i, %j ; <i8> [#uses=1]
+ %b = icmp eq i8 %tmp, 0 ; <i1> [#uses=1]
+ ret i1 %b
+unwind_to %0
+ ret i1 false
+}
+
+define i1 @test4(i8 %i, i8 %j) {
+ %tmp = sub i8 %i, %j ; <i8> [#uses=1]
+ %b = icmp eq i8 %tmp, 0 ; <i1> [#uses=1]
+ br label %1
+unwind_to %1
+ ret i1 false
+}
+
+define void @test5() {
+ unwind
+}
+
+define void @test6() {
+unwind: unwind_to %unwind
+ unwind
+}
Modified: llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp?rev=47802&r1=47801&r2=47802&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp (original)
+++ llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp Sat Mar 1 20:48:09 2008
@@ -172,6 +172,7 @@
switch (CodeID) {
default: return 0;
case bitc::FUNC_CODE_DECLAREBLOCKS: return "DECLAREBLOCKS";
+ case bitc::FUNC_CODE_INST_BB_UNWINDDEST: return "UNWINDDEST";
case bitc::FUNC_CODE_INST_BINOP: return "INST_BINOP";
case bitc::FUNC_CODE_INST_CAST: return "INST_CAST";
More information about the llvm-commits
mailing list