@@ -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 , _ := 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 for i := 0 ; i < n ; i ++ {
415421 m := mset .At (i )
@@ -421,12 +427,17 @@ func (b Builder) abiUncommonMethods(t types.Type, mset *types.MethodSet) llvm.Va
421427 }
422428 mSig := m .Type ().(* types.Signature )
423429 var tfn , ifn llvm.Value
424- tfn = b .abiMethodFunc (anonymous , pkg , mName , mSig )
425- ifn = tfn
426- if _ , ok := m .Recv ().Underlying ().(* types.Pointer ); ! ok {
427- pRecv := types .NewVar (token .NoPos , pkg , "" , types .NewPointer (mSig .Recv ().Type ()))
428- pSig := types .NewSignature (pRecv , mSig .Params (), mSig .Results (), mSig .Variadic ())
429- ifn = b .abiMethodFunc (anonymous , pkg , mName , pSig )
430+ if prog .abiTypePruning && ! prog .methodIsInvoke (m ) {
431+ tfn = prog .Nil (prog .VoidPtr ()).impl
432+ ifn = tfn
433+ } else {
434+ tfn = b .abiMethodFunc (anonymous , pkg , mName , mSig )
435+ ifn = tfn
436+ if _ , ok := m .Recv ().Underlying ().(* types.Pointer ); ! ok {
437+ pRecv := types .NewVar (token .NoPos , pkg , "" , types .NewPointer (mSig .Recv ().Type ()))
438+ pSig := types .NewSignature (pRecv , mSig .Params (), mSig .Results (), mSig .Variadic ())
439+ ifn = b .abiMethodFunc (anonymous , pkg , mName , pSig )
440+ }
430441 }
431442 var values []llvm.Value
432443 values = append (values , name )
@@ -448,7 +459,7 @@ func funcType(prog Program, typ types.Type) types.Type {
448459func (b Builder ) abiMethodFunc (anonymous bool , mPkg * types.Package , mName string , mSig * types.Signature ) (tfn llvm.Value ) {
449460 var fullName string
450461 if anonymous {
451- fullName = b . Pkg .Path () + "." + mSig .Recv ().Type ().String () + "." + mName
462+ fullName = mPkg .Path () + "." + mSig .Recv ().Type ().String () + "." + mName
452463 } else {
453464 fullName = FuncName (mPkg , mName , mSig .Recv (), false )
454465 }
@@ -471,14 +482,31 @@ func (b Builder) abiMethodFunc(anonymous bool, mPkg *types.Package, mName string
471482 }
472483*/
473484func (b Builder ) abiType (t types.Type ) Expr {
474- name , _ := b .Pkg .abi .TypeName (t )
475- g := b .Pkg .VarOf (name )
476485 prog := b .Prog
486+ var name string
487+ if v , ok := prog .abiTypeName [t ]; ok {
488+ name = v
489+ } else {
490+ name , _ = b .Pkg .abi .TypeName (t )
491+ }
492+ g := b .Pkg .VarOf (name )
477493 pkg := b .Pkg
478494 if g == nil {
495+ raw := t
479496 if prog .patchType != nil {
480497 t = prog .patchType (t )
481498 }
499+ prog .abiTypeName [raw ] = name
500+ if prog .abiTypePruning {
501+ if sym , ok := prog .abiSymbol [name ]; ok {
502+ pkgPath := pkg .abi .Pkg
503+ pkg .abi .Pkg = sym .pkgPath
504+ defer func () {
505+ pkg .abi .Pkg = pkgPath
506+ }()
507+ }
508+ }
509+
482510 mset , hasUncommon := b .abiUncommonMethodSet (t )
483511 rt := prog .rtNamed (pkg .abi .RuntimeName (t ))
484512 var typ types.Type = rt
@@ -499,24 +527,38 @@ func (b Builder) abiType(t types.Type) Expr {
499527 llvm .ConstNamedStruct (prog .AbiType ().ll , fields ),
500528 }, exts ... )
501529 }
530+ var xcount int
502531 if hasUncommon {
532+ commonTyp := llvm .ConstNamedStruct (prog .Type (rt , InGo ).ll , fields )
533+ var uncommonTyp llvm.Value
534+ uncommonTyp , xcount = b .abiUncommonType (t , mset )
535+ uncommonMethods := b .abiUncommonMethods (t , name , mset )
503536 fields = []llvm.Value {
504- llvm . ConstNamedStruct ( prog . Type ( rt , InGo ). ll , fields ) ,
505- b . abiUncommonType ( t , mset ) ,
506- b . abiUncommonMethods ( t , mset ) ,
537+ commonTyp ,
538+ uncommonTyp ,
539+ uncommonMethods ,
507540 }
508541 }
509542 g .impl .SetInitializer (prog .ctx .ConstStruct (fields , false ))
510543 g .impl .SetGlobalConstant (true )
511- g .impl .SetLinkage (llvm .WeakODRLinkage )
512- prog .abiSymbol [name ] = g .Type
544+ if ! prog .abiTypePruning {
545+ g .impl .SetLinkage (llvm .WeakODRLinkage )
546+ prog .abiSymbol [name ] = & AbiSymbol {raw : raw , typ : g .Type , pkgPath : pkg .Path (), xcount : xcount }
547+ }
513548 }
514549 return Expr {llvm .ConstGEP (g .impl .GlobalValueType (), g .impl , []llvm.Value {
515550 llvm .ConstInt (prog .Int32 ().ll , 0 , false ),
516551 llvm .ConstInt (prog .Int32 ().ll , 0 , false ),
517552 }), prog .AbiTypePtr ()}
518553}
519554
555+ type AbiSymbol struct {
556+ raw types.Type
557+ typ Type
558+ pkgPath string
559+ xcount int
560+ }
561+
520562func (p Package ) getAbiTypes (name string ) Expr {
521563 prog := p .Prog
522564 names := make ([]string , len (prog .abiSymbol ))
@@ -528,7 +570,7 @@ func (p Package) getAbiTypes(name string) Expr {
528570 sort .Strings (names )
529571 fields := make ([]llvm.Value , len (names ))
530572 for i , name := range names {
531- g := p .doNewVar (name , prog .abiSymbol [name ])
573+ g := p .doNewVar (name , prog .abiSymbol [name ]. typ )
532574 g .impl .SetLinkage (llvm .ExternalLinkage )
533575 g .impl .SetGlobalConstant (true )
534576 ptr := Expr {llvm .ConstGEP (g .impl .GlobalValueType (), g .impl , []llvm.Value {
@@ -568,4 +610,39 @@ func (p Package) InitAbiTypes(fname string) Function {
568610 return initFn
569611}
570612
613+ func (p Package ) PruneAbiTypes (methodIsInvoke func (method * types.Selection ) bool ) {
614+ prog := p .Prog
615+ var names []string
616+ for k , sym := range prog .abiSymbol {
617+ if sym .xcount == 0 {
618+ continue
619+ }
620+ names = append (names , k )
621+ }
622+ sort .Strings (names )
623+ p .SetResolveLinkname (prog .resolveLinkname )
624+ if methodIsInvoke == nil {
625+ methodIsInvoke = func (method * types.Selection ) bool {
626+ if ms , ok := prog .invokeMethods [method .Obj ().Name ()]; ok {
627+ for m := range ms {
628+ if types .Identical (m , method .Type ()) {
629+ return true
630+ }
631+ }
632+ }
633+ return false
634+ }
635+ }
636+ prog .abiTypePruning = true
637+ defer func () {
638+ prog .abiTypePruning = false
639+ }()
640+ prog .methodIsInvoke = methodIsInvoke
641+ b := (& aFunction {Pkg : p , Prog : prog }).NewBuilder ()
642+ for _ , name := range names {
643+ sym := prog .abiSymbol [name ]
644+ b .abiType (sym .raw )
645+ }
646+ }
647+
571648// -----------------------------------------------------------------------------
0 commit comments