[cfe-commits] r85446 - in /cfe/trunk/lib: AST/ExprConstant.cpp CodeGen/CGExprConstant.cpp CodeGen/CGExprScalar.cpp CodeGen/CGStmt.cpp CodeGen/CodeGenFunction.cpp CodeGen/CodeGenFunction.h

Chris Lattner sabre at nondot.org
Wed Oct 28 16:59:40 PDT 2009


Author: lattner
Date: Wed Oct 28 18:59:40 2009
New Revision: 85446

URL: http://llvm.org/viewvc/llvm-project?rev=85446&view=rev
Log:
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" :)


Modified:
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/CodeGen/CGStmt.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=85446&r1=85445&r2=85446&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Wed Oct 28 18:59:40 2009
@@ -58,7 +58,12 @@
 static bool EvaluateLValue(const Expr *E, APValue &Result, EvalInfo &Info);
 static bool EvaluatePointer(const Expr *E, APValue &Result, EvalInfo &Info);
 static bool EvaluateInteger(const Expr *E, APSInt  &Result, EvalInfo &Info);
+#ifndef USEINDIRECTBRANCH
 static bool EvaluateIntegerOrLValue(const Expr *E, APValue  &Result, EvalInfo &Info);
+#else
+static bool EvaluateIntegerOrLValue(const Expr *E, APValue  &Result,
+                                    EvalInfo &Info);
+#endif
 static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info);
 static bool EvaluateComplex(const Expr *E, APValue &Result, EvalInfo &Info);
 

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=85446&r1=85445&r2=85446&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Wed Oct 28 18:59:40 2009
@@ -776,11 +776,17 @@
     }
     case Expr::AddrLabelExprClass: {
       assert(CGF && "Invalid address of label expression outside function.");
+#ifndef USEINDIRECTBRANCH
       unsigned id =
           CGF->GetIDForAddrOfLabel(cast<AddrLabelExpr>(E)->getLabel());
       llvm::Constant *C =
             llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), id);
       return llvm::ConstantExpr::getIntToPtr(C, ConvertType(E->getType()));
+#else
+      llvm::Constant *Ptr =
+        CGF->GetAddrOfLabel(cast<AddrLabelExpr>(E)->getLabel());
+      return llvm::ConstantExpr::getBitCast(Ptr, ConvertType(E->getType()));
+#endif
     }
     case Expr::CallExprClass: {
       CallExpr* CE = cast<CallExpr>(E);

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=85446&r1=85445&r2=85446&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Wed Oct 28 18:59:40 2009
@@ -135,11 +135,16 @@
   }
   Value *VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E);
   Value *VisitAddrLabelExpr(const AddrLabelExpr *E) {
+#ifndef USEINDIRECTBRANCH
     llvm::Value *V =
       llvm::ConstantInt::get(llvm::Type::getInt32Ty(CGF.getLLVMContext()),
                              CGF.GetIDForAddrOfLabel(E->getLabel()));
 
     return Builder.CreateIntToPtr(V, ConvertType(E->getType()));
+#else
+    llvm::Value *V = CGF.GetAddrOfLabel(E->getLabel());
+    return Builder.CreateBitCast(V, ConvertType(E->getType()));
+#endif
   }
 
   // l-values.

Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=85446&r1=85445&r2=85446&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Wed Oct 28 18:59:40 2009
@@ -287,8 +287,13 @@
   // Emit initial switch which will be patched up later by
   // EmitIndirectSwitches(). We need a default dest, so we use the
   // current BB, but this is overwritten.
+#ifndef USEINDIRECTBRANCH
   llvm::Value *V = Builder.CreatePtrToInt(EmitScalarExpr(S.getTarget()),
                                           llvm::Type::getInt32Ty(VMContext),
+#else
+  llvm::Value *V = Builder.CreateBitCast(EmitScalarExpr(S.getTarget()),
+                                         llvm::Type::getInt8PtrTy(VMContext),
+#endif
                                           "addr");
   llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
   

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=85446&r1=85445&r2=85446&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Wed Oct 28 18:59:40 2009
@@ -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) {

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=85446&r1=85445&r2=85446&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Oct 28 18:59:40 2009
@@ -183,13 +183,26 @@
   void PopConditionalTempDestruction();
 
 private:
+#ifndef USEINDIRECTBRANCH
   CGDebugInfo* DebugInfo;
+#else
+  CGDebugInfo *DebugInfo;
+#endif
 
+#ifndef USEINDIRECTBRANCH
   /// LabelIDs - Track arbitrary ids assigned to labels for use in implementing
   /// the GCC address-of-label extension and indirect goto. IDs are assigned to
   /// labels inside getIDForAddrOfLabel().
   std::map<const LabelStmt*, unsigned> LabelIDs;
+#else
+  /// IndirectBranch - The first time an indirect goto is seen we create a
+  /// block with an indirect branch.  Every time we see the address of a label
+  /// taken, we add the label to the indirect goto.  Every subsequent indirect
+  /// goto is codegen'd as a jump to the IndirectBranch's basic block.
+  llvm::IndirectBrInst *IndirectBranch;
+#endif
 
+#ifndef USEINDIRECTBRANCH
   /// IndirectGotoSwitch - The first time an indirect goto is seen we create a
   /// block with the switch for the indirect gotos.  Every time we see the
   /// address of a label taken, we add the label to the indirect goto.  Every
@@ -197,6 +210,7 @@
   /// IndirectGotoSwitch's basic block.
   llvm::SwitchInst *IndirectGotoSwitch;
 
+#endif
   /// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C
   /// decls.
   llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
@@ -558,7 +572,11 @@
   /// the input field number being accessed.
   static unsigned getAccessedFieldNo(unsigned Idx, const llvm::Constant *Elts);
 
+#ifndef USEINDIRECTBRANCH
   unsigned GetIDForAddrOfLabel(const LabelStmt *L);
+#else
+  llvm::BlockAddress *GetAddrOfLabel(const LabelStmt *L);
+#endif
   llvm::BasicBlock *GetIndirectGotoBlock();
 
   /// EmitMemSetToZero - Generate code to memset a value of the given type to 0.





More information about the cfe-commits mailing list