Beginning of the Great Exception Handling Rewrite.
authorBill Wendling <isanbard@gmail.com>
Sun, 10 Apr 2011 00:04:27 +0000 (00:04 +0000)
committerBill Wendling <isanbard@gmail.com>
Sun, 10 Apr 2011 00:04:27 +0000 (00:04 +0000)
* 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

include/llvm/BasicBlock.h
include/llvm/Bitcode/LLVMBitCodes.h
lib/AsmParser/LLLexer.cpp
lib/AsmParser/LLParser.cpp
lib/AsmParser/LLToken.h
lib/Bitcode/Reader/BitcodeReader.cpp
lib/Bitcode/Writer/BitcodeWriter.cpp
lib/VMCore/AsmWriter.cpp
lib/VMCore/BasicBlock.cpp
test/Feature/bb_attrs.ll [new file with mode: 0644]

index 7e7c9e76943d07cf878152346d898fbba9beaae8..3336b3610d3d760767cdc000439c0c8794c1ddea 100644 (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.
   ///
index 7692bd28720bc791b64dbfe4ee875c1e950bcb0d..dcfbe5a6b4c0201f919735bfea19142eac09682e 100644 (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 {
index 857fa1ef626f01d9e4437b2b6fcf49e1a1b5e379..da26cb82106dc121d6dd606726e2fd4e033b3557 100644 (file)
@@ -587,6 +587,8 @@ lltok::Kind LLLexer::LexIdentifier() {
 
   KEYWORD(x);
   KEYWORD(blockaddress);
+
+  KEYWORD(landingpad);
 #undef KEYWORD
 
   // Keywords for types.
index 0c3237a67995fc1425bd875dfa7d6f40fca77c63..afd10a0826f96533e1fb81978e3729d5a094073a 100644 (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.
index 576da191aecf5682764a926c5e19867264e5fd18..53cf8d87f355c7801e90f29164ff710e35cdb8cd 100644 (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
index 8223f76bbbc6a3b9b79cf9356b61a73da23b1535..235519850f0d354a3910389919c3c30ff4e053bf 100644 (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;
index e34137f6155a9d18893dde93a4945e6682a23280..51c13bd50163d6538a7a4dc37c13b3933fd013aa 100644 (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();
index ffd367a7ada216decf255f353c9aad9cc94cb0d4..a92c9bc668d19bf0fc3a0c49af4af4bfbd459157 100644 (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;
index 955a0285b2602056a68ea8dbee0eaa0b5d0e08a5..b46fab590f1ba5fabfbda015a4d7f55cf9e9dcd7 100644 (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
diff --git a/test/Feature/bb_attrs.ll b/test/Feature/bb_attrs.ll
new file mode 100644 (file)
index 0000000..af2af31
--- /dev/null
@@ -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
+}