@@ -347,14 +347,14 @@ func (b Builder) abiUncommonMethodSet(t types.Type) (mset *types.MethodSet, ok b
347347 }
348348 mset := types .NewMethodSet (t )
349349 if mset .Len () != 0 {
350- if prog .compileMethods != nil {
350+ if prog .compileMethods != nil && ! prog . abiTypePruning {
351351 prog .compileMethods (b .Pkg , t )
352352 }
353353 }
354354 return mset , true
355355 case * types.Struct , * types.Pointer :
356356 if mset := types .NewMethodSet (t ); mset .Len () != 0 {
357- if prog .compileMethods != nil {
357+ if prog .compileMethods != nil && ! prog . abiTypePruning {
358358 prog .compileMethods (b .Pkg , t )
359359 }
360360 return mset , true
@@ -372,7 +372,7 @@ type UncommonType struct {
372372}
373373*/
374374
375- func (b Builder ) abiUncommonType (t types.Type , mset * types.MethodSet ) llvm.Value {
375+ func (b Builder ) abiUncommonType (t types.Type , mset * types.MethodSet ) ( llvm.Value , int ) {
376376 prog := b .Prog
377377 ft := prog .rtType ("uncommonType" )
378378 var fields []llvm.Value
@@ -389,7 +389,7 @@ func (b Builder) abiUncommonType(t types.Type, mset *types.MethodSet) llvm.Value
389389 fields = append (fields , prog .IntVal (uint64 (mcount ), prog .Uint16 ()).impl )
390390 fields = append (fields , prog .IntVal (uint64 (xcount ), prog .Uint16 ()).impl )
391391 fields = append (fields , prog .IntVal (moff , prog .Uint32 ()).impl )
392- return llvm .ConstNamedStruct (ft .ll , fields )
392+ return llvm .ConstNamedStruct (ft .ll , fields ), xcount
393393}
394394
395395/*
@@ -401,15 +401,21 @@ type Method struct {
401401}
402402*/
403403
404- func (b Builder ) abiUncommonMethods (t types.Type , mset * types.MethodSet ) llvm.Value {
404+ func (b Builder ) abiUncommonMethods (t types.Type , name string , mset * types.MethodSet ) llvm.Value {
405405 prog := b .Prog
406406 ft := prog .rtType ("Method" )
407407 n := mset .Len ()
408408 fields := make ([]llvm.Value , n )
409409 pkg , pkgPath := b .abiUncommonPkg (t )
410410 anonymous := pkg == nil
411411 if anonymous {
412- pkg = types .NewPackage (b .Pkg .Path (), "" )
412+ pkgPath := b .Pkg .Path ()
413+ if prog .abiTypePruning {
414+ if sym , ok := prog .abiSymbol [name ]; ok {
415+ pkgPath = sym .pkgPath
416+ }
417+ }
418+ pkg = types .NewPackage (pkgPath , "" )
413419 }
414420 var mPkg * types.Package
415421 for i := 0 ; i < n ; i ++ {
@@ -427,18 +433,21 @@ func (b Builder) abiUncommonMethods(t types.Type, mset *types.MethodSet) llvm.Va
427433 name = b .Str (abi .FullName (mPkg , mName )).impl
428434 skipfn = PathOf (mPkg ) != pkgPath
429435 }
436+ if prog .abiTypePruning {
437+ skipfn = ! prog .methodIsInvoke (m )
438+ }
430439 mSig := m .Type ().(* types.Signature )
431440 var tfn , ifn llvm.Value
432441 if skipfn {
433442 tfn = prog .Nil (prog .VoidPtr ()).impl
434443 ifn = tfn
435444 } else {
436- tfn = b .abiMethodFunc (anonymous , mPkg , mName , mSig )
445+ tfn = b .abiMethodFunc (anonymous , pkg , mPkg , mName , mSig )
437446 ifn = tfn
438447 if _ , ok := m .Recv ().Underlying ().(* types.Pointer ); ! ok {
439448 pRecv := types .NewVar (token .NoPos , mPkg , "" , types .NewPointer (mSig .Recv ().Type ()))
440449 pSig := types .NewSignature (pRecv , mSig .Params (), mSig .Results (), mSig .Variadic ())
441- ifn = b .abiMethodFunc (anonymous , mPkg , mName , pSig )
450+ ifn = b .abiMethodFunc (anonymous , pkg , mPkg , mName , pSig )
442451 }
443452 }
444453 var values []llvm.Value
@@ -458,10 +467,10 @@ func funcType(prog Program, typ types.Type) types.Type {
458467 return ftyp .raw .Type .(* types.Struct ).Field (0 ).Type ()
459468}
460469
461- func (b Builder ) abiMethodFunc (anonymous bool , mPkg * types.Package , mName string , mSig * types.Signature ) (tfn llvm.Value ) {
470+ func (b Builder ) abiMethodFunc (anonymous bool , pkg , mPkg * types.Package , mName string , mSig * types.Signature ) (tfn llvm.Value ) {
462471 var fullName string
463472 if anonymous {
464- fullName = b . Pkg .Path () + "." + mSig .Recv ().Type ().String () + "." + mName
473+ fullName = pkg .Path () + "." + mSig .Recv ().Type ().String () + "." + mName
465474 } else {
466475 fullName = FuncName (mPkg , mName , mSig .Recv (), false )
467476 }
@@ -484,14 +493,31 @@ func (b Builder) abiMethodFunc(anonymous bool, mPkg *types.Package, mName string
484493 }
485494*/
486495func (b Builder ) abiType (t types.Type ) Expr {
487- name , _ := b .Pkg .abi .TypeName (t )
488- g := b .Pkg .VarOf (name )
489496 prog := b .Prog
497+ var name string
498+ if v , ok := prog .abiTypeName [t ]; ok {
499+ name = v
500+ } else {
501+ name , _ = b .Pkg .abi .TypeName (t )
502+ }
503+ g := b .Pkg .VarOf (name )
490504 pkg := b .Pkg
491505 if g == nil {
506+ raw := t
492507 if prog .patchType != nil {
493508 t = prog .patchType (t )
494509 }
510+ prog .abiTypeName [raw ] = name
511+ if prog .abiTypePruning {
512+ if sym , ok := prog .abiSymbol [name ]; ok {
513+ pkgPath := pkg .abi .Pkg
514+ pkg .abi .Pkg = sym .pkgPath
515+ defer func () {
516+ pkg .abi .Pkg = pkgPath
517+ }()
518+ }
519+ }
520+
495521 mset , hasUncommon := b .abiUncommonMethodSet (t )
496522 rt := prog .rtNamed (pkg .abi .RuntimeName (t ))
497523 var typ types.Type = rt
@@ -512,24 +538,38 @@ func (b Builder) abiType(t types.Type) Expr {
512538 llvm .ConstNamedStruct (prog .AbiType ().ll , fields ),
513539 }, exts ... )
514540 }
541+ var xcount int
515542 if hasUncommon {
543+ commonTyp := llvm .ConstNamedStruct (prog .Type (rt , InGo ).ll , fields )
544+ var uncommonTyp llvm.Value
545+ uncommonTyp , xcount = b .abiUncommonType (t , mset )
546+ uncommonMethods := b .abiUncommonMethods (t , name , mset )
516547 fields = []llvm.Value {
517- llvm . ConstNamedStruct ( prog . Type ( rt , InGo ). ll , fields ) ,
518- b . abiUncommonType ( t , mset ) ,
519- b . abiUncommonMethods ( t , mset ) ,
548+ commonTyp ,
549+ uncommonTyp ,
550+ uncommonMethods ,
520551 }
521552 }
522553 g .impl .SetInitializer (prog .ctx .ConstStruct (fields , false ))
523554 g .impl .SetGlobalConstant (true )
524- g .impl .SetLinkage (llvm .WeakODRLinkage )
525- prog .abiSymbol [name ] = g .Type
555+ if ! prog .abiTypePruning {
556+ g .impl .SetLinkage (llvm .WeakODRLinkage )
557+ prog .abiSymbol [name ] = & AbiSymbol {raw : raw , typ : g .Type , pkgPath : pkg .Path (), xcount : xcount }
558+ }
526559 }
527560 return Expr {llvm .ConstGEP (g .impl .GlobalValueType (), g .impl , []llvm.Value {
528561 llvm .ConstInt (prog .Int32 ().ll , 0 , false ),
529562 llvm .ConstInt (prog .Int32 ().ll , 0 , false ),
530563 }), prog .AbiTypePtr ()}
531564}
532565
566+ type AbiSymbol struct {
567+ raw types.Type
568+ typ Type
569+ pkgPath string
570+ xcount int
571+ }
572+
533573func (p Package ) getAbiTypes (name string ) Expr {
534574 prog := p .Prog
535575 names := make ([]string , len (prog .abiSymbol ))
@@ -541,7 +581,7 @@ func (p Package) getAbiTypes(name string) Expr {
541581 sort .Strings (names )
542582 fields := make ([]llvm.Value , len (names ))
543583 for i , name := range names {
544- g := p .doNewVar (name , prog .abiSymbol [name ])
584+ g := p .doNewVar (name , prog .abiSymbol [name ]. typ )
545585 g .impl .SetLinkage (llvm .ExternalLinkage )
546586 g .impl .SetGlobalConstant (true )
547587 ptr := Expr {llvm .ConstGEP (g .impl .GlobalValueType (), g .impl , []llvm.Value {
@@ -581,4 +621,39 @@ func (p Package) InitAbiTypes(fname string) Function {
581621 return initFn
582622}
583623
624+ func (p Package ) PruneAbiTypes (methodIsInvoke func (method * types.Selection ) bool ) {
625+ prog := p .Prog
626+ var names []string
627+ for k , sym := range prog .abiSymbol {
628+ if sym .xcount == 0 {
629+ continue
630+ }
631+ names = append (names , k )
632+ }
633+ sort .Strings (names )
634+ p .SetResolveLinkname (prog .resolveLinkname )
635+ if methodIsInvoke == nil {
636+ methodIsInvoke = func (method * types.Selection ) bool {
637+ if ms , ok := prog .invokeMethods [method .Obj ().Name ()]; ok {
638+ for m := range ms {
639+ if types .Identical (m , method .Type ()) {
640+ return true
641+ }
642+ }
643+ }
644+ return false
645+ }
646+ }
647+ prog .abiTypePruning = true
648+ defer func () {
649+ prog .abiTypePruning = false
650+ }()
651+ prog .methodIsInvoke = methodIsInvoke
652+ b := (& aFunction {Pkg : p , Prog : prog }).NewBuilder ()
653+ for _ , name := range names {
654+ sym := prog .abiSymbol [name ]
655+ b .abiType (sym .raw )
656+ }
657+ }
658+
584659// -----------------------------------------------------------------------------
0 commit comments