[llvm-commits] [llvm] r98579 - in /llvm/trunk: include/llvm/CodeGen/MachineModuleInfo.h lib/CodeGen/AsmPrinter/AsmPrinter.cpp lib/CodeGen/MachineModuleInfo.cpp test/CodeGen/Generic/addr-label.ll test/CodeGen/X86/crash.ll

Chris Lattner sabre at nondot.org
Mon Mar 15 13:39:01 PDT 2010


Author: lattner
Date: Mon Mar 15 15:39:00 2010
New Revision: 98579

URL: http://llvm.org/viewvc/llvm-project?rev=98579&view=rev
Log:
Implement support for the case when a reference to a addr-of-bb 
label is generated, but then the block is deleted.  Since the
value is undefined, we just emit the label right after the entry 
label of the function.  It might matter that the label is in the
same section as the function was afterall.


Added:
    llvm/trunk/test/CodeGen/Generic/addr-label.ll
Modified:
    llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp
    llvm/trunk/test/CodeGen/X86/crash.ll

Modified: llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h?rev=98579&r1=98578&r2=98579&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineModuleInfo.h Mon Mar 15 15:39:00 2010
@@ -214,6 +214,14 @@
   /// block when its address is taken.  This cannot be its normal LBB label
   /// because the block may be accessed outside its containing function.
   MCSymbol *getAddrLabelSymbol(const BasicBlock *BB);
+
+  /// takeDeletedSymbolsForFunction - If the specified function has had any
+  /// references to address-taken blocks generated, but the block got deleted,
+  /// return the symbol now so we can emit it.  This prevents emitting a
+  /// reference to a symbol that has no definition.
+  void takeDeletedSymbolsForFunction(const Function *F, 
+                                     std::vector<MCSymbol*> &Result);
+
   
   //===- EH ---------------------------------------------------------------===//
 

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=98579&r1=98578&r2=98579&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Mon Mar 15 15:39:00 2010
@@ -307,6 +307,16 @@
   // do their wild and crazy things as required.
   EmitFunctionEntryLabel();
   
+  // If the function had address-taken blocks that got deleted, then we have
+  // references to the dangling symbols.  Emit them at the start of the function
+  // so that we don't get references to undefined symbols.
+  std::vector<MCSymbol*> DeadBlockSyms;
+  MMI->takeDeletedSymbolsForFunction(F, DeadBlockSyms);
+  for (unsigned i = 0, e = DeadBlockSyms.size(); i != e; ++i) {
+    OutStreamer.AddComment("Address taken block that was later removed");
+    OutStreamer.EmitLabel(DeadBlockSyms[i]);
+  }
+  
   // Add some workaround for linkonce linkage on Cygwin\MinGW.
   if (MAI->getLinkOnceDirective() != 0 &&
       (F->hasLinkOnceLinkage() || F->hasWeakLinkage()))

Modified: llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp?rev=98579&r1=98578&r2=98579&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp Mon Mar 15 15:39:00 2010
@@ -52,18 +52,35 @@
 class MMIAddrLabelMap {
   MCContext &Context;
   struct AddrLabelSymEntry {
-    MCSymbol *Sym;
-    unsigned Index;
+    MCSymbol *Sym;  // The symbol for the label.
+    Function *Fn;   // The containing function of the BasicBlock.
+    unsigned Index; // The index in BBCallbacks for the BasicBlock.
   };
   
   DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols;
   
+  /// BBCallbacks - Callbacks for the BasicBlock's that we have entries for.  We
+  /// use this so we get notified if a block is deleted or RAUWd.
   std::vector<MMIAddrLabelMapCallbackPtr> BBCallbacks;
+
+  /// DeletedAddrLabelsNeedingEmission - This is a per-function list of symbols
+  /// whose corresponding BasicBlock got deleted.  These symbols need to be
+  /// emitted at some point in the file, so AsmPrinter emits them after the
+  /// function body.
+  DenseMap<AssertingVH<Function>, std::vector<MCSymbol*> >
+    DeletedAddrLabelsNeedingEmission;
 public:
   
   MMIAddrLabelMap(MCContext &context) : Context(context) {}
+  ~MMIAddrLabelMap() {
+    assert(DeletedAddrLabelsNeedingEmission.empty() &&
+           "Some labels for deleted blocks never got emitted");
+  }
   
   MCSymbol *getAddrLabelSymbol(BasicBlock *BB);  
+  void takeDeletedSymbolsForFunction(Function *F, 
+                                     std::vector<MCSymbol*> &Result);
+
   void UpdateForDeletedBlock(BasicBlock *BB);
   void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New);
 };
@@ -75,16 +92,36 @@
   AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];
   
   // If we already had an entry for this block, just return it.
