summaryrefslogtreecommitdiffstats
path: root/llvm/lib/VMCore
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2008-03-02 02:48:09 +0000
committerNick Lewycky <nicholas@mxc.ca>2008-03-02 02:48:09 +0000
commit3cc9be0b5955278e7f8166b8db3e9ba697902190 (patch)
treec83f9867eeaff118b40bc0d3b010909e7911e45d /llvm/lib/VMCore
parent20bcdba9cadb47c3d8fbf1dd31f2942a7d43b2de (diff)
downloadbcm5719-llvm-3cc9be0b5955278e7f8166b8db3e9ba697902190.tar.gz
bcm5719-llvm-3cc9be0b5955278e7f8166b8db3e9ba697902190.zip
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. llvm-svn: 47802
Diffstat (limited to 'llvm/lib/VMCore')
-rw-r--r--llvm/lib/VMCore/AsmWriter.cpp23
-rw-r--r--llvm/lib/VMCore/BasicBlock.cpp23
2 files changed, 38 insertions, 8 deletions
diff --git a/llvm/lib/VMCore/AsmWriter.cpp b/llvm/lib/VMCore/AsmWriter.cpp
index 55d037db141..595f478c72a 100644
--- a/llvm/lib/VMCore/AsmWriter.cpp
+++ b/llvm/lib/VMCore/AsmWriter.cpp
@@ -1130,7 +1130,7 @@ void AssemblyWriter::printFunction(const Function *F) {
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 @@ void AssemblyWriter::printArgument(const Argument *Arg,
/// 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 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
}
}
- Out << "\n";
+ if (BB->hasName() || !BB->use_empty() || BB->getUnwindDest() ||
+ BB != &BB->getParent()->getEntryBlock())
+ Out << "\n";
if (AnnotationWriter) AnnotationWriter->emitBasicBlockStartAnnot(BB, Out);
diff --git a/llvm/lib/VMCore/BasicBlock.cpp b/llvm/lib/VMCore/BasicBlock.cpp
index 3ab5e961579..f9bead74d25 100644
--- a/llvm/lib/VMCore/BasicBlock.cpp
+++ b/llvm/lib/VMCore/BasicBlock.cpp
@@ -70,8 +70,8 @@ template class SymbolTableListTraits<Instruction, BasicBlock>;
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 @@ BasicBlock::BasicBlock(const std::string &Name, Function *NewParent,
}
setName(Name);
+ unwindDest.init(NULL, this);
+ setUnwindDest(Dest);
}
@@ -113,6 +115,19 @@ void BasicBlock::eraseFromParent() {
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 @@ Instruction* BasicBlock::getFirstNonPHI()
}
void BasicBlock::dropAllReferences() {
+ setUnwindDest(NULL);
for(iterator I = begin(), E = end(); I != E; ++I)
I->dropAllReferences();
}
@@ -177,6 +193,9 @@ void BasicBlock::removePredecessor(BasicBlock *Pred,
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.
OpenPOWER on IntegriCloud