[cfe-commits] r85677 - in /cfe/trunk: lib/CodeGen/CGVtable.cpp test/CodeGenCXX/virt.cpp

Chris Lattner clattner at apple.com
Sat Oct 31 14:10:32 PDT 2009


On Oct 31, 2009, at 1:06 PM, Mike Stump wrote:
> URL: http://llvm.org/viewvc/llvm-project?rev=85677&view=rev
> Log:
> Refine vcall/vbase ordering with vtable construction.

>
> -  void GenerateVBaseOffsets(std::vector<llvm::Constant *> &offsets,
> -                            const CXXRecordDecl *RD, uint64_t Offset,
> +#define D1(x)
> +//#define D1(X) do { if (getenv("DEBUG")) { X; } } while (0)

Any reason not to use the existing DEBUG macros?
http://llvm.org/docs/ProgrammersManual.html#DEBUG

-Chris

> +
> +  void GenerateVBaseOffsets(const CXXRecordDecl *RD, uint64_t Offset,
>                             bool updateVBIndex, Index_t  
> current_vbindex) {
>     for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin 
> (),
>            e = RD->bases_end(); i != e; ++i) {
> @@ -105,22 +107,24 @@
>       Index_t next_vbindex = current_vbindex;
>       if (i->isVirtual() && !SeenVBase.count(Base)) {
>         SeenVBase.insert(Base);
> -        int64_t BaseOffset = -(Offset/8) +  
> BLayout.getVBaseClassOffset(Base)/8;
> -        llvm::Constant *m = wrap(BaseOffset);
> -        m = wrap((0?700:0) + BaseOffset);
>         if (updateVBIndex) {
> -          next_vbindex = (ssize_t)(-(offsets.size() 
> *LLVMPointerWidth/8)
> +          next_vbindex = (ssize_t)(-(VCalls.size()*LLVMPointerWidth/ 
> 8)
>                                    - 3*LLVMPointerWidth/8);
>           VBIndex[Base] = next_vbindex;
>         }
> -        offsets.push_back(m);
> +        int64_t BaseOffset = -(Offset/8) +  
> BLayout.getVBaseClassOffset(Base)/8;
> +        VCalls.push_back((0?700:0) + BaseOffset);
> +        D1(printf("  vbase for %s at %d delta %d most derived %s\n",
> +                  Base->getNameAsCString(),
> +                  (int)-VCalls.size()-3, (int)BaseOffset,
> +                  Class->getNameAsCString()));
>       }
>       // We also record offsets for non-virtual bases to closest  
> enclosing
>       // virtual base.  We do this so that we don't have to search
>       // for the nearst virtual base class when generating thunks.
>       if (updateVBIndex && VBIndex.count(Base) == 0)
>         VBIndex[Base] = next_vbindex;
> -      GenerateVBaseOffsets(offsets, Base, Offset, updateVBIndex,  
> next_vbindex);
> +      GenerateVBaseOffsets(Base, Offset, updateVBIndex,  
> next_vbindex);
>     }
>   }
>
> @@ -237,9 +241,17 @@
>             VCallOffset[MD] = OverrideOffset/8;
>             idx = VCalls.size()+1;
>             VCalls.push_back(0);
> +            D1(printf("  vcall for %s at %d with delta %d most  
> derived %s\n",
> +                      MD->getNameAsCString(),
> +                      (int)-VCalls.size()-3, (int)VCallOffset[MD],
> +                      Class->getNameAsCString()));
>           } else {
>             VCallOffset[MD] = VCallOffset[OMD];
>             VCalls[idx-1] = -VCallOffset[OMD] + OverrideOffset/8;
> +            D1(printf("  vcall patch for %s at %d with delta %d  
> most derived %s\n",
> +                      MD->getNameAsCString(),
> +                      (int)-VCalls.size()-3, (int)VCallOffset[MD],
> +                      Class->getNameAsCString()));
>           }
>           VCall[MD] = idx;
>           CallOffset ThisOffset;
> @@ -340,7 +352,8 @@
>     }
>   }
>
> -  void AddMethod(const CXXMethodDecl *MD, bool MorallyVirtual,  
> Index_t Offset) {
> +  void AddMethod(const CXXMethodDecl *MD, bool MorallyVirtual,  
> Index_t Offset,
> +    bool ForVirtualBase) {
>     llvm::Constant *m = WrapAddrOf(MD);
>
>     // If we can find a previously allocated slot for this, reuse it.
> @@ -350,6 +363,7 @@
>     // else allocate a new slot.
>     Index[MD] = submethods.size();
>     submethods.push_back(m);
> +    D1(printf("  vfn for %s at %d\n", MD->getNameAsCString(), (int) 
> Index[MD]));
>     if (MD->isPure())
>       Pures[MD] = 1;
>     if (MorallyVirtual) {
> @@ -359,16 +373,19 @@
>       if (idx == 0) {
>         idx = VCalls.size()+1;
>         VCalls.push_back(0);
> +        D1(printf("  vcall for %s at %d with delta %d\n",
> +                  MD->getNameAsCString(), (int)-VCalls.size()-3,
> +                  (int)VCallOffset[MD]));
>       }
>     }
>   }
>
>   void AddMethods(const CXXRecordDecl *RD, bool MorallyVirtual,
> -                  Index_t Offset) {
> +                  Index_t Offset, bool RDisVirtualBase) {
>     for (method_iter mi = RD->method_begin(), me = RD->method_end();  
> mi != me;
>          ++mi)
>       if (mi->isVirtual())
> -        AddMethod(*mi, MorallyVirtual, Offset);
> +        AddMethod(*mi, MorallyVirtual, Offset, RDisVirtualBase);
>   }
>
>   void NonVirtualBases(const CXXRecordDecl *RD, const  
> ASTRecordLayout &Layout,
> @@ -397,6 +414,7 @@
>
>   void insertVCalls(int InsertionPoint) {
>     llvm::Constant *e = 0;
> +    D1(printf("============= combining vbase/vcall\n"));
>     D(VCalls.insert(VCalls.begin(), 673));
>     D(VCalls.push_back(672));
>     methods.insert(methods.begin() + InsertionPoint, VCalls.size(),  
> e);
> @@ -408,11 +426,10 @@
>     VCalls.clear();
>   }
>
> -  Index_t end(const CXXRecordDecl *RD, std::vector<llvm::Constant  
> *> &offsets,
> -              const ASTRecordLayout &Layout,
> -              const CXXRecordDecl *PrimaryBase,
> -              bool PrimaryBaseWasVirtual, bool MorallyVirtual,
> -              int64_t Offset, bool ForVirtualBase, Path_t *Path) {
> +  Index_t end(const CXXRecordDecl *RD, const ASTRecordLayout &Layout,
> +              const CXXRecordDecl *PrimaryBase, bool  
> PrimaryBaseWasVirtual,
> +              bool MorallyVirtual, int64_t Offset, bool  
> ForVirtualBase,
> +              Path_t *Path) {
>     bool alloc = false;
>     if (Path == 0) {
>       alloc = true;
> @@ -421,16 +438,6 @@
>
>     StartNewTable();
>     extra = 0;
> -    // FIXME: Cleanup.
> -    if (!ForVirtualBase) {
> -      D(methods.push_back(wrap(666)));
> -      // then virtual base offsets...
> -      for (std::vector<llvm::Constant *>::reverse_iterator i =  
> offsets.rbegin(),
> -             e = offsets.rend(); i != e; ++i)
> -        methods.push_back(*i);
> -      D(methods.push_back(wrap(667)));
> -    }
> -
>     bool DeferVCalls = MorallyVirtual || ForVirtualBase;
>     int VCallInsertionPoint = methods.size();
>     if (!DeferVCalls) {
> @@ -439,20 +446,12 @@
>       // FIXME: just for extra, or for all uses of VCalls.size post  
> this?
>       extra = -VCalls.size();
>
> -    if (ForVirtualBase) {
> -      D(methods.push_back(wrap(668)));
> -      // then virtual base offsets...
> -      for (std::vector<llvm::Constant *>::reverse_iterator i =  
> offsets.rbegin(),
> -             e = offsets.rend(); i != e; ++i)
> -        methods.push_back(*i);
> -      D(methods.push_back(wrap(669)));
> -    }
> -
>     methods.push_back(wrap(-(Offset/8)));
>     methods.push_back(rtti);
>     Index_t AddressPoint = methods.size();
>
>     InstallThunks();
> +    D1(printf("============= combining methods\n"));
>     methods.insert(methods.end(), submethods.begin(), submethods.end 
> ());
>     submethods.clear();
>
> @@ -461,10 +460,8 @@
>                     MorallyVirtual, Offset, Path);
>
>     if (ForVirtualBase) {
> -      D(methods.push_back(wrap(670)));
>       insertVCalls(VCallInsertionPoint);
>       AddressPoint += VCalls.size();
> -      D(methods.push_back(wrap(671)));
>     }
>
>     if (alloc) {
> @@ -473,7 +470,36 @@
>     return AddressPoint;
>   }
>
> -  void Primaries(const CXXRecordDecl *RD, bool MorallyVirtual,  
> int64_t Offset) {
> +  void Primaries(const CXXRecordDecl *RD, bool MorallyVirtual,  
> int64_t Offset,
> +                 bool updateVBIndex, Index_t current_vbindex,
> +                 bool RDisVirtualBase) {
> +    if (!RD->isDynamicClass())
> +      return;
> +
> +    const ASTRecordLayout &Layout = CGM.getContext 
> ().getASTRecordLayout(RD);
> +    const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
> +    const bool PrimaryBaseWasVirtual =  
> Layout.getPrimaryBaseWasVirtual();
> +
> +    // vtables are composed from the chain of primaries.
> +    if (PrimaryBase) {
> +      D1(printf(" doing primaries for %s most derived %s\n",
> +                RD->getNameAsCString(), Class->getNameAsCString()));
> +
> +      if (!PrimaryBaseWasVirtual)
> +        Primaries(PrimaryBase, PrimaryBaseWasVirtual| 
> MorallyVirtual, Offset,
> +                  updateVBIndex, current_vbindex,  
> PrimaryBaseWasVirtual);
> +    }
> +
> +    D1(printf(" doing vcall entries for %s most derived %s\n",
> +              RD->getNameAsCString(), Class->getNameAsCString()));
> +
> +    // And add the virtuals for the class to the primary vtable.
> +    AddMethods(RD, MorallyVirtual, Offset, RDisVirtualBase);
> +  }
> +
> +  void VBPrimaries(const CXXRecordDecl *RD, bool MorallyVirtual,  
> int64_t Offset,
> +                   bool updateVBIndex, Index_t current_vbindex,
> +                   bool RDisVirtualBase, bool bottom=false) {
>     if (!RD->isDynamicClass())
>       return;
>
> @@ -485,11 +511,22 @@
>     if (PrimaryBase) {
>       if (PrimaryBaseWasVirtual)
>         IndirectPrimary.insert(PrimaryBase);
> -      Primaries(PrimaryBase, PrimaryBaseWasVirtual|MorallyVirtual,  
> Offset);
> +
> +      D1(printf(" doing primaries for %s most derived %s\n",
> +                RD->getNameAsCString(), Class->getNameAsCString()));
> +
> +      VBPrimaries(PrimaryBase, PrimaryBaseWasVirtual| 
> MorallyVirtual, Offset,
> +                  updateVBIndex, current_vbindex,  
> PrimaryBaseWasVirtual);
>     }
>
> -    // And add the virtuals for the class to the primary vtable.
> -    AddMethods(RD, MorallyVirtual, Offset);
> +    D1(printf(" doing vbase entries for %s most derived %s\n",
> +              RD->getNameAsCString(), Class->getNameAsCString()));
> +    GenerateVBaseOffsets(RD, Offset, updateVBIndex, current_vbindex);
> +
> +    if (RDisVirtualBase || bottom) {
> +      Primaries(RD, MorallyVirtual, Offset, updateVBIndex,  
> current_vbindex,
> +                RDisVirtualBase);
> +    }
>   }
>
>   int64_t GenerateVtableForBase(const CXXRecordDecl *RD,
> @@ -503,19 +540,21 @@
>     const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
>     const bool PrimaryBaseWasVirtual =  
> Layout.getPrimaryBaseWasVirtual();
>
> -    std::vector<llvm::Constant *> offsets;
>     extra = 0;
> -    GenerateVBaseOffsets(offsets, RD, Offset, !ForVirtualBase, 0);
> +    D1(printf("building entries for base %s most derived %s\n",
> +              RD->getNameAsCString(), Class->getNameAsCString()));
> +
>     if (ForVirtualBase)
> -      extra = offsets.size();
> +      extra = VCalls.size();
>
> -    Primaries(RD, MorallyVirtual, Offset);
> +    VBPrimaries(RD, MorallyVirtual, Offset, !ForVirtualBase, 0,  
> ForVirtualBase,
> +                true);
>
>     if (Path)
>       OverrideMethods(Path, MorallyVirtual, Offset);
>
> -    return end(RD, offsets, Layout, PrimaryBase,  
> PrimaryBaseWasVirtual,
> -               MorallyVirtual, Offset, ForVirtualBase, Path);
> +    return end(RD, Layout, PrimaryBase, PrimaryBaseWasVirtual,  
> MorallyVirtual,
> +               Offset, ForVirtualBase, Path);
>   }
>
>   void GenerateVtableForVBases(const CXXRecordDecl *RD,
> @@ -540,6 +579,8 @@
>         VCall.clear();
>         int64_t BaseOffset = BLayout.getVBaseClassOffset(Base);
>         CurrentVBaseOffset = BaseOffset;
> +        D1(printf("vtable %s virtual base %s\n",
> +                  Class->getNameAsCString(), Base->getNameAsCString 
> ()));
>         GenerateVtableForBase(Base, true, BaseOffset, true, Path);
>       }
>       int64_t BaseOffset = Offset;
> @@ -575,6 +616,7 @@
>   // FIXME: This seems expensive.  Can we do a partial job to get
>   // just this data.
>   VtableBuilder b(methods, RD, CGM);
> +  D1(printf("vtable %s\n", RD->getNameAsCString()));
>   b.GenerateVtableForBase(RD);
>   b.GenerateVtableForVBases(RD);
>
> @@ -599,6 +641,7 @@
>   // FIXME: This seems expensive.  Can we do a partial job to get
>   // just this data.
>   VtableBuilder b(methods, RD, CGM);
> +  D1(printf("vtable %s\n", RD->getNameAsCString()));
>   b.GenerateVtableForBase(RD);
>   b.GenerateVtableForVBases(RD);
>
> @@ -629,6 +672,7 @@
>
>   VtableBuilder b(methods, RD, CGM);
>
> +  D1(printf("vtable %s\n", RD->getNameAsCString()));
>   // First comes the vtables for all the non-virtual bases...
>   AddressPoint = b.GenerateVtableForBase(RD);
>
>
> Modified: cfe/trunk/test/CodeGenCXX/virt.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/virt.cpp?rev=85677&r1=85676&r2=85677&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/test/CodeGenCXX/virt.cpp (original)
> +++ cfe/trunk/test/CodeGenCXX/virt.cpp Sat Oct 31 15:06:59 2009
> @@ -306,10 +306,10 @@
> // CHECK-LP32-NEXT: .long __ZN9test5_B227funcB22Ev
> // CHECK-LP32-NEXT: .long __ZN9test5_B217funcB21Ev
> // CHECK-LP32-NEXT: .space 4
> -// CHECK-LP32: .long 8
> -// CHECK-LP32 .space 4
> -// CHECK-LP32 .space 4                       FIXME
> -// CHECK-LP32: .long 4
> +// CHECK-LP32-NEXT: .long 8
> +// CHECK-LP32-NEXT: .space 4
> +// CHECK-LP32-NEXT: .space 4
> +// CHECK-LP32-NEXT: .long 4
> // CHECK-LP32-NEXT: .space 4
> // CHECK-LP32-NEXT: .space 4
> // CHECK-LP32-NEXT: .long 4294967288
> @@ -358,10 +358,10 @@
> // CHECK-LP64-NEXT: .quad __ZN9test5_B227funcB22Ev
> // CHECK-LP64-NEXT: .quad __ZN9test5_B217funcB21Ev
> // CHECK-LP64-NEXT: .space 8
> -// CHECK-LP64: .quad 16
> -// CHECK-LP64 .space 8
> -// CHECK-LP64 .space 8
> -// CHECK-LP64: .quad 8
> +// CHECK-LP64-NEXT: .quad 16
> +// CHECK-LP64-NEXT: .space 8
> +// CHECK-LP64-NEXT: .space 8
> +// CHECK-LP64-NEXT: .quad 8
> // CHECK-LP64-NEXT: .space 8
> // CHECK-LP64-NEXT: .space 8
> // CHECK-LP64-NEXT: .quad 18446744073709551600
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




More information about the cfe-commits mailing list