-  if (Entry.Sym) return Entry.Sym;
+  if (Entry.Sym) {
+    assert(BB->getParent() == Entry.Fn && "Parent changed");
+    return Entry.Sym;
+  }
   
   // Otherwise, this is a new entry, create a new symbol for it and add an
   // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd.
   BBCallbacks.push_back(BB);
   BBCallbacks.back().setMap(this);
   Entry.Index = BBCallbacks.size()-1;
+  Entry.Fn = BB->getParent();
   return Entry.Sym = Context.CreateTempSymbol();
 }
 
+/// takeDeletedSymbolsForFunction - If we have any deleted symbols for F, return
+/// them.
+void MMIAddrLabelMap::
+takeDeletedSymbolsForFunction(Function *F, std::vector<MCSymbol*> &Result) {
+  DenseMap<AssertingVH<Function>, std::vector<MCSymbol*> >::iterator I =
+    DeletedAddrLabelsNeedingEmission.find(F);
+
+  // If there are no entries for the function, just return.
+  if (I == DeletedAddrLabelsNeedingEmission.end()) return;
+  
+  // Otherwise, take the list.
+  std::swap(Result, I->second);
+  DeletedAddrLabelsNeedingEmission.erase(I);
+}
+
+
 void MMIAddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) {
   // If the block got deleted, there is no need for the symbol.  If the symbol
   // was already emitted, we can just forget about it, otherwise we need to
@@ -98,9 +135,13 @@
     return;
   
   // If the block is not yet defined, we need to emit it at the end of the
-  // function.
-  assert(0 && "Case not handled yet!");
-  abort();
+  // function.  Add the symbol to the DeletedAddrLabelsNeedingEmission list for
+  // the containing Function.  Since the block is being deleted, its parent may
+  // already be removed, we have to get the function from 'Entry'.
+  assert((BB->getParent() == 0 || BB->getParent() == Entry.Fn) &&
+         "Block/parent mismatch");
+  
+  DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Entry.Sym);
 }
 
 void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) {
@@ -219,6 +260,18 @@
   return AddrLabelSymbols->getAddrLabelSymbol(const_cast<BasicBlock*>(BB));
 }
 
+/// takeDeletedSymbolsForFunction - If the specified function has had any
+/// references to address-taken blocks generated, but the block got deleted,
+/// return the symbol now so we can emit it.  This prevents emitting a
+/// reference to a symbol that has no definition.
+void MachineModuleInfo::
+takeDeletedSymbolsForFunction(const Function *F,
+                              std::vector<MCSymbol*> &Result) {
+  // If no blocks have had their addresses taken, we're done.
+  if (AddrLabelSymbols == 0) return;
+  return AddrLabelSymbols->
+     takeDeletedSymbolsForFunction(const_cast<Function*>(F), Result);
+}
 
 //===- EH -----------------------------------------------------------------===//
 

Added: llvm/trunk/test/CodeGen/Generic/addr-label.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/addr-label.ll?rev=98579&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Generic/addr-label.ll (added)
+++ llvm/trunk/test/CodeGen/Generic/addr-label.ll Mon Mar 15 15:39:00 2010
@@ -0,0 +1,39 @@
+; RUN: llc %s -o -
+
+;; Reference to a label that gets deleted.
+define i8* @test1() nounwind {
+entry:
+	ret i8* blockaddress(@test1b, %test_label)
+}
+
+define i32 @test1b() nounwind {
+entry:
+	ret i32 -1
+test_label:
+	br label %ret
+ret:
+	ret i32 -1
+}
+
+
+;; Issues with referring to a label that gets RAUW'd later.
+define i32 @test2a() nounwind {
+entry:
+        %target = bitcast i8* blockaddress(@test2b, %test_label) to i8*
+
+        call i32 @test2b(i8* %target)
+
+        ret i32 0
+}
+
+define i32 @test2b(i8* %target) nounwind {
+entry:
+        indirectbr i8* %target, [label %test_label]
+
+test_label:
+; assume some code here...
+        br label %ret
+
+ret:
+        ret i32 -1
+}

Modified: llvm/trunk/test/CodeGen/X86/crash.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/crash.ll?rev=98579&r1=98578&r2=98579&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/crash.ll (original)
+++ llvm/trunk/test/CodeGen/X86/crash.ll Mon Mar 15 15:39:00 2010
@@ -92,26 +92,3 @@
 }
 
 
-;; Issues with referring to a label that gets RAUW'd later.
-define i32 @test6a() nounwind {
-entry:
-	%target = bitcast i8* blockaddress(@test6b, %test_label) to i8*
-
-	call i32 @test6b(i8* %target)
-
-	ret i32 0
-}
-
-define i32 @test6b(i8* %target) nounwind {
-entry:
-	indirectbr i8* %target, [label %test_label]
-
-test_label:
-; assume some code here...
-	br label %ret
-
-ret:
-	ret i32 -1
-}
-
-





More information about the llvm-commits mailing list