[cfe-commits] r89933 - in /cfe/trunk/lib/CodeGen: CGCXX.cpp CGVtable.cpp CGVtable.h CodeGenFunction.h CodeGenModule.h Mangle.cpp Mangle.h

Anders Carlsson andersca at mac.com
Wed Nov 25 19:09:37 PST 2009


Author: andersca
Date: Wed Nov 25 21:09:37 2009
New Revision: 89933

URL: http://llvm.org/viewvc/llvm-project?rev=89933&view=rev
Log:
Add a CovariantThunkAdjustment struct that represents the adjustments needed for a covariant thunk.

Modified:
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/lib/CodeGen/CGVtable.cpp
    cfe/trunk/lib/CodeGen/CGVtable.h
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/lib/CodeGen/Mangle.cpp
    cfe/trunk/lib/CodeGen/Mangle.h

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Wed Nov 25 21:09:37 2009
@@ -824,49 +824,50 @@
                                bool Extern, 
                                const ThunkAdjustment &ThisAdjustment) {
   return GenerateCovariantThunk(Fn, MD, Extern, 
-                                ThisAdjustment.NonVirtual,
-                                ThisAdjustment.Virtual, 0, 0);
+                                CovariantThunkAdjustment(ThisAdjustment,
+                                                         ThunkAdjustment()));
 }
 
-llvm::Value *CodeGenFunction::DynamicTypeAdjust(llvm::Value *V, int64_t nv,
-                                                int64_t v) {
-  llvm::Type *Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),
-                                              0);
+llvm::Value *
+CodeGenFunction::DynamicTypeAdjust(llvm::Value *V, 
+                                   const ThunkAdjustment &Adjustment) {
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
+
   const llvm::Type *OrigTy = V->getType();
-  if (nv) {
+  if (Adjustment.NonVirtual) {
     // Do the non-virtual adjustment
-    V = Builder.CreateBitCast(V, Ptr8Ty);
-    V = Builder.CreateConstInBoundsGEP1_64(V, nv);
+    V = Builder.CreateBitCast(V, Int8PtrTy);
+    V = Builder.CreateConstInBoundsGEP1_64(V, Adjustment.NonVirtual);
     V = Builder.CreateBitCast(V, OrigTy);
   }
-  if (v) {
-    // Do the virtual this adjustment
-    const llvm::Type *PtrDiffTy = 
-      ConvertType(getContext().getPointerDiffType());
-    llvm::Type *PtrPtr8Ty, *PtrPtrDiffTy;
-    PtrPtr8Ty = llvm::PointerType::get(Ptr8Ty, 0);
-    PtrPtrDiffTy = llvm::PointerType::get(PtrDiffTy, 0);
-    llvm::Value *ThisVal = Builder.CreateBitCast(V, Ptr8Ty);
-    V = Builder.CreateBitCast(V, PtrPtrDiffTy->getPointerTo());
-    V = Builder.CreateLoad(V, "vtable");
-    llvm::Value *VTablePtr = V;
-    assert(v % (LLVMPointerWidth/8) == 0 && "vtable entry unaligned");
-    v /= LLVMPointerWidth/8;
-    V = Builder.CreateConstInBoundsGEP1_64(VTablePtr, v);
-    V = Builder.CreateLoad(V);
-    V = Builder.CreateGEP(ThisVal, V);
-    V = Builder.CreateBitCast(V, OrigTy);
-  }
-  return V;
+  
+  if (!Adjustment.Virtual)
+    return V;
+
+  assert(Adjustment.Virtual % (LLVMPointerWidth / 8) == 0 && 
+         "vtable entry unaligned");
+
+  // Do the virtual this adjustment
+  const llvm::Type *PtrDiffTy = ConvertType(getContext().getPointerDiffType());
+  const llvm::Type *PtrDiffPtrTy = PtrDiffTy->getPointerTo();
+  
+  llvm::Value *ThisVal = Builder.CreateBitCast(V, Int8PtrTy);
+  V = Builder.CreateBitCast(V, PtrDiffPtrTy->getPointerTo());
+  V = Builder.CreateLoad(V, "vtable");
+  
+  llvm::Value *VTablePtr = V;
+  uint64_t VirtualAdjustment = Adjustment.Virtual / (LLVMPointerWidth / 8);
+  V = Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment);
+  V = Builder.CreateLoad(V);
+  V = Builder.CreateGEP(ThisVal, V);
+  
+  return Builder.CreateBitCast(V, OrigTy);
 }
 
-llvm::Constant *CodeGenFunction::GenerateCovariantThunk(llvm::Function *Fn,
-                                                        const CXXMethodDecl *MD,
-                                                        bool Extern,
-                                                        int64_t nv_t,
-                                                        int64_t v_t,
-                                                        int64_t nv_r,
-                                                        int64_t v_r) {
+llvm::Constant *
+CodeGenFunction::GenerateCovariantThunk(llvm::Function *Fn,
+                                   const CXXMethodDecl *MD, bool Extern,
+                                   const CovariantThunkAdjustment &Adjustment) {
   QualType ResultType = MD->getType()->getAs<FunctionType>()->getResultType();
 
   FunctionArgList Args;
@@ -899,16 +900,23 @@
   llvm::Value *Callee = CGM.GetAddrOfFunction(MD, Ty);
   CallArgList CallArgs;
 
+  bool ShouldAdjustReturnPointer = true;
   QualType ArgType = MD->getThisType(getContext());
   llvm::Value *Arg = Builder.CreateLoad(LocalDeclMap[ThisDecl], "this");
-  if (nv_t || v_t) {
+  if (!Adjustment.ThisAdjustment.isEmpty()) {
     // Do the this adjustment.
     const llvm::Type *OrigTy = Callee->getType();
-    Arg = DynamicTypeAdjust(Arg, nv_t, v_t);
-    if (nv_r || v_r) {
-      Callee = CGM.BuildCovariantThunk(MD, Extern, 0, 0, nv_r, v_r);
+    Arg = DynamicTypeAdjust(Arg, Adjustment.ThisAdjustment);
+    
+    if (!Adjustment.ReturnAdjustment.isEmpty()) {
+      const CovariantThunkAdjustment &ReturnAdjustment = 
+        CovariantThunkAdjustment(ThunkAdjustment(),
+                                 Adjustment.ReturnAdjustment);
+      
+      Callee = CGM.BuildCovariantThunk(MD, Extern, ReturnAdjustment);
+      
       Callee = Builder.CreateBitCast(Callee, OrigTy);
-      nv_r = v_r = 0;
+      ShouldAdjustReturnPointer = false;
     }
   }    
 
@@ -927,7 +935,7 @@
 
   RValue RV = EmitCall(CGM.getTypes().getFunctionInfo(ResultType, CallArgs),
                        Callee, CallArgs, MD);
-  if (nv_r || v_r) {
+  if (ShouldAdjustReturnPointer && !Adjustment.ReturnAdjustment.isEmpty()) {
     bool CanBeZero = !(ResultType->isReferenceType()
     // FIXME: attr nonnull can't be zero either
                        /* || ResultType->hasAttr<NonNullAttr>() */ );
@@ -942,7 +950,8 @@
       Builder.CreateCondBr(Builder.CreateICmpNE(RV.getScalarVal(), Zero),
                            NonZeroBlock, ZeroBlock);
       EmitBlock(NonZeroBlock);
-      llvm::Value *NZ = DynamicTypeAdjust(RV.getScalarVal(), nv_r, v_r);
+      llvm::Value *NZ = 
+        DynamicTypeAdjust(RV.getScalarVal(), Adjustment.ReturnAdjustment);
       EmitBranch(ContBlock);
       EmitBlock(ZeroBlock);
       llvm::Value *Z = RV.getScalarVal();
@@ -953,7 +962,8 @@
       RVOrZero->addIncoming(Z, ZeroBlock);
       RV = RValue::get(RVOrZero);
     } else
-      RV = RValue::get(DynamicTypeAdjust(RV.getScalarVal(), nv_r, v_r));
+      RV = RValue::get(DynamicTypeAdjust(RV.getScalarVal(), 
+                                         Adjustment.ReturnAdjustment));
   }
 
   if (!ResultType->isVoidType())
@@ -987,12 +997,11 @@
   return m;
 }
 
-llvm::Constant *CodeGenModule::BuildCovariantThunk(const CXXMethodDecl *MD,
-                                                   bool Extern, int64_t nv_t,
-                                                   int64_t v_t, int64_t nv_r,
-                                                   int64_t v_r) {
+llvm::Constant *
+CodeGenModule::BuildCovariantThunk(const CXXMethodDecl *MD, bool Extern,
+                                   const CovariantThunkAdjustment &Adjustment) {
   llvm::SmallString<256> OutName;
-  getMangleContext().mangleCovariantThunk(MD, nv_t, v_t, nv_r, v_r, OutName);
+  getMangleContext().mangleCovariantThunk(MD, Adjustment, OutName);
   llvm::GlobalVariable::LinkageTypes linktype;
   linktype = llvm::GlobalValue::WeakAnyLinkage;
   if (!Extern)
@@ -1005,8 +1014,7 @@
 
   llvm::Function *Fn = llvm::Function::Create(FTy, linktype, OutName.str(),
                                               &getModule());
-  CodeGenFunction(*this).GenerateCovariantThunk(Fn, MD, Extern, nv_t, v_t, nv_r,
-                                               v_r);
+  CodeGenFunction(*this).GenerateCovariantThunk(Fn, MD, Extern, Adjustment);
   llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty);
   return m;
 }

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Wed Nov 25 21:09:37 2009
@@ -349,8 +349,10 @@
       Index_t v_t = i->second.first.first.second;
       Index_t nv_r = i->second.first.second.first;
       Index_t v_r = i->second.first.second.second;
-      submethods[idx] = CGM.BuildCovariantThunk(MD, Extern, nv_t, v_t, nv_r,
-                                                v_r);
+      
+      CovariantThunkAdjustment Adjustment(ThunkAdjustment(nv_t, v_t),
+                                          ThunkAdjustment(nv_r, v_r));
+      submethods[idx] = CGM.BuildCovariantThunk(MD, Extern, Adjustment);
     }
     CovariantThunks.clear();
     for (Pures_t::iterator i = Pures.begin(), e = Pures.end();

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.h (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.h Wed Nov 25 21:09:37 2009
@@ -49,6 +49,19 @@
   int64_t Virtual;
 };
 
+/// CovariantThunkAdjustment - Adjustment of the 'this' pointer and the
+/// return pointer for covariant thunks.
+struct CovariantThunkAdjustment {
+  CovariantThunkAdjustment(const ThunkAdjustment &ThisAdjustment,
+                           const ThunkAdjustment &ReturnAdjustment)
+  : ThisAdjustment(ThisAdjustment), ReturnAdjustment(ReturnAdjustment) { }
+
+  CovariantThunkAdjustment() { }
+
+  ThunkAdjustment ThisAdjustment;
+  ThunkAdjustment ReturnAdjustment;
+};
+
 class CGVtableInfo {
   CodeGenModule &CGM;
   

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Nov 25 21:09:37 2009
@@ -437,16 +437,17 @@
   /// DynamicTypeAdjust - Do the non-virtual and virtual adjustments on an
   /// object pointer to alter the dynamic type of the pointer.  Used by
   /// GenerateCovariantThunk for building thunks.
-  llvm::Value *DynamicTypeAdjust(llvm::Value *V, int64_t nv, int64_t v);
+  llvm::Value *DynamicTypeAdjust(llvm::Value *V, 
+                                 const ThunkAdjustment &Adjustment);
 
   /// GenerateThunk - Generate a thunk for the given method
   llvm::Constant *GenerateThunk(llvm::Function *Fn, const CXXMethodDecl *MD,
                                 bool Extern, 
                                 const ThunkAdjustment &ThisAdjustment);
-  llvm::Constant *GenerateCovariantThunk(llvm::Function *Fn,
-                                         const CXXMethodDecl *MD, bool Extern,
-                                         int64_t nv_t, int64_t v_t,
-                                         int64_t nv_r, int64_t v_r);
+  llvm::Constant *
+  GenerateCovariantThunk(llvm::Function *Fn, const CXXMethodDecl *MD, 
+                         bool Extern,
+                         const CovariantThunkAdjustment &Adjustment);
 
   void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type);
 

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Wed Nov 25 21:09:37 2009
@@ -238,9 +238,9 @@
                              const ThunkAdjustment &ThisAdjustment);
 
   /// BuildCoVariantThunk - Build a thunk for the given method
-  llvm::Constant *BuildCovariantThunk(const CXXMethodDecl *MD, bool Extern,
-                                      int64_t nv_t, int64_t v_t,
-                                      int64_t nv_r, int64_t v_r);
+  llvm::Constant *
+  BuildCovariantThunk(const CXXMethodDecl *MD, bool Extern,
+                      const CovariantThunkAdjustment &Adjustment);
 
   typedef std::pair<const CXXRecordDecl *, uint64_t> CtorVtable_t;
   typedef llvm::DenseMap<const CXXRecordDecl *,

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

==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Wed Nov 25 21:09:37 2009
@@ -1371,9 +1371,10 @@
 
 /// \brief Mangles the a covariant thunk for the declaration D and emits that
 /// name to the given output stream.
-void MangleContext::mangleCovariantThunk(const FunctionDecl *FD, int64_t nv_t,
-                                         int64_t v_t, int64_t nv_r, int64_t v_r,
-                                         llvm::SmallVectorImpl<char> &Res) {
+void 
+MangleContext::mangleCovariantThunk(const FunctionDecl *FD,
+                                    const CovariantThunkAdjustment& Adjustment,
+                                    llvm::SmallVectorImpl<char> &Res) {
   // FIXME: Hum, we might have to thunk these, fix.
   assert(!isa<CXXDestructorDecl>(FD) &&
          "Use mangleCXXDtor for destructor decls!");
@@ -1384,8 +1385,8 @@
   //                      # second call-offset is result adjustment
   CXXNameMangler Mangler(*this, Res);
   Mangler.getStream() << "_ZTc";
-  Mangler.mangleCallOffset(ThunkAdjustment(nv_t, v_t));
-  Mangler.mangleCallOffset(ThunkAdjustment(nv_r, v_r));
+  Mangler.mangleCallOffset(Adjustment.ThisAdjustment);
+  Mangler.mangleCallOffset(Adjustment.ReturnAdjustment);
   Mangler.mangleFunctionEncoding(FD);
 }
 

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

==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.h (original)
+++ cfe/trunk/lib/CodeGen/Mangle.h Wed Nov 25 21:09:37 2009
@@ -35,6 +35,7 @@
   class VarDecl;
 
 namespace CodeGen {
+  class CovariantThunkAdjustment;
   class ThunkAdjustment;
    
 /// MangleContext - Context for tracking state which persists across multiple
@@ -66,8 +67,8 @@
   void mangleThunk(const FunctionDecl *FD, 
                    const ThunkAdjustment &ThisAdjustment,
                    llvm::SmallVectorImpl<char> &);
-  void mangleCovariantThunk(const FunctionDecl *FD, int64_t nv_t, int64_t v_t,
-                            int64_t nv_r, int64_t v_r,
+  void mangleCovariantThunk(const FunctionDecl *FD, 
+                            const CovariantThunkAdjustment& Adjustment,
                             llvm::SmallVectorImpl<char> &);
   void mangleGuardVariable(const VarDecl *D, llvm::SmallVectorImpl<char> &);
   void mangleCXXVtable(const CXXRecordDecl *RD, llvm::SmallVectorImpl<char> &);





More information about the cfe-commits mailing list