@@ -87,6 +87,7 @@ type compilerContext struct {
8787 program * ssa.Program
8888 diagnostics []error
8989 functionInfos map [* ssa.Function ]functionInfo
90+ functionABIs map [functionABIKey ]functionABI
9091 astComments map [string ]* ast.CommentGroup
9192 embedGlobals map [string ][]* loader.EmbedFile
9293 pkg * types.Package
@@ -107,6 +108,7 @@ func newCompilerContext(moduleName string, machine llvm.TargetMachine, config *C
107108 machine : machine ,
108109 targetData : machine .CreateTargetData (),
109110 functionInfos : map [* ssa.Function ]functionInfo {},
111+ functionABIs : map [functionABIKey ]functionABI {},
110112 astComments : map [string ]* ast.CommentGroup {},
111113 }
112114
@@ -789,18 +791,26 @@ func (b *builder) getLocalVariable(variable *types.Var) llvm.Metadata {
789791 return dilocal
790792}
791793
792- // attachDebugInfo adds debug info to a function declaration . It returns the
794+ // attachDebugInfo adds debug info to a function. It returns the
793795// DISubprogram metadata node.
794796func (c * compilerContext ) attachDebugInfo (f * ssa.Function ) llvm.Metadata {
795797 pos := c .program .Fset .Position (f .Syntax ().Pos ())
796798 _ , fn := c .getFunction (f )
797799 return c .attachDebugInfoRaw (f , fn , "" , pos .Filename , pos .Line )
798800}
799801
800- // attachDebugInfo adds debug info to a function declaration . It returns the
802+ // attachDebugInfoRaw adds debug info to a function. It returns the
801803// DISubprogram metadata node. This method allows some more control over how
802804// debug info is added to the function.
803805func (c * compilerContext ) attachDebugInfoRaw (f * ssa.Function , llvmFn llvm.Value , suffix , filename string , line int ) llvm.Metadata {
806+ return c .attachDebugInfoRawWithDefinition (f , llvmFn , suffix , filename , line , true )
807+ }
808+
809+ func (c * compilerContext ) attachDebugInfoDeclarationRaw (f * ssa.Function , llvmFn llvm.Value , suffix , filename string , line int ) llvm.Metadata {
810+ return c .attachDebugInfoRawWithDefinition (f , llvmFn , suffix , filename , line , false )
811+ }
812+
813+ func (c * compilerContext ) attachDebugInfoRawWithDefinition (f * ssa.Function , llvmFn llvm.Value , suffix , filename string , line int , isDefinition bool ) llvm.Metadata {
804814 // Debug info for this function.
805815 params := getParams (f .Signature )
806816 diparams := make ([]llvm.Metadata , 0 , len (params ))
@@ -819,7 +829,7 @@ func (c *compilerContext) attachDebugInfoRaw(f *ssa.Function, llvmFn llvm.Value,
819829 Line : line ,
820830 Type : diFuncType ,
821831 LocalToUnit : true ,
822- IsDefinition : true ,
832+ IsDefinition : isDefinition ,
823833 ScopeLine : 0 ,
824834 Flags : llvm .FlagPrototyped ,
825835 Optimized : true ,
@@ -1284,27 +1294,23 @@ func (b *builder) createFunctionStart(intrinsic bool) {
12841294 }
12851295
12861296 // Load function parameters
1297+ abi := b .getFunctionABI (b .fn .Signature , b .info .exported )
12871298 llvmParamIndex := 0
1288- if _ , indirectResult := b . hasIndirectResult ( b . fn . Signature ); indirectResult && ! b . info . exported {
1299+ if abi . indirectResult {
12891300 b .indirectReturn = b .llvmFn .Param (llvmParamIndex )
12901301 b .indirectReturn .SetName ("return" )
12911302 llvmParamIndex ++
12921303 }
1293- for _ , param := range b .fn .Params {
1294- llvmType := b . getLLVMType ( param . Type ())
1295- if b . isIndirectParam ( llvmType , b . info . exported ) {
1304+ for i , param := range b .fn .Params {
1305+ llvmType := abi . params [ i ]. llvmType
1306+ if abi . params [ i ]. indirect {
12961307 llvmParam := b .llvmFn .Param (llvmParamIndex )
12971308 llvmParam .SetName (param .Name ())
12981309 b .indirectValues [param ] = llvmParam
12991310 llvmParamIndex ++
13001311 continue
13011312 }
1302- var paramInfos []paramInfo
1303- if b .info .exported {
1304- paramInfos = b .expandDirectFormalParamType (llvmType , param .Name (), param .Type ())
1305- } else {
1306- paramInfos = b .expandFormalParamType (llvmType , param .Name (), param .Type ())
1307- }
1313+ paramInfos := b .expandDirectFormalParamType (llvmType , param .Name (), param .Type ())
13081314 fields := make ([]llvm.Value , 0 , 1 )
13091315 for _ , info := range paramInfos {
13101316 param := b .llvmFn .Param (llvmParamIndex )
@@ -1441,14 +1447,20 @@ func (b *builder) createFunction() {
14411447 }
14421448
14431449 // Resolve phi nodes
1450+ phiBuilder := b .ctx .NewBuilder ()
1451+ originalBuilder := b .Builder
1452+ b .Builder = phiBuilder
14441453 for _ , phi := range b .phis {
14451454 block := phi .ssa .Block ()
14461455 for i , edge := range phi .ssa .Edges {
1447- llvmVal := b .getCallArgument (edge , false )
14481456 llvmBlock := b .blockInfo [block .Preds [i ].Index ].exit
1457+ b .SetInsertPointBefore (llvmBlock .LastInstruction ())
1458+ llvmVal := b .getCallArgument (edge , b .isIndirectAggregate (b .getLLVMType (edge .Type ())))
14491459 phi .llvm .AddIncoming ([]llvm.Value {llvmVal }, []llvm.BasicBlock {llvmBlock })
14501460 }
14511461 }
1462+ b .Builder = originalBuilder
1463+ phiBuilder .Dispose ()
14521464
14531465 if b .NeedsStackObjects {
14541466 // Track phi nodes.
@@ -1676,9 +1688,8 @@ func (b *builder) getValuePointer(value ssa.Value) llvm.Value {
16761688 return ptr
16771689}
16781690
1679- func (b * builder ) getCallArgument (value ssa.Value , exported bool ) llvm.Value {
1680- paramType := b .getLLVMType (value .Type ())
1681- if b .isIndirectParam (paramType , exported ) {
1691+ func (b * builder ) getCallArgument (value ssa.Value , indirect bool ) llvm.Value {
1692+ if indirect {
16821693 return b .getValuePointer (value )
16831694 }
16841695 return b .getValue (value , getPos (value ))
@@ -2323,18 +2334,21 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
23232334 b .createNilCheck (instr .Value , callee , "fpcall" )
23242335 }
23252336
2326- var params []llvm.Value
2327- for _ , param := range instr .Args {
2328- params = append (params , b .getCallArgument (param , exported ))
2337+ abi := b .getFunctionABI (instr .Signature (), exported )
2338+ paramOffset := 0
2339+ if instr .IsInvoke () {
2340+ abi = b .getInterfaceFunctionABI (instr .Signature ())
2341+ paramOffset = 1
23292342 }
2343+ params := b .getCallArguments (instr .Args , abi .params [paramOffset :])
23302344 if instr .IsInvoke () {
23312345 params = append ([]llvm.Value {invokeReceiver }, params ... )
23322346 params = append (params , invokeTypecode )
23332347 }
23342348
23352349 if ! exported {
2336- if resultType , indirectResult := b . hasIndirectResult ( instr . Signature ()); indirectResult {
2337- result := b .createIndirectStorage (resultType , "call.result" )
2350+ if abi . indirectResult {
2351+ result := b .createIndirectStorage (abi . resultType , "call.result" )
23382352 params = append ([]llvm.Value {result }, params ... )
23392353 params = append (params , context )
23402354 b .createInvoke (calleeType , callee , params , "" )
@@ -2715,7 +2729,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
27152729 return b .createMapIteratorNext (rangeVal , llvmRangeVal , it ), nil
27162730 }
27172731 case * ssa.Phi :
2718- phiType := b .storedParamType (b .getLLVMType (expr .Type ()), false )
2732+ phiType := b .storedParamType (b .getLLVMType (expr .Type ()))
27192733 phi := b .CreatePHI (phiType , "" )
27202734 b .phis = append (b .phis , phiNode {expr , phi })
27212735 return phi , nil
0 commit comments