@@ -130,7 +130,9 @@ func newBuilder(c *compilerContext, irbuilder llvm.Builder, f *ir.Function) *bui
130130}
131131
132132type deferBuiltin struct {
133- funcName string
133+ callName string
134+ pos token.Pos
135+ argTypes []types.Type
134136 callback int
135137}
136138
@@ -1196,11 +1198,11 @@ func (b *builder) createInstruction(instr ssa.Instruction) {
11961198
11971199// createBuiltin lowers a builtin Go function (append, close, delete, etc.) to
11981200// LLVM IR. It uses runtime calls for some builtins.
1199- func (b * builder ) createBuiltin (args []ssa .Value , callName string , pos token.Pos ) (llvm.Value , error ) {
1201+ func (b * builder ) createBuiltin (argTypes []types. Type , argValues []llvm .Value , callName string , pos token.Pos ) (llvm.Value , error ) {
12001202 switch callName {
12011203 case "append" :
1202- src := b . getValue ( args [0 ])
1203- elems := b . getValue ( args [1 ])
1204+ src := argValues [0 ]
1205+ elems := argValues [1 ]
12041206 srcBuf := b .CreateExtractValue (src , 0 , "append.srcBuf" )
12051207 srcPtr := b .CreateBitCast (srcBuf , b .i8ptrType , "append.srcPtr" )
12061208 srcLen := b .CreateExtractValue (src , 1 , "append.srcLen" )
@@ -1221,9 +1223,9 @@ func (b *builder) createBuiltin(args []ssa.Value, callName string, pos token.Pos
12211223 newSlice = b .CreateInsertValue (newSlice , newCap , 2 , "" )
12221224 return newSlice , nil
12231225 case "cap" :
1224- value := b . getValue ( args [0 ])
1226+ value := argValues [0 ]
12251227 var llvmCap llvm.Value
1226- switch args [0 ]. Type () .(type ) {
1228+ switch argTypes [0 ].(type ) {
12271229 case * types.Chan :
12281230 llvmCap = b .createRuntimeCall ("chanCap" , []llvm.Value {value }, "cap" )
12291231 case * types.Slice :
@@ -1236,12 +1238,12 @@ func (b *builder) createBuiltin(args []ssa.Value, callName string, pos token.Pos
12361238 }
12371239 return llvmCap , nil
12381240 case "close" :
1239- b .createChanClose (args [0 ])
1241+ b .createChanClose (argValues [0 ])
12401242 return llvm.Value {}, nil
12411243 case "complex" :
1242- r := b . getValue ( args [0 ])
1243- i := b . getValue ( args [1 ])
1244- t := args [0 ]. Type () .Underlying ().(* types.Basic )
1244+ r := argValues [0 ]
1245+ i := argValues [1 ]
1246+ t := argTypes [0 ].Underlying ().(* types.Basic )
12451247 var cplx llvm.Value
12461248 switch t .Kind () {
12471249 case types .Float32 :
@@ -1255,8 +1257,8 @@ func (b *builder) createBuiltin(args []ssa.Value, callName string, pos token.Pos
12551257 cplx = b .CreateInsertValue (cplx , i , 1 , "" )
12561258 return cplx , nil
12571259 case "copy" :
1258- dst := b . getValue ( args [0 ])
1259- src := b . getValue ( args [1 ])
1260+ dst := argValues [0 ]
1261+ src := argValues [1 ]
12601262 dstLen := b .CreateExtractValue (dst , 1 , "copy.dstLen" )
12611263 srcLen := b .CreateExtractValue (src , 1 , "copy.srcLen" )
12621264 dstBuf := b .CreateExtractValue (dst , 0 , "copy.dstArray" )
@@ -1267,16 +1269,16 @@ func (b *builder) createBuiltin(args []ssa.Value, callName string, pos token.Pos
12671269 elemSize := llvm .ConstInt (b .uintptrType , b .targetData .TypeAllocSize (elemType ), false )
12681270 return b .createRuntimeCall ("sliceCopy" , []llvm.Value {dstBuf , srcBuf , dstLen , srcLen , elemSize }, "copy.n" ), nil
12691271 case "delete" :
1270- m := b . getValue ( args [0 ])
1271- key := b . getValue ( args [1 ])
1272- return llvm.Value {}, b .createMapDelete (args [1 ]. Type () , m , key , pos )
1272+ m := argValues [0 ]
1273+ key := argValues [1 ]
1274+ return llvm.Value {}, b .createMapDelete (argTypes [1 ], m , key , pos )
12731275 case "imag" :
1274- cplx := b . getValue ( args [0 ])
1276+ cplx := argValues [0 ]
12751277 return b .CreateExtractValue (cplx , 1 , "imag" ), nil
12761278 case "len" :
1277- value := b . getValue ( args [0 ])
1279+ value := argValues [0 ]
12781280 var llvmLen llvm.Value
1279- switch args [0 ]. Type () .Underlying ().(type ) {
1281+ switch argTypes [0 ].Underlying ().(type ) {
12801282 case * types.Basic , * types.Slice :
12811283 // string or slice
12821284 llvmLen = b .CreateExtractValue (value , 1 , "len" )
@@ -1292,12 +1294,11 @@ func (b *builder) createBuiltin(args []ssa.Value, callName string, pos token.Pos
12921294 }
12931295 return llvmLen , nil
12941296 case "print" , "println" :
1295- for i , arg := range args {
1297+ for i , value := range argValues {
12961298 if i >= 1 && callName == "println" {
12971299 b .createRuntimeCall ("printspace" , nil , "" )
12981300 }
1299- value := b .getValue (arg )
1300- typ := arg .Type ().Underlying ()
1301+ typ := argTypes [i ].Underlying ()
13011302 switch typ := typ .(type ) {
13021303 case * types.Basic :
13031304 switch typ .Kind () {
@@ -1349,13 +1350,13 @@ func (b *builder) createBuiltin(args []ssa.Value, callName string, pos token.Pos
13491350 }
13501351 return llvm.Value {}, nil // print() or println() returns void
13511352 case "real" :
1352- cplx := b . getValue ( args [0 ])
1353+ cplx := argValues [0 ]
13531354 return b .CreateExtractValue (cplx , 0 , "real" ), nil
13541355 case "recover" :
13551356 return b .createRuntimeCall ("_recover" , nil , "" ), nil
13561357 case "ssa:wrapnilchk" :
13571358 // TODO: do an actual nil check?
1358- return b . getValue ( args [0 ]) , nil
1359+ return argValues [0 ], nil
13591360 default :
13601361 return llvm.Value {}, b .makeError (pos , "todo: builtin: " + callName )
13611362 }
@@ -1432,7 +1433,13 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
14321433 exported = targetFunc .IsExported ()
14331434 } else if call , ok := instr .Value .(* ssa.Builtin ); ok {
14341435 // Builtin function (append, close, delete, etc.).)
1435- return b .createBuiltin (instr .Args , call .Name (), instr .Pos ())
1436+ var argTypes []types.Type
1437+ var argValues []llvm.Value
1438+ for _ , arg := range instr .Args {
1439+ argTypes = append (argTypes , arg .Type ())
1440+ argValues = append (argValues , b .getValue (arg ))
1441+ }
1442+ return b .createBuiltin (argTypes , argValues , call .Name (), instr .Pos ())
14361443 } else {
14371444 // Function pointer.
14381445 value := b .getValue (instr .Value )
0 commit comments