Implement clang support for indirect branch and address of label
using the new LLVM support for this.  This is temporarily hiding
behind horrible and ugly #ifdefs until the time when the optimizer
is stable (hopefully a week or so).  Until then, lets make it "opt in" :)



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85446 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index c6111fa..88beadf 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -27,7 +27,11 @@
   : BlockFunction(cgm, *this, Builder), CGM(cgm),
     Target(CGM.getContext().Target),
     Builder(cgm.getModule().getContext()),
+#ifndef USEINDIRECTBRANCH
     DebugInfo(0), IndirectGotoSwitch(0),
+#else
+    DebugInfo(0), IndirectBranch(0),
+#endif
     SwitchInsn(0), CaseRangeBlock(0), InvokeDest(0),
     CXXThisDecl(0) {
   LLVMIntTy = ConvertType(getContext().IntTy);
@@ -130,10 +134,33 @@
 
   EmitFunctionEpilog(*CurFnInfo, ReturnValue);
 
+#ifdef USEINDIRECTBRANCH
+  // If someone did an indirect goto, emit the indirect goto block at the end of
+  // the function.
+  if (IndirectBranch) {
+    EmitBlock(IndirectBranch->getParent());
+    Builder.ClearInsertionPoint();
+  }
+  
+  
+#endif
   // Remove the AllocaInsertPt instruction, which is just a convenience for us.
   llvm::Instruction *Ptr = AllocaInsertPt;
   AllocaInsertPt = 0;
   Ptr->eraseFromParent();
+#ifdef USEINDIRECTBRANCH
+  
+  // If someone took the address of a label but never did an indirect goto, we
+  // made a zero entry PHI node, which is illegal, zap it now.
+  if (IndirectBranch) {
+    llvm::PHINode *PN = cast<llvm::PHINode>(IndirectBranch->getAddress());
+    if (PN->getNumIncomingValues() == 0) {
+      PN->replaceAllUsesWith(llvm::UndefValue::get(PN->getType()));
+      PN->eraseFromParent();
+    }
+  }
+  
+#endif
 }
 
 void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
@@ -466,13 +493,26 @@
                                              TypeInfo.second/8));
 }
 
+#ifndef USEINDIRECTBRANCH
 unsigned CodeGenFunction::GetIDForAddrOfLabel(const LabelStmt *L) {
   // Use LabelIDs.size()+1 as the new ID if one hasn't been assigned.
   unsigned &Entry = LabelIDs[L];
   if (Entry) return Entry;
+#else
+
+llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelStmt *L) {
+  // Make sure that there is a block for the indirect goto.
+  if (IndirectBranch == 0)
+    GetIndirectGotoBlock();
+#endif
   
+#ifndef USEINDIRECTBRANCH
   Entry = LabelIDs.size();
+#else
+  llvm::BasicBlock *BB = getBasicBlockForLabel(L);
+#endif
   
+#ifndef USEINDIRECTBRANCH
   // If this is the first "address taken" of a label and the indirect goto has
   // already been seen, add this to it.
   if (IndirectGotoSwitch) {
@@ -488,19 +528,42 @@
   }
   
   return Entry;
+#else
+  // Make sure the indirect branch includes all of the address-taken blocks.
+  IndirectBranch->addDestination(BB);
+  return llvm::BlockAddress::get(CurFn, BB);
+#endif
 }
 
 llvm::BasicBlock *CodeGenFunction::GetIndirectGotoBlock() {
+#ifndef USEINDIRECTBRANCH
   // If we already made the switch stmt for indirect goto, return its block.
   if (IndirectGotoSwitch) return IndirectGotoSwitch->getParent();
+#else
+  // If we already made the indirect branch for indirect goto, return its block.
+  if (IndirectBranch) return IndirectBranch->getParent();
+#endif
   
+#ifndef USEINDIRECTBRANCH
   EmitBlock(createBasicBlock("indirectgoto"));
+#else
+  CGBuilderTy TmpBuilder(createBasicBlock("indirectgoto"));
+#endif
   
+#ifndef USEINDIRECTBRANCH
   const llvm::IntegerType *Int32Ty = llvm::Type::getInt32Ty(VMContext);
+#else
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
+#endif
 
   // Create the PHI node that indirect gotos will add entries to.
+#ifndef USEINDIRECTBRANCH
   llvm::Value *DestVal = Builder.CreatePHI(Int32Ty, "indirect.goto.dest");
+#else
+  llvm::Value *DestVal = TmpBuilder.CreatePHI(Int8PtrTy, "indirect.goto.dest");
+#endif
   
+#ifndef USEINDIRECTBRANCH
   // Create the switch instruction.  For now, set the insert block to this block
   // which will be fixed as labels are added.
   IndirectGotoSwitch = Builder.CreateSwitch(DestVal, Builder.GetInsertBlock());
@@ -540,6 +603,11 @@
   }
 
   return IndirectGotoSwitch->getParent();
+#else
+  // Create the indirect branch instruction.
+  IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal);
+  return IndirectBranch->getParent();
+#endif
 }
 
 llvm::Value *CodeGenFunction::GetVLASize(const VariableArrayType *VAT) {