diff --git a/cl/_testdata/embedunexport/out.ll b/cl/_testdata/embedunexport/out.ll index 986d419641..bf6efc6187 100644 --- a/cl/_testdata/embedunexport/out.ll +++ b/cl/_testdata/embedunexport/out.ll @@ -60,3 +60,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0 declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocZ"(i64) declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.IfacePtrData"(%"github.com/goplus/llgo/runtime/internal/runtime.iface") + +!llgo.useifacemethod = !{!0} + +!0 = !{!"github.com/goplus/llgo/cl/_testdata/embedunexport.Use", !"_llgo_github.com/goplus/llgo/cl/_testdata/embedunexport.Object", !"github.com/goplus/llgo/cl/_testdata/embedunexport.setName", !"_llgo_func$dlTgtqQDYoqfVBQYEBE1Fa3ytcia1pdKaKVOnw8ZjkA"} diff --git a/cl/_testdata/foo/out.ll b/cl/_testdata/foo/out.ll index 2deb0f303e..85c82a8697 100644 --- a/cl/_testdata/foo/out.ll +++ b/cl/_testdata/foo/out.ll @@ -121,3 +121,8 @@ declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintString"(%"gi declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintByte"(i8) attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useiface = !{!0, !1} + +!0 = !{!"github.com/goplus/llgo/cl/_testdata/foo.Bar", !"_llgo_struct$K-dZ9QotZfVPz2a0YdRa9vmZUuDXPTqZOlMShKEDJtk"} +!1 = !{!"github.com/goplus/llgo/cl/_testdata/foo.F", !"github.com/goplus/llgo/cl/_testdata/foo.struct$MYpsoM99ZwFY087IpUOkIw1zjBA_sgFXVodmn1m-G88"} diff --git a/cl/_testdata/geometry1370/out.ll b/cl/_testdata/geometry1370/out.ll index 0651810645..eabf098a03 100644 --- a/cl/_testdata/geometry1370/out.ll +++ b/cl/_testdata/geometry1370/out.ll @@ -88,3 +88,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0 declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocZ"(i64) declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.IfacePtrData"(%"github.com/goplus/llgo/runtime/internal/runtime.iface") + +!llgo.useifacemethod = !{!0} + +!0 = !{!"github.com/goplus/llgo/cl/_testdata/geometry1370.RegisterShape", !"_llgo_github.com/goplus/llgo/cl/_testdata/geometry1370.Shape", !"github.com/goplus/llgo/cl/_testdata/geometry1370.setID", !"_llgo_func$VZ-8VPNF1RaLICwxc1Ghn7BbgyFX3v762OCdx127EkA"} diff --git a/cl/_testdata/print/out.ll b/cl/_testdata/print/out.ll index 9219560bd0..63c9cf7559 100644 --- a/cl/_testdata/print/out.ll +++ b/cl/_testdata/print/out.ll @@ -1206,3 +1206,21 @@ _llgo_0: } declare %"github.com/goplus/llgo/runtime/internal/runtime.Slice" @"github.com/goplus/llgo/runtime/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64) + +!llgo.useiface = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14} + +!0 = !{!"github.com/goplus/llgo/cl/_testdata/print.main", !"_llgo_float32"} +!1 = !{!"github.com/goplus/llgo/cl/_testdata/print.main", !"_llgo_float64"} +!2 = !{!"github.com/goplus/llgo/cl/_testdata/print.main", !"_llgo_string"} +!3 = !{!"github.com/goplus/llgo/cl/_testdata/print.main", !"_llgo_bool"} +!4 = !{!"github.com/goplus/llgo/cl/_testdata/print.main", !"_llgo_int32"} +!5 = !{!"github.com/goplus/llgo/cl/_testdata/print.main", !"_llgo_int8"} +!6 = !{!"github.com/goplus/llgo/cl/_testdata/print.main", !"_llgo_int16"} +!7 = !{!"github.com/goplus/llgo/cl/_testdata/print.main", !"_llgo_int64"} +!8 = !{!"github.com/goplus/llgo/cl/_testdata/print.main", !"_llgo_int"} +!9 = !{!"github.com/goplus/llgo/cl/_testdata/print.main", !"_llgo_uint8"} +!10 = !{!"github.com/goplus/llgo/cl/_testdata/print.main", !"_llgo_uint16"} +!11 = !{!"github.com/goplus/llgo/cl/_testdata/print.main", !"_llgo_uint32"} +!12 = !{!"github.com/goplus/llgo/cl/_testdata/print.main", !"_llgo_uint64"} +!13 = !{!"github.com/goplus/llgo/cl/_testdata/print.main", !"_llgo_uintptr"} +!14 = !{!"github.com/goplus/llgo/cl/_testdata/print.main", !"_llgo_complex128"} diff --git a/cl/_testdata/vargs/out.ll b/cl/_testdata/vargs/out.ll index 31ab5878f8..f41b599037 100644 --- a/cl/_testdata/vargs/out.ll +++ b/cl/_testdata/vargs/out.ll @@ -120,3 +120,8 @@ declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64) declare void @"github.com/goplus/llgo/runtime/internal/runtime.Panic"(%"github.com/goplus/llgo/runtime/internal/runtime.eface") declare i32 @printf(ptr, ...) + +!llgo.useiface = !{!0, !1} + +!0 = !{!"github.com/goplus/llgo/cl/_testdata/vargs.main", !"_llgo_int"} +!1 = !{!"github.com/goplus/llgo/cl/_testdata/vargs.test", !"_llgo_string"} diff --git a/cl/_testgo/abimethod/out.ll b/cl/_testgo/abimethod/out.ll index f227a1be3d..0afd1b9380 100644 --- a/cl/_testgo/abimethod/out.ll +++ b/cl/_testgo/abimethod/out.ll @@ -1756,3 +1756,149 @@ _llgo_0: } attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useiface = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26} +!llgo.methodoff = !{!27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43, !44, !45, !46, !47, !48, !49, !50, !51, !52, !53, !54, !55, !56, !57, !58, !59, !60, !61, !62, !63, !64, !65, !66, !67, !68, !69, !70, !71, !72, !73, !74, !75, !76, !77, !78, !79, !80, !81, !82, !83, !84, !85, !86, !87, !88, !89, !90, !91, !92, !93, !94, !95, !96, !97, !98, !99, !100, !101, !102, !103, !104, !105, !106, !107, !108, !109, !110, !111, !112, !113, !114, !115, !116, !117, !118, !119, !120, !121, !122, !123} +!llgo.useifacemethod = !{!124, !125, !126, !127, !128, !129, !130, !131, !132, !133, !134, !135, !136, !137, !138, !139, !140} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous1", !"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$mRfo5gQx8vKF1DvrL24XRoyvI_ttVDcwc1JYMRxWfb8"} +!1 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous1", !"_llgo_string"} +!2 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous2", !"github.com/goplus/llgo/cl/_testgo/abimethod.struct$mRfo5gQx8vKF1DvrL24XRoyvI_ttVDcwc1JYMRxWfb8"} +!3 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous2", !"_llgo_string"} +!4 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous3", !"github.com/goplus/llgo/cl/_testgo/abimethod.struct$F3FioEGWwXQRUdV6xoxVUEDjRNgBQIpL0XIyBECp088"} +!5 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous3", !"_llgo_string"} +!6 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous4", !"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$F3FioEGWwXQRUdV6xoxVUEDjRNgBQIpL0XIyBECp088"} +!7 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous4", !"_llgo_string"} +!8 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous5", !"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$F3FioEGWwXQRUdV6xoxVUEDjRNgBQIpL0XIyBECp088"} +!9 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous5", !"_llgo_string"} +!10 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous6", !"github.com/goplus/llgo/cl/_testgo/abimethod.struct$mRfo5gQx8vKF1DvrL24XRoyvI_ttVDcwc1JYMRxWfb8"} +!11 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous6", !"_llgo_string"} +!12 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous7", !"github.com/goplus/llgo/cl/_testgo/abimethod.struct$mRfo5gQx8vKF1DvrL24XRoyvI_ttVDcwc1JYMRxWfb8"} +!13 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous7", !"_llgo_string"} +!14 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous8", !"github.com/goplus/llgo/cl/_testgo/abimethod.struct$mRfo5gQx8vKF1DvrL24XRoyvI_ttVDcwc1JYMRxWfb8"} +!15 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous8", !"_llgo_string"} +!16 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymousBuffer", !"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY"} +!17 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymousBuffer", !"_llgo_string"} +!18 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testGeneric", !"*_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.Pointer[any]"} +!19 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testGeneric", !"_llgo_string"} +!20 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testGeneric$1", !"_llgo_int"} +!21 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testNamed1", !"*_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.T"} +!22 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testNamed1", !"_llgo_string"} +!23 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testNamed2", !"_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.T"} +!24 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testNamed2", !"_llgo_string"} +!25 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testNamed3", !"*_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.T"} +!26 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testNamed3", !"_llgo_string"} +!27 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.T", i32 0, !"Demo1", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!28 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.T", i32 0, !"Demo1", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!29 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.T", i32 1, !"Demo2", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!30 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.T", i32 2, !"github.com/goplus/llgo/cl/_testgo/abimethod.demo3", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!31 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$mRfo5gQx8vKF1DvrL24XRoyvI_ttVDcwc1JYMRxWfb8", i32 0, !"Demo1", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!32 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$mRfo5gQx8vKF1DvrL24XRoyvI_ttVDcwc1JYMRxWfb8", i32 1, !"Demo2", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!33 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$mRfo5gQx8vKF1DvrL24XRoyvI_ttVDcwc1JYMRxWfb8", i32 2, !"github.com/goplus/llgo/cl/_testgo/abimethod.demo3", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!34 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$mRfo5gQx8vKF1DvrL24XRoyvI_ttVDcwc1JYMRxWfb8", i32 0, !"Demo1", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!35 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$mRfo5gQx8vKF1DvrL24XRoyvI_ttVDcwc1JYMRxWfb8", i32 1, !"Demo2", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!36 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$mRfo5gQx8vKF1DvrL24XRoyvI_ttVDcwc1JYMRxWfb8", i32 2, !"github.com/goplus/llgo/cl/_testgo/abimethod.demo3", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!37 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$F3FioEGWwXQRUdV6xoxVUEDjRNgBQIpL0XIyBECp088", i32 0, !"Demo1", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!38 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$F3FioEGWwXQRUdV6xoxVUEDjRNgBQIpL0XIyBECp088", i32 1, !"Demo2", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!39 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$F3FioEGWwXQRUdV6xoxVUEDjRNgBQIpL0XIyBECp088", i32 2, !"github.com/goplus/llgo/cl/_testgo/abimethod.demo3", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!40 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$F3FioEGWwXQRUdV6xoxVUEDjRNgBQIpL0XIyBECp088", i32 0, !"Demo1", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!41 = !{!"*_llgo_bytes.Buffer", i32 0, !"Available", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!42 = !{!"*_llgo_bytes.Buffer", i32 1, !"AvailableBuffer", !"_llgo_func$Z_-7GWzB37LCYRTQLsSYmEihg_hqBK8o_GbT88pqnPY"} +!43 = !{!"*_llgo_bytes.Buffer", i32 2, !"Bytes", !"_llgo_func$Z_-7GWzB37LCYRTQLsSYmEihg_hqBK8o_GbT88pqnPY"} +!44 = !{!"*_llgo_bytes.Buffer", i32 3, !"Cap", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!45 = !{!"*_llgo_bytes.Buffer", i32 4, !"Grow", !"_llgo_func$VZ-8VPNF1RaLICwxc1Ghn7BbgyFX3v762OCdx127EkA"} +!46 = !{!"*_llgo_bytes.Buffer", i32 5, !"Len", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!47 = !{!"*_llgo_bytes.Buffer", i32 6, !"Next", !"_llgo_func$d4kMA_oCkLwnd1j8nVlv1hwRarEVuCIrDCpnHhDz9UY"} +!48 = !{!"*_llgo_bytes.Buffer", i32 7, !"Read", !"_llgo_func$G2hch9Iy9DrhKKsg70PbL54bK-XSl-1IUUORN17J2Dk"} +!49 = !{!"*_llgo_bytes.Buffer", i32 8, !"ReadByte", !"_llgo_func$lukqSsfDYBoIp_R8GMojGkZnrYDqaq2iHn8RkCjW7iQ"} +!50 = !{!"*_llgo_bytes.Buffer", i32 9, !"ReadBytes", !"_llgo_func$aJkaU3jhXr0Q2QraTe2_TTdupeMMW2MD66UwBxynRM0"} +!51 = !{!"*_llgo_bytes.Buffer", i32 10, !"ReadFrom", !"_llgo_func$uVmBDI0DMcrui3Q9y-g_hbtVN8JckQ18V2wmO5_G7A8"} +!52 = !{!"*_llgo_bytes.Buffer", i32 11, !"ReadRune", !"_llgo_func$q-bw-_pPYBCXnr1TXIF8sOD4fVVzzIlpHqD-A13AB4Y"} +!53 = !{!"*_llgo_bytes.Buffer", i32 12, !"ReadString", !"_llgo_func$TBlCn7YTQdraI1HMiBWmkrqIGG-8UgD1UVyJy62Z_0o"} +!54 = !{!"*_llgo_bytes.Buffer", i32 13, !"Reset", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!55 = !{!"*_llgo_bytes.Buffer", i32 14, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!56 = !{!"*_llgo_bytes.Buffer", i32 15, !"Truncate", !"_llgo_func$VZ-8VPNF1RaLICwxc1Ghn7BbgyFX3v762OCdx127EkA"} +!57 = !{!"*_llgo_bytes.Buffer", i32 16, !"UnreadByte", !"_llgo_func$8rsrSd_r3UHd_2DiYTyaOKR7BYkei4zw5ysG35KF38w"} +!58 = !{!"*_llgo_bytes.Buffer", i32 17, !"UnreadRune", !"_llgo_func$8rsrSd_r3UHd_2DiYTyaOKR7BYkei4zw5ysG35KF38w"} +!59 = !{!"*_llgo_bytes.Buffer", i32 18, !"Write", !"_llgo_func$G2hch9Iy9DrhKKsg70PbL54bK-XSl-1IUUORN17J2Dk"} +!60 = !{!"*_llgo_bytes.Buffer", i32 19, !"WriteByte", !"_llgo_func$w4tN9iibS_UimF5vLUWoKP0uAk2tJZF26VqETo_8LVg"} +!61 = !{!"*_llgo_bytes.Buffer", i32 20, !"WriteRune", !"_llgo_func$uf8yw1UkUdbDuCneSpNKIq_NThWIEVE7f1IYfJGz_bw"} +!62 = !{!"*_llgo_bytes.Buffer", i32 21, !"WriteString", !"_llgo_func$thH5FBpdXzJNnCpSfiLU5ItTntFU6LWp0RJhDm2XJjw"} +!63 = !{!"*_llgo_bytes.Buffer", i32 22, !"WriteTo", !"_llgo_func$vSv85k0UY6JWccAc3T-lvdCx9J-4GM-oZC9zGLrxW1M"} +!64 = !{!"*_llgo_bytes.Buffer", i32 23, !"bytes.empty", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!65 = !{!"*_llgo_bytes.Buffer", i32 24, !"bytes.grow", !"_llgo_func$ekGNsrYBSzltfAjxbl6T8H6Yq8j16wzqS3nDj2xxGMU"} +!66 = !{!"*_llgo_bytes.Buffer", i32 25, !"bytes.readSlice", !"_llgo_func$aJkaU3jhXr0Q2QraTe2_TTdupeMMW2MD66UwBxynRM0"} +!67 = !{!"*_llgo_bytes.Buffer", i32 26, !"bytes.tryGrowByReslice", !"_llgo_func$qVJ5SH6qhXP_h0AM41vpBGzQEMp-fQIfvwQEJy5NI8M"} +!68 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 0, !"Available", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!69 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 1, !"AvailableBuffer", !"_llgo_func$Z_-7GWzB37LCYRTQLsSYmEihg_hqBK8o_GbT88pqnPY"} +!70 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 2, !"Bytes", !"_llgo_func$Z_-7GWzB37LCYRTQLsSYmEihg_hqBK8o_GbT88pqnPY"} +!71 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 3, !"Cap", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!72 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 4, !"Grow", !"_llgo_func$VZ-8VPNF1RaLICwxc1Ghn7BbgyFX3v762OCdx127EkA"} +!73 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 5, !"Len", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!74 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 6, !"Next", !"_llgo_func$d4kMA_oCkLwnd1j8nVlv1hwRarEVuCIrDCpnHhDz9UY"} +!75 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 7, !"Read", !"_llgo_func$G2hch9Iy9DrhKKsg70PbL54bK-XSl-1IUUORN17J2Dk"} +!76 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 8, !"ReadByte", !"_llgo_func$lukqSsfDYBoIp_R8GMojGkZnrYDqaq2iHn8RkCjW7iQ"} +!77 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 9, !"ReadBytes", !"_llgo_func$aJkaU3jhXr0Q2QraTe2_TTdupeMMW2MD66UwBxynRM0"} +!78 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 10, !"ReadFrom", !"_llgo_func$uVmBDI0DMcrui3Q9y-g_hbtVN8JckQ18V2wmO5_G7A8"} +!79 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 11, !"ReadRune", !"_llgo_func$q-bw-_pPYBCXnr1TXIF8sOD4fVVzzIlpHqD-A13AB4Y"} +!80 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 12, !"ReadString", !"_llgo_func$TBlCn7YTQdraI1HMiBWmkrqIGG-8UgD1UVyJy62Z_0o"} +!81 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 13, !"Reset", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!82 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 14, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!83 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 15, !"Truncate", !"_llgo_func$VZ-8VPNF1RaLICwxc1Ghn7BbgyFX3v762OCdx127EkA"} +!84 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 16, !"UnreadByte", !"_llgo_func$8rsrSd_r3UHd_2DiYTyaOKR7BYkei4zw5ysG35KF38w"} +!85 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 17, !"UnreadRune", !"_llgo_func$8rsrSd_r3UHd_2DiYTyaOKR7BYkei4zw5ysG35KF38w"} +!86 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 18, !"Write", !"_llgo_func$G2hch9Iy9DrhKKsg70PbL54bK-XSl-1IUUORN17J2Dk"} +!87 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 19, !"WriteByte", !"_llgo_func$w4tN9iibS_UimF5vLUWoKP0uAk2tJZF26VqETo_8LVg"} +!88 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 20, !"WriteRune", !"_llgo_func$uf8yw1UkUdbDuCneSpNKIq_NThWIEVE7f1IYfJGz_bw"} +!89 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 21, !"WriteString", !"_llgo_func$thH5FBpdXzJNnCpSfiLU5ItTntFU6LWp0RJhDm2XJjw"} +!90 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 22, !"WriteTo", !"_llgo_func$vSv85k0UY6JWccAc3T-lvdCx9J-4GM-oZC9zGLrxW1M"} +!91 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 23, !"bytes.empty", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!92 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 24, !"bytes.grow", !"_llgo_func$ekGNsrYBSzltfAjxbl6T8H6Yq8j16wzqS3nDj2xxGMU"} +!93 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 25, !"bytes.readSlice", !"_llgo_func$aJkaU3jhXr0Q2QraTe2_TTdupeMMW2MD66UwBxynRM0"} +!94 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 26, !"bytes.tryGrowByReslice", !"_llgo_func$qVJ5SH6qhXP_h0AM41vpBGzQEMp-fQIfvwQEJy5NI8M"} +!95 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 0, !"Available", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!96 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 1, !"AvailableBuffer", !"_llgo_func$Z_-7GWzB37LCYRTQLsSYmEihg_hqBK8o_GbT88pqnPY"} +!97 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 2, !"Bytes", !"_llgo_func$Z_-7GWzB37LCYRTQLsSYmEihg_hqBK8o_GbT88pqnPY"} +!98 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 3, !"Cap", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!99 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 4, !"Grow", !"_llgo_func$VZ-8VPNF1RaLICwxc1Ghn7BbgyFX3v762OCdx127EkA"} +!100 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 5, !"Len", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!101 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 6, !"Next", !"_llgo_func$d4kMA_oCkLwnd1j8nVlv1hwRarEVuCIrDCpnHhDz9UY"} +!102 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 7, !"Read", !"_llgo_func$G2hch9Iy9DrhKKsg70PbL54bK-XSl-1IUUORN17J2Dk"} +!103 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 8, !"ReadByte", !"_llgo_func$lukqSsfDYBoIp_R8GMojGkZnrYDqaq2iHn8RkCjW7iQ"} +!104 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 9, !"ReadBytes", !"_llgo_func$aJkaU3jhXr0Q2QraTe2_TTdupeMMW2MD66UwBxynRM0"} +!105 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 10, !"ReadFrom", !"_llgo_func$uVmBDI0DMcrui3Q9y-g_hbtVN8JckQ18V2wmO5_G7A8"} +!106 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 11, !"ReadRune", !"_llgo_func$q-bw-_pPYBCXnr1TXIF8sOD4fVVzzIlpHqD-A13AB4Y"} +!107 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 12, !"ReadString", !"_llgo_func$TBlCn7YTQdraI1HMiBWmkrqIGG-8UgD1UVyJy62Z_0o"} +!108 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 13, !"Reset", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!109 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 14, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!110 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 15, !"Truncate", !"_llgo_func$VZ-8VPNF1RaLICwxc1Ghn7BbgyFX3v762OCdx127EkA"} +!111 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 16, !"UnreadByte", !"_llgo_func$8rsrSd_r3UHd_2DiYTyaOKR7BYkei4zw5ysG35KF38w"} +!112 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 17, !"UnreadRune", !"_llgo_func$8rsrSd_r3UHd_2DiYTyaOKR7BYkei4zw5ysG35KF38w"} +!113 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 18, !"Write", !"_llgo_func$G2hch9Iy9DrhKKsg70PbL54bK-XSl-1IUUORN17J2Dk"} +!114 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 19, !"WriteByte", !"_llgo_func$w4tN9iibS_UimF5vLUWoKP0uAk2tJZF26VqETo_8LVg"} +!115 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 20, !"WriteRune", !"_llgo_func$uf8yw1UkUdbDuCneSpNKIq_NThWIEVE7f1IYfJGz_bw"} +!116 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 21, !"WriteString", !"_llgo_func$thH5FBpdXzJNnCpSfiLU5ItTntFU6LWp0RJhDm2XJjw"} +!117 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 22, !"WriteTo", !"_llgo_func$vSv85k0UY6JWccAc3T-lvdCx9J-4GM-oZC9zGLrxW1M"} +!118 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 23, !"bytes.empty", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!119 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 24, !"bytes.grow", !"_llgo_func$ekGNsrYBSzltfAjxbl6T8H6Yq8j16wzqS3nDj2xxGMU"} +!120 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 25, !"bytes.readSlice", !"_llgo_func$aJkaU3jhXr0Q2QraTe2_TTdupeMMW2MD66UwBxynRM0"} +!121 = !{!"*github.com/goplus/llgo/cl/_testgo/abimethod.struct$RGW016k7zllXgGPm1CvD5-IBe-9lphOOTCFtYyDGLjY", i32 26, !"bytes.tryGrowByReslice", !"_llgo_func$qVJ5SH6qhXP_h0AM41vpBGzQEMp-fQIfvwQEJy5NI8M"} +!122 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.Pointer[any]", i32 0, !"Load", !"_llgo_func$oqZ09zjnrQRdlivNw60EomwRoboDQbCk5_Y4MGDpQMQ"} +!123 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.Pointer[any]", i32 1, !"Store", !"_llgo_func$Y8Pl6IHgSDuynhMRTXPlqFo9zl71SSTuMe0Wi5m8eWw"} +!124 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous1", !"_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.I", !"Demo1", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!125 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous2", !"_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.I", !"Demo1", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!126 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous3", !"_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.I", !"Demo1", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!127 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous4", !"_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.I", !"Demo1", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!128 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous5", !"_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.I2", !"Demo2", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!129 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous6", !"_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.I2", !"Demo2", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!130 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous7", !"_llgo_iface$58AxoxqQ6sGUOM73FOqFrXsMlgxkU4HGd-S1Wl-ssYw", !"Demo1", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!131 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous7", !"_llgo_iface$58AxoxqQ6sGUOM73FOqFrXsMlgxkU4HGd-S1Wl-ssYw", !"Demo2", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!132 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous8", !"github.com/goplus/llgo/cl/_testgo/abimethod.iface$kT5SIXt45Cspjl04Bof3DZVSOIltlDo-njpk6KqtZvA", !"Demo1", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!133 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous8", !"github.com/goplus/llgo/cl/_testgo/abimethod.iface$kT5SIXt45Cspjl04Bof3DZVSOIltlDo-njpk6KqtZvA", !"Demo2", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!134 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymous8", !"github.com/goplus/llgo/cl/_testgo/abimethod.iface$kT5SIXt45Cspjl04Bof3DZVSOIltlDo-njpk6KqtZvA", !"github.com/goplus/llgo/cl/_testgo/abimethod.demo3", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!135 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testAnonymousBuffer", !"_llgo_fmt.Stringer", !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!136 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testGeneric", !"_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.IP", !"Store", !"_llgo_func$Y8Pl6IHgSDuynhMRTXPlqFo9zl71SSTuMe0Wi5m8eWw"} +!137 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testGeneric", !"_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.IP", !"Load", !"_llgo_func$oqZ09zjnrQRdlivNw60EomwRoboDQbCk5_Y4MGDpQMQ"} +!138 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testNamed1", !"_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.I", !"Demo1", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!139 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testNamed2", !"_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.I", !"Demo1", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!140 = !{!"github.com/goplus/llgo/cl/_testgo/abimethod.testNamed3", !"_llgo_github.com/goplus/llgo/cl/_testgo/abimethod.I2", !"Demo2", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} diff --git a/cl/_testgo/closureall/out.ll b/cl/_testgo/closureall/out.ll index 0d1f779163..649ea8722d 100644 --- a/cl/_testgo/closureall/out.ll +++ b/cl/_testgo/closureall/out.ll @@ -274,3 +274,14 @@ _llgo_0: declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.IfacePtrData"(%"github.com/goplus/llgo/runtime/internal/runtime.iface") attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useiface = !{!0, !1} +!llgo.methodoff = !{!2, !3, !4} +!llgo.useifacemethod = !{!5} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/closureall.main", !"*_llgo_github.com/goplus/llgo/cl/_testgo/closureall.S"} +!1 = !{!"github.com/goplus/llgo/cl/_testgo/closureall.main", !"_llgo_string"} +!2 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/closureall.S", i32 0, !"Inc", !"_llgo_func$ekGNsrYBSzltfAjxbl6T8H6Yq8j16wzqS3nDj2xxGMU"} +!3 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/closureall.S", i32 0, !"Add", !"_llgo_func$ekGNsrYBSzltfAjxbl6T8H6Yq8j16wzqS3nDj2xxGMU"} +!4 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/closureall.S", i32 1, !"Inc", !"_llgo_func$ekGNsrYBSzltfAjxbl6T8H6Yq8j16wzqS3nDj2xxGMU"} +!5 = !{!"github.com/goplus/llgo/cl/_testgo/closureall.interface{Add(int) int}.Add$bound", !"_llgo_iface$VdBKYV8-gcMjZtZfcf-u2oKoj9Lu3VXwuG8TGCW2S4A", !"Add", !"_llgo_func$ekGNsrYBSzltfAjxbl6T8H6Yq8j16wzqS3nDj2xxGMU"} diff --git a/cl/_testgo/cursor/out.ll b/cl/_testgo/cursor/out.ll index bc18f282f4..1995997433 100644 --- a/cl/_testgo/cursor/out.ll +++ b/cl/_testgo/cursor/out.ll @@ -2812,3 +2812,193 @@ declare i64 @"go/ast.(*ValueSpec).Pos"(ptr) declare void @"go/ast.(*ValueSpec).specNode"(ptr) attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useiface = !{!0, !1} +!llgo.methodoff = !{!2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43, !44, !45, !46, !47, !48, !49, !50, !51, !52, !53, !54, !55, !56, !57, !58, !59, !60, !61, !62, !63, !64, !65, !66, !67, !68, !69, !70, !71, !72, !73, !74, !75, !76, !77, !78, !79, !80, !81, !82, !83, !84, !85, !86, !87, !88, !89, !90, !91, !92, !93, !94, !95, !96, !97, !98, !99, !100, !101, !102, !103, !104, !105, !106, !107, !108, !109, !110, !111, !112, !113, !114, !115, !116, !117, !118, !119, !120, !121, !122, !123, !124, !125, !126, !127, !128, !129, !130, !131, !132, !133, !134, !135, !136, !137, !138, !139, !140, !141, !142, !143, !144, !145, !146, !147, !148, !149, !150, !151, !152, !153, !154, !155, !156, !157, !158, !159, !160, !161, !162, !163, !164, !165, !166, !167, !168, !169, !170, !171, !172, !173, !174, !175, !176, !177, !178, !179, !180, !181, !182, !183, !184, !185} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/cursor.Cursor.FindNode", !"_llgo_string"} +!1 = !{!"github.com/goplus/llgo/cl/_testgo/cursor.Cursor.FindNode$1", !"_llgo_string"} +!2 = !{!"*_llgo_go/token.Pos", i32 0, !"IsValid", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!3 = !{!"_llgo_go/token.Pos", i32 0, !"IsValid", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!4 = !{!"*_llgo_go/ast.ObjKind", i32 0, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!5 = !{!"_llgo_go/ast.ObjKind", i32 0, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!6 = !{!"*_llgo_go/ast.Object", i32 0, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!7 = !{!"*_llgo_go/ast.Ident", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!8 = !{!"*_llgo_go/ast.Ident", i32 1, !"IsExported", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!9 = !{!"*_llgo_go/ast.Ident", i32 2, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!10 = !{!"*_llgo_go/ast.Ident", i32 3, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!11 = !{!"*_llgo_go/ast.Ident", i32 4, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!12 = !{!"*_llgo_go/ast.ArrayType", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!13 = !{!"*_llgo_go/ast.ArrayType", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!14 = !{!"*_llgo_go/ast.ArrayType", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!15 = !{!"*_llgo_go/token.Token", i32 0, !"IsKeyword", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!16 = !{!"*_llgo_go/token.Token", i32 1, !"IsLiteral", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!17 = !{!"*_llgo_go/token.Token", i32 2, !"IsOperator", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!18 = !{!"*_llgo_go/token.Token", i32 3, !"Precedence", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!19 = !{!"*_llgo_go/token.Token", i32 4, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!20 = !{!"_llgo_go/token.Token", i32 0, !"IsKeyword", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!21 = !{!"_llgo_go/token.Token", i32 1, !"IsLiteral", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!22 = !{!"_llgo_go/token.Token", i32 2, !"IsOperator", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!23 = !{!"_llgo_go/token.Token", i32 3, !"Precedence", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!24 = !{!"_llgo_go/token.Token", i32 4, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!25 = !{!"*_llgo_go/ast.AssignStmt", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!26 = !{!"*_llgo_go/ast.AssignStmt", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!27 = !{!"*_llgo_go/ast.AssignStmt", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!28 = !{!"*_llgo_go/ast.BadDecl", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!29 = !{!"*_llgo_go/ast.BadDecl", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!30 = !{!"*_llgo_go/ast.BadDecl", i32 2, !"go/ast.declNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!31 = !{!"*_llgo_go/ast.BadExpr", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!32 = !{!"*_llgo_go/ast.BadExpr", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!33 = !{!"*_llgo_go/ast.BadExpr", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!34 = !{!"*_llgo_go/ast.BadStmt", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!35 = !{!"*_llgo_go/ast.BadStmt", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!36 = !{!"*_llgo_go/ast.BadStmt", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!37 = !{!"*_llgo_go/ast.BasicLit", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!38 = !{!"*_llgo_go/ast.BasicLit", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!39 = !{!"*_llgo_go/ast.BasicLit", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!40 = !{!"*_llgo_go/ast.BinaryExpr", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!41 = !{!"*_llgo_go/ast.BinaryExpr", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!42 = !{!"*_llgo_go/ast.BinaryExpr", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!43 = !{!"*_llgo_go/ast.BlockStmt", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!44 = !{!"*_llgo_go/ast.BlockStmt", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!45 = !{!"*_llgo_go/ast.BlockStmt", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!46 = !{!"*_llgo_go/ast.BranchStmt", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!47 = !{!"*_llgo_go/ast.BranchStmt", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!48 = !{!"*_llgo_go/ast.BranchStmt", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!49 = !{!"*_llgo_go/ast.CallExpr", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!50 = !{!"*_llgo_go/ast.CallExpr", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!51 = !{!"*_llgo_go/ast.CallExpr", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!52 = !{!"*_llgo_go/ast.CaseClause", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!53 = !{!"*_llgo_go/ast.CaseClause", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!54 = !{!"*_llgo_go/ast.CaseClause", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!55 = !{!"*_llgo_go/ast.ChanType", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!56 = !{!"*_llgo_go/ast.ChanType", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!57 = !{!"*_llgo_go/ast.ChanType", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!58 = !{!"*_llgo_go/ast.CommClause", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!59 = !{!"*_llgo_go/ast.CommClause", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!60 = !{!"*_llgo_go/ast.CommClause", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!61 = !{!"*_llgo_go/ast.Comment", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!62 = !{!"*_llgo_go/ast.Comment", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!63 = !{!"*_llgo_go/ast.CommentGroup", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!64 = !{!"*_llgo_go/ast.CommentGroup", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!65 = !{!"*_llgo_go/ast.CommentGroup", i32 2, !"Text", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!66 = !{!"*_llgo_go/ast.CompositeLit", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!67 = !{!"*_llgo_go/ast.CompositeLit", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!68 = !{!"*_llgo_go/ast.CompositeLit", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!69 = !{!"*_llgo_go/ast.DeclStmt", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!70 = !{!"*_llgo_go/ast.DeclStmt", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!71 = !{!"*_llgo_go/ast.DeclStmt", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!72 = !{!"*_llgo_go/ast.DeferStmt", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!73 = !{!"*_llgo_go/ast.DeferStmt", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!74 = !{!"*_llgo_go/ast.DeferStmt", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!75 = !{!"*_llgo_go/ast.Ellipsis", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!76 = !{!"*_llgo_go/ast.Ellipsis", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!77 = !{!"*_llgo_go/ast.Ellipsis", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!78 = !{!"*_llgo_go/ast.EmptyStmt", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!79 = !{!"*_llgo_go/ast.EmptyStmt", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!80 = !{!"*_llgo_go/ast.EmptyStmt", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!81 = !{!"*_llgo_go/ast.ExprStmt", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!82 = !{!"*_llgo_go/ast.ExprStmt", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!83 = !{!"*_llgo_go/ast.ExprStmt", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!84 = !{!"*_llgo_go/ast.Field", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!85 = !{!"*_llgo_go/ast.Field", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!86 = !{!"*_llgo_go/ast.FieldList", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!87 = !{!"*_llgo_go/ast.FieldList", i32 1, !"NumFields", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!88 = !{!"*_llgo_go/ast.FieldList", i32 2, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!89 = !{!"*_llgo_go/ast.Scope", i32 0, !"Insert", !"_llgo_func$6Bzrve4Ehr-C8uebix54ffuv5HX-Qd3V5Ir1RrkuIIQ"} +!90 = !{!"*_llgo_go/ast.Scope", i32 1, !"Lookup", !"_llgo_func$DskKPFGJyA_zqt8KHhnaaEzc7yv07D3u6QVXgrOswcg"} +!91 = !{!"*_llgo_go/ast.Scope", i32 2, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!92 = !{!"*_llgo_go/ast.ImportSpec", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!93 = !{!"*_llgo_go/ast.ImportSpec", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!94 = !{!"*_llgo_go/ast.ImportSpec", i32 2, !"go/ast.specNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!95 = !{!"*_llgo_go/ast.File", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!96 = !{!"*_llgo_go/ast.File", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!97 = !{!"*_llgo_go/ast.ForStmt", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!98 = !{!"*_llgo_go/ast.ForStmt", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!99 = !{!"*_llgo_go/ast.ForStmt", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!100 = !{!"*_llgo_go/ast.FuncType", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!101 = !{!"*_llgo_go/ast.FuncType", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!102 = !{!"*_llgo_go/ast.FuncType", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!103 = !{!"*_llgo_go/ast.FuncDecl", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!104 = !{!"*_llgo_go/ast.FuncDecl", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!105 = !{!"*_llgo_go/ast.FuncDecl", i32 2, !"go/ast.declNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!106 = !{!"*_llgo_go/ast.FuncLit", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!107 = !{!"*_llgo_go/ast.FuncLit", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!108 = !{!"*_llgo_go/ast.FuncLit", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!109 = !{!"*_llgo_go/ast.GenDecl", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!110 = !{!"*_llgo_go/ast.GenDecl", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!111 = !{!"*_llgo_go/ast.GenDecl", i32 2, !"go/ast.declNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!112 = !{!"*_llgo_go/ast.GoStmt", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!113 = !{!"*_llgo_go/ast.GoStmt", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!114 = !{!"*_llgo_go/ast.GoStmt", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!115 = !{!"*_llgo_go/ast.IfStmt", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!116 = !{!"*_llgo_go/ast.IfStmt", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!117 = !{!"*_llgo_go/ast.IfStmt", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!118 = !{!"*_llgo_go/ast.IncDecStmt", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!119 = !{!"*_llgo_go/ast.IncDecStmt", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!120 = !{!"*_llgo_go/ast.IncDecStmt", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!121 = !{!"*_llgo_go/ast.IndexExpr", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!122 = !{!"*_llgo_go/ast.IndexExpr", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!123 = !{!"*_llgo_go/ast.IndexExpr", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!124 = !{!"*_llgo_go/ast.IndexListExpr", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!125 = !{!"*_llgo_go/ast.IndexListExpr", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!126 = !{!"*_llgo_go/ast.IndexListExpr", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!127 = !{!"*_llgo_go/ast.InterfaceType", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!128 = !{!"*_llgo_go/ast.InterfaceType", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!129 = !{!"*_llgo_go/ast.InterfaceType", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!130 = !{!"*_llgo_go/ast.KeyValueExpr", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!131 = !{!"*_llgo_go/ast.KeyValueExpr", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!132 = !{!"*_llgo_go/ast.KeyValueExpr", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!133 = !{!"*_llgo_go/ast.LabeledStmt", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!134 = !{!"*_llgo_go/ast.LabeledStmt", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!135 = !{!"*_llgo_go/ast.LabeledStmt", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!136 = !{!"*_llgo_go/ast.MapType", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!137 = !{!"*_llgo_go/ast.MapType", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!138 = !{!"*_llgo_go/ast.MapType", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!139 = !{!"*_llgo_go/ast.Package", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!140 = !{!"*_llgo_go/ast.Package", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!141 = !{!"*_llgo_go/ast.ParenExpr", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!142 = !{!"*_llgo_go/ast.ParenExpr", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!143 = !{!"*_llgo_go/ast.ParenExpr", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!144 = !{!"*_llgo_go/ast.RangeStmt", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!145 = !{!"*_llgo_go/ast.RangeStmt", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!146 = !{!"*_llgo_go/ast.RangeStmt", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!147 = !{!"*_llgo_go/ast.ReturnStmt", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!148 = !{!"*_llgo_go/ast.ReturnStmt", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!149 = !{!"*_llgo_go/ast.ReturnStmt", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!150 = !{!"*_llgo_go/ast.SelectStmt", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!151 = !{!"*_llgo_go/ast.SelectStmt", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!152 = !{!"*_llgo_go/ast.SelectStmt", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!153 = !{!"*_llgo_go/ast.SelectorExpr", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!154 = !{!"*_llgo_go/ast.SelectorExpr", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!155 = !{!"*_llgo_go/ast.SelectorExpr", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!156 = !{!"*_llgo_go/ast.SendStmt", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!157 = !{!"*_llgo_go/ast.SendStmt", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!158 = !{!"*_llgo_go/ast.SendStmt", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!159 = !{!"*_llgo_go/ast.SliceExpr", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!160 = !{!"*_llgo_go/ast.SliceExpr", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!161 = !{!"*_llgo_go/ast.SliceExpr", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!162 = !{!"*_llgo_go/ast.StarExpr", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!163 = !{!"*_llgo_go/ast.StarExpr", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!164 = !{!"*_llgo_go/ast.StarExpr", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!165 = !{!"*_llgo_go/ast.StructType", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!166 = !{!"*_llgo_go/ast.StructType", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!167 = !{!"*_llgo_go/ast.StructType", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!168 = !{!"*_llgo_go/ast.SwitchStmt", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!169 = !{!"*_llgo_go/ast.SwitchStmt", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!170 = !{!"*_llgo_go/ast.SwitchStmt", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!171 = !{!"*_llgo_go/ast.TypeAssertExpr", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!172 = !{!"*_llgo_go/ast.TypeAssertExpr", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!173 = !{!"*_llgo_go/ast.TypeAssertExpr", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!174 = !{!"*_llgo_go/ast.TypeSpec", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!175 = !{!"*_llgo_go/ast.TypeSpec", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!176 = !{!"*_llgo_go/ast.TypeSpec", i32 2, !"go/ast.specNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!177 = !{!"*_llgo_go/ast.TypeSwitchStmt", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!178 = !{!"*_llgo_go/ast.TypeSwitchStmt", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!179 = !{!"*_llgo_go/ast.TypeSwitchStmt", i32 2, !"go/ast.stmtNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!180 = !{!"*_llgo_go/ast.UnaryExpr", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!181 = !{!"*_llgo_go/ast.UnaryExpr", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!182 = !{!"*_llgo_go/ast.UnaryExpr", i32 2, !"go/ast.exprNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!183 = !{!"*_llgo_go/ast.ValueSpec", i32 0, !"End", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!184 = !{!"*_llgo_go/ast.ValueSpec", i32 1, !"Pos", !"_llgo_func$CJFKsfrtVsmWyEEPXCTr-THQYm4CSPEiO6h57SNQxKU"} +!185 = !{!"*_llgo_go/ast.ValueSpec", i32 2, !"go/ast.specNode", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} diff --git a/cl/_testgo/embedunexport-1598/out.ll b/cl/_testgo/embedunexport-1598/out.ll index 6f08d5e099..563b1a2b9e 100644 --- a/cl/_testgo/embedunexport-1598/out.ll +++ b/cl/_testgo/embedunexport-1598/out.ll @@ -174,3 +174,16 @@ declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintString"(%"gi declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintByte"(i8) attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useiface = !{!0} +!llgo.methodoff = !{!1, !2, !3, !4, !5, !6} +!llgo.useifacemethod = !{!7} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/embedunexport-1598.main", !"*_llgo_github.com/goplus/llgo/cl/_testgo/embedunexport-1598.Wrapped"} +!1 = !{!"*_llgo_github.com/goplus/llgo/cl/_testdata/embedunexport.Base", i32 0, !"Name", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!2 = !{!"*_llgo_github.com/goplus/llgo/cl/_testdata/embedunexport.Base", i32 1, !"github.com/goplus/llgo/cl/_testdata/embedunexport.setName", !"_llgo_func$dlTgtqQDYoqfVBQYEBE1Fa3ytcia1pdKaKVOnw8ZjkA"} +!3 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/embedunexport-1598.Wrapped", i32 0, !"Name", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!4 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/embedunexport-1598.Wrapped", i32 1, !"github.com/goplus/llgo/cl/_testdata/embedunexport.setName", !"_llgo_func$dlTgtqQDYoqfVBQYEBE1Fa3ytcia1pdKaKVOnw8ZjkA"} +!5 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/embedunexport-1598.Wrapped", i32 0, !"Name", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!6 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/embedunexport-1598.Wrapped", i32 1, !"github.com/goplus/llgo/cl/_testdata/embedunexport.setName", !"_llgo_func$dlTgtqQDYoqfVBQYEBE1Fa3ytcia1pdKaKVOnw8ZjkA"} +!7 = !{!"github.com/goplus/llgo/cl/_testgo/embedunexport-1598.main", !"_llgo_github.com/goplus/llgo/cl/_testdata/embedunexport.Object", !"Name", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} diff --git a/cl/_testgo/equal/out.ll b/cl/_testgo/equal/out.ll index fbbe0df1ed..5a56e2ded8 100644 --- a/cl/_testgo/equal/out.ll +++ b/cl/_testgo/equal/out.ll @@ -525,3 +525,14 @@ _llgo_0: declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.MakeMap"(ptr, i64) attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useiface = !{!0, !1, !2, !3, !4, !5, !6, !7} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/equal.assert", !"_llgo_string"} +!1 = !{!"github.com/goplus/llgo/cl/_testgo/equal.init#3", !"_llgo_int"} +!2 = !{!"github.com/goplus/llgo/cl/_testgo/equal.init#3", !"_llgo_string"} +!3 = !{!"github.com/goplus/llgo/cl/_testgo/equal.init#5", !"_llgo_int"} +!4 = !{!"github.com/goplus/llgo/cl/_testgo/equal.init#5", !"_llgo_struct$n1H8J_3prDN3firMwPxBLVTkE5hJ9Di-AqNvaC9jczw"} +!5 = !{!"github.com/goplus/llgo/cl/_testgo/equal.init#5", !"_llgo_github.com/goplus/llgo/cl/_testgo/equal.T"} +!6 = !{!"github.com/goplus/llgo/cl/_testgo/equal.init#5", !"_llgo_string"} +!7 = !{!"github.com/goplus/llgo/cl/_testgo/equal.init#5", !"_llgo_github.com/goplus/llgo/cl/_testgo/equal.N"} diff --git a/cl/_testgo/errors/out.ll b/cl/_testgo/errors/out.ll index fc7a97faea..db4859fb6e 100644 --- a/cl/_testgo/errors/out.ll +++ b/cl/_testgo/errors/out.ll @@ -123,3 +123,11 @@ declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintByte"(i8) declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.IfacePtrData"(%"github.com/goplus/llgo/runtime/internal/runtime.iface") declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintString"(%"github.com/goplus/llgo/runtime/internal/runtime.String") + +!llgo.useiface = !{!0} +!llgo.methodoff = !{!1} +!llgo.useifacemethod = !{!2} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/errors.New", !"*_llgo_github.com/goplus/llgo/cl/_testgo/errors.errorString"} +!1 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/errors.errorString", i32 0, !"Error", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!2 = !{!"github.com/goplus/llgo/cl/_testgo/errors.main", !"_llgo_error", !"Error", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} diff --git a/cl/_testgo/ifaceconv/out.ll b/cl/_testgo/ifaceconv/out.ll index 4a8243f6e5..ebeb610cea 100644 --- a/cl/_testgo/ifaceconv/out.ll +++ b/cl/_testgo/ifaceconv/out.ll @@ -471,3 +471,16 @@ declare i1 @"github.com/goplus/llgo/runtime/internal/runtime.EfaceEqual"(%"githu declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintString"(%"github.com/goplus/llgo/runtime/internal/runtime.String") declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintByte"(i8) + +!llgo.useiface = !{!0, !1, !2} +!llgo.methodoff = !{!3, !4, !5, !6, !7, !8} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/ifaceconv.main", !"_llgo_string"} +!1 = !{!"github.com/goplus/llgo/cl/_testgo/ifaceconv.main", !"_llgo_github.com/goplus/llgo/cl/_testgo/ifaceconv.C1"} +!2 = !{!"github.com/goplus/llgo/cl/_testgo/ifaceconv.main", !"_llgo_github.com/goplus/llgo/cl/_testgo/ifaceconv.C2"} +!3 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/ifaceconv.C1", i32 0, !"github.com/goplus/llgo/cl/_testgo/ifaceconv.f", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!4 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/ifaceconv.C1", i32 0, !"github.com/goplus/llgo/cl/_testgo/ifaceconv.f", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!5 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/ifaceconv.C2", i32 0, !"github.com/goplus/llgo/cl/_testgo/ifaceconv.f", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!6 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/ifaceconv.C2", i32 1, !"github.com/goplus/llgo/cl/_testgo/ifaceconv.g", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!7 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/ifaceconv.C2", i32 0, !"github.com/goplus/llgo/cl/_testgo/ifaceconv.f", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!8 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/ifaceconv.C2", i32 1, !"github.com/goplus/llgo/cl/_testgo/ifaceconv.g", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} diff --git a/cl/_testgo/ifaceprom/out.ll b/cl/_testgo/ifaceprom/out.ll index a001d6e3a3..d82b6eb562 100644 --- a/cl/_testgo/ifaceprom/out.ll +++ b/cl/_testgo/ifaceprom/out.ll @@ -480,3 +480,23 @@ declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintString"(%"gi declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintByte"(i8) attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useifacemethod = !{!0, !1, !2, !3, !4, !5, !6, !7} +!llgo.useiface = !{!8, !9, !10} +!llgo.methodoff = !{!11, !12, !13, !14} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/ifaceprom.S.one", !"_llgo_github.com/goplus/llgo/cl/_testgo/ifaceprom.I", !"github.com/goplus/llgo/cl/_testgo/ifaceprom.one", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!1 = !{!"github.com/goplus/llgo/cl/_testgo/ifaceprom.S.two", !"_llgo_github.com/goplus/llgo/cl/_testgo/ifaceprom.I", !"github.com/goplus/llgo/cl/_testgo/ifaceprom.two", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!2 = !{!"github.com/goplus/llgo/cl/_testgo/ifaceprom.(*S).one", !"_llgo_github.com/goplus/llgo/cl/_testgo/ifaceprom.I", !"github.com/goplus/llgo/cl/_testgo/ifaceprom.one", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!3 = !{!"github.com/goplus/llgo/cl/_testgo/ifaceprom.(*S).two", !"_llgo_github.com/goplus/llgo/cl/_testgo/ifaceprom.I", !"github.com/goplus/llgo/cl/_testgo/ifaceprom.two", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!4 = !{!"github.com/goplus/llgo/cl/_testgo/ifaceprom.main", !"_llgo_github.com/goplus/llgo/cl/_testgo/ifaceprom.I", !"github.com/goplus/llgo/cl/_testgo/ifaceprom.one", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!5 = !{!"github.com/goplus/llgo/cl/_testgo/ifaceprom.main", !"_llgo_github.com/goplus/llgo/cl/_testgo/ifaceprom.I", !"github.com/goplus/llgo/cl/_testgo/ifaceprom.two", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!6 = !{!"github.com/goplus/llgo/cl/_testgo/ifaceprom.I.one$bound", !"_llgo_github.com/goplus/llgo/cl/_testgo/ifaceprom.I", !"github.com/goplus/llgo/cl/_testgo/ifaceprom.one", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!7 = !{!"github.com/goplus/llgo/cl/_testgo/ifaceprom.I.two$bound", !"_llgo_github.com/goplus/llgo/cl/_testgo/ifaceprom.I", !"github.com/goplus/llgo/cl/_testgo/ifaceprom.two", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!8 = !{!"github.com/goplus/llgo/cl/_testgo/ifaceprom.main", !"_llgo_github.com/goplus/llgo/cl/_testgo/ifaceprom.impl"} +!9 = !{!"github.com/goplus/llgo/cl/_testgo/ifaceprom.main", !"_llgo_int"} +!10 = !{!"github.com/goplus/llgo/cl/_testgo/ifaceprom.main", !"_llgo_string"} +!11 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/ifaceprom.impl", i32 0, !"github.com/goplus/llgo/cl/_testgo/ifaceprom.one", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!12 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/ifaceprom.impl", i32 1, !"github.com/goplus/llgo/cl/_testgo/ifaceprom.two", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!13 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/ifaceprom.impl", i32 0, !"github.com/goplus/llgo/cl/_testgo/ifaceprom.one", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!14 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/ifaceprom.impl", i32 1, !"github.com/goplus/llgo/cl/_testgo/ifaceprom.two", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} diff --git a/cl/_testgo/interface/out.ll b/cl/_testgo/interface/out.ll index 9a6ac02890..65e40eba33 100644 --- a/cl/_testgo/interface/out.ll +++ b/cl/_testgo/interface/out.ll @@ -235,3 +235,18 @@ declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintBool"(i1) declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.IfacePtrData"(%"github.com/goplus/llgo/runtime/internal/runtime.iface") attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useiface = !{!0, !1} +!llgo.methodoff = !{!2, !3, !4, !5, !6, !7, !8} +!llgo.useifacemethod = !{!9} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/interface.main", !"*_llgo_github.com/goplus/llgo/cl/_testgo/interface.Game1"} +!1 = !{!"github.com/goplus/llgo/cl/_testgo/interface.main", !"*_llgo_github.com/goplus/llgo/cl/_testgo/interface.Game2"} +!2 = !{!"*_llgo_github.com/goplus/llgo/cl/_testdata/foo.Game", i32 0, !"Load", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!3 = !{!"*_llgo_github.com/goplus/llgo/cl/_testdata/foo.Game", i32 1, !"github.com/goplus/llgo/cl/_testdata/foo.initGame", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!4 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/interface.Game1", i32 0, !"Load", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!5 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/interface.Game1", i32 1, !"github.com/goplus/llgo/cl/_testdata/foo.initGame", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!6 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/interface.Game1", i32 0, !"Load", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!7 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/interface.Game1", i32 1, !"github.com/goplus/llgo/cl/_testdata/foo.initGame", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!8 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/interface.Game2", i32 0, !"github.com/goplus/llgo/cl/_testgo/interface.initGame", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!9 = !{!"github.com/goplus/llgo/cl/_testgo/interface.main", !"_llgo_github.com/goplus/llgo/cl/_testdata/foo.Gamer", !"Load", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} diff --git a/cl/_testgo/interface1370/out.ll b/cl/_testgo/interface1370/out.ll index cfd466948d..fc1b1e349b 100644 --- a/cl/_testgo/interface1370/out.ll +++ b/cl/_testgo/interface1370/out.ll @@ -153,3 +153,12 @@ declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintString"(%"gi declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintByte"(i8) declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintInt"(i64) + +!llgo.useiface = !{!0} +!llgo.methodoff = !{!1, !2, !3, !4} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/interface1370.main", !"*_llgo_github.com/goplus/llgo/cl/_testdata/geometry1370.Rectangle"} +!1 = !{!"*_llgo_github.com/goplus/llgo/cl/_testdata/geometry1370.Rectangle", i32 0, !"Area", !"_llgo_func$UYiLlmcWxoOKZPPzvR4LByitNeKoVGoTrB_5ubdOWW8"} +!2 = !{!"*_llgo_github.com/goplus/llgo/cl/_testdata/geometry1370.Rectangle", i32 1, !"GetID", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!3 = !{!"*_llgo_github.com/goplus/llgo/cl/_testdata/geometry1370.Rectangle", i32 2, !"github.com/goplus/llgo/cl/_testdata/geometry1370.setID", !"_llgo_func$VZ-8VPNF1RaLICwxc1Ghn7BbgyFX3v762OCdx127EkA"} +!4 = !{!"*_llgo_github.com/goplus/llgo/cl/_testdata/geometry1370.Rectangle", i32 3, !"github.com/goplus/llgo/cl/_testdata/geometry1370.validate", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} diff --git a/cl/_testgo/invoke/out.ll b/cl/_testgo/invoke/out.ll index 1cdd95e85f..e70464c4b5 100644 --- a/cl/_testgo/invoke/out.ll +++ b/cl/_testgo/invoke/out.ll @@ -518,3 +518,37 @@ _llgo_0: } attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useifacemethod = !{!0} +!llgo.useiface = !{!1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14} +!llgo.methodoff = !{!15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/invoke.invoke", !"_llgo_github.com/goplus/llgo/cl/_testgo/invoke.I", !"Invoke", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!1 = !{!"github.com/goplus/llgo/cl/_testgo/invoke.main", !"_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T"} +!2 = !{!"github.com/goplus/llgo/cl/_testgo/invoke.main", !"*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T"} +!3 = !{!"github.com/goplus/llgo/cl/_testgo/invoke.main", !"_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T1"} +!4 = !{!"github.com/goplus/llgo/cl/_testgo/invoke.main", !"*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T1"} +!5 = !{!"github.com/goplus/llgo/cl/_testgo/invoke.main", !"_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T2"} +!6 = !{!"github.com/goplus/llgo/cl/_testgo/invoke.main", !"*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T2"} +!7 = !{!"github.com/goplus/llgo/cl/_testgo/invoke.main", !"*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T3"} +!8 = !{!"github.com/goplus/llgo/cl/_testgo/invoke.main", !"_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T4"} +!9 = !{!"github.com/goplus/llgo/cl/_testgo/invoke.main", !"*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T4"} +!10 = !{!"github.com/goplus/llgo/cl/_testgo/invoke.main", !"_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T5"} +!11 = !{!"github.com/goplus/llgo/cl/_testgo/invoke.main", !"*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T5"} +!12 = !{!"github.com/goplus/llgo/cl/_testgo/invoke.main", !"_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T6"} +!13 = !{!"github.com/goplus/llgo/cl/_testgo/invoke.main", !"*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T6"} +!14 = !{!"github.com/goplus/llgo/cl/_testgo/invoke.main", !"_llgo_string"} +!15 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T", i32 0, !"Invoke", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!16 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T", i32 1, !"Method", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!17 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T", i32 0, !"Invoke", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!18 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T1", i32 0, !"Invoke", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!19 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T1", i32 0, !"Invoke", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!20 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T2", i32 0, !"Invoke", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!21 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T2", i32 0, !"Invoke", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!22 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T3", i32 0, !"Invoke", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!23 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T4", i32 0, !"Invoke", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!24 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T4", i32 0, !"Invoke", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!25 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T5", i32 0, !"Invoke", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!26 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T5", i32 0, !"Invoke", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!27 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T6", i32 0, !"Invoke", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!28 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T6", i32 0, !"Invoke", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} diff --git a/cl/_testgo/reader/out.ll b/cl/_testgo/reader/out.ll index 49ad7ec3a2..42689823be 100644 --- a/cl/_testgo/reader/out.ll +++ b/cl/_testgo/reader/out.ll @@ -1073,3 +1073,43 @@ declare void @"github.com/goplus/llgo/runtime/internal/runtime.AssertIndexRange" declare { i32, i64 } @"unicode/utf8.DecodeRuneInString"(%"github.com/goplus/llgo/runtime/internal/runtime.String") attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useiface = !{!0, !1, !2, !3, !4, !5} +!llgo.methodoff = !{!6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26} +!llgo.useifacemethod = !{!27, !28, !29, !30, !31, !32, !33, !34} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/reader.NopCloser", !"_llgo_github.com/goplus/llgo/cl/_testgo/reader.nopCloserWriterTo"} +!1 = !{!"github.com/goplus/llgo/cl/_testgo/reader.NopCloser", !"_llgo_github.com/goplus/llgo/cl/_testgo/reader.nopCloser"} +!2 = !{!"github.com/goplus/llgo/cl/_testgo/reader.main", !"*_llgo_github.com/goplus/llgo/cl/_testgo/reader.stringReader"} +!3 = !{!"github.com/goplus/llgo/cl/_testgo/reader.newError", !"*_llgo_github.com/goplus/llgo/cl/_testgo/reader.errorString"} +!4 = !{!"github.com/goplus/llgo/cl/_testgo/reader.nopCloserWriterTo.WriteTo", !"_llgo_string"} +!5 = !{!"github.com/goplus/llgo/cl/_testgo/reader.(*stringReader).WriteTo", !"_llgo_string"} +!6 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reader.nopCloserWriterTo", i32 0, !"Close", !"_llgo_func$8rsrSd_r3UHd_2DiYTyaOKR7BYkei4zw5ysG35KF38w"} +!7 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reader.nopCloserWriterTo", i32 1, !"Read", !"_llgo_func$G2hch9Iy9DrhKKsg70PbL54bK-XSl-1IUUORN17J2Dk"} +!8 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reader.nopCloserWriterTo", i32 2, !"WriteTo", !"_llgo_func$V_kP-r1nn8Ij-G2jGIm9ROLn4CjtLBch-g3Ha7pGJo4"} +!9 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/reader.nopCloserWriterTo", i32 0, !"Close", !"_llgo_func$8rsrSd_r3UHd_2DiYTyaOKR7BYkei4zw5ysG35KF38w"} +!10 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/reader.nopCloserWriterTo", i32 1, !"Read", !"_llgo_func$G2hch9Iy9DrhKKsg70PbL54bK-XSl-1IUUORN17J2Dk"} +!11 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/reader.nopCloserWriterTo", i32 2, !"WriteTo", !"_llgo_func$V_kP-r1nn8Ij-G2jGIm9ROLn4CjtLBch-g3Ha7pGJo4"} +!12 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reader.nopCloser", i32 0, !"Close", !"_llgo_func$8rsrSd_r3UHd_2DiYTyaOKR7BYkei4zw5ysG35KF38w"} +!13 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reader.nopCloser", i32 1, !"Read", !"_llgo_func$G2hch9Iy9DrhKKsg70PbL54bK-XSl-1IUUORN17J2Dk"} +!14 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/reader.nopCloser", i32 0, !"Close", !"_llgo_func$8rsrSd_r3UHd_2DiYTyaOKR7BYkei4zw5ysG35KF38w"} +!15 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/reader.nopCloser", i32 1, !"Read", !"_llgo_func$G2hch9Iy9DrhKKsg70PbL54bK-XSl-1IUUORN17J2Dk"} +!16 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reader.stringReader", i32 0, !"Len", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!17 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reader.stringReader", i32 1, !"Read", !"_llgo_func$G2hch9Iy9DrhKKsg70PbL54bK-XSl-1IUUORN17J2Dk"} +!18 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reader.stringReader", i32 2, !"ReadAt", !"_llgo_func$QoHVzMQ4PMXOd5kbZvdARJn-o_00R6hNyf6LoVk3X_4"} +!19 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reader.stringReader", i32 3, !"ReadByte", !"_llgo_func$lukqSsfDYBoIp_R8GMojGkZnrYDqaq2iHn8RkCjW7iQ"} +!20 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reader.stringReader", i32 4, !"ReadRune", !"_llgo_func$q-bw-_pPYBCXnr1TXIF8sOD4fVVzzIlpHqD-A13AB4Y"} +!21 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reader.stringReader", i32 5, !"Seek", !"_llgo_func$HE7H49xPa1uXmrkMDpqB3RCRGf3qzhLGrxKCEXOYjms"} +!22 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reader.stringReader", i32 6, !"Size", !"_llgo_func$Eoig9xhJM5GShHH5aNPxTZZXp1IZxprRl4zPuv2hkug"} +!23 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reader.stringReader", i32 7, !"UnreadByte", !"_llgo_func$8rsrSd_r3UHd_2DiYTyaOKR7BYkei4zw5ysG35KF38w"} +!24 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reader.stringReader", i32 8, !"UnreadRune", !"_llgo_func$8rsrSd_r3UHd_2DiYTyaOKR7BYkei4zw5ysG35KF38w"} +!25 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reader.stringReader", i32 9, !"WriteTo", !"_llgo_func$V_kP-r1nn8Ij-G2jGIm9ROLn4CjtLBch-g3Ha7pGJo4"} +!26 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reader.errorString", i32 0, !"Error", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!27 = !{!"github.com/goplus/llgo/cl/_testgo/reader.ReadAll", !"_llgo_github.com/goplus/llgo/cl/_testgo/reader.Reader", !"Read", !"_llgo_func$G2hch9Iy9DrhKKsg70PbL54bK-XSl-1IUUORN17J2Dk"} +!28 = !{!"github.com/goplus/llgo/cl/_testgo/reader.WriteString", !"_llgo_github.com/goplus/llgo/cl/_testgo/reader.StringWriter", !"WriteString", !"_llgo_func$thH5FBpdXzJNnCpSfiLU5ItTntFU6LWp0RJhDm2XJjw"} +!29 = !{!"github.com/goplus/llgo/cl/_testgo/reader.WriteString", !"_llgo_github.com/goplus/llgo/cl/_testgo/reader.Writer", !"Write", !"_llgo_func$G2hch9Iy9DrhKKsg70PbL54bK-XSl-1IUUORN17J2Dk"} +!30 = !{!"github.com/goplus/llgo/cl/_testgo/reader.nopCloser.Read", !"_llgo_github.com/goplus/llgo/cl/_testgo/reader.Reader", !"Read", !"_llgo_func$G2hch9Iy9DrhKKsg70PbL54bK-XSl-1IUUORN17J2Dk"} +!31 = !{!"github.com/goplus/llgo/cl/_testgo/reader.(*nopCloser).Read", !"_llgo_github.com/goplus/llgo/cl/_testgo/reader.Reader", !"Read", !"_llgo_func$G2hch9Iy9DrhKKsg70PbL54bK-XSl-1IUUORN17J2Dk"} +!32 = !{!"github.com/goplus/llgo/cl/_testgo/reader.nopCloserWriterTo.Read", !"_llgo_github.com/goplus/llgo/cl/_testgo/reader.Reader", !"Read", !"_llgo_func$G2hch9Iy9DrhKKsg70PbL54bK-XSl-1IUUORN17J2Dk"} +!33 = !{!"github.com/goplus/llgo/cl/_testgo/reader.nopCloserWriterTo.WriteTo", !"_llgo_github.com/goplus/llgo/cl/_testgo/reader.WriterTo", !"WriteTo", !"_llgo_func$V_kP-r1nn8Ij-G2jGIm9ROLn4CjtLBch-g3Ha7pGJo4"} +!34 = !{!"github.com/goplus/llgo/cl/_testgo/reader.(*nopCloserWriterTo).Read", !"_llgo_github.com/goplus/llgo/cl/_testgo/reader.Reader", !"Read", !"_llgo_func$G2hch9Iy9DrhKKsg70PbL54bK-XSl-1IUUORN17J2Dk"} diff --git a/cl/_testgo/reflect/out.ll b/cl/_testgo/reflect/out.ll index 7db6230448..1a2bb6f924 100644 --- a/cl/_testgo/reflect/out.ll +++ b/cl/_testgo/reflect/out.ll @@ -1132,3 +1132,41 @@ declare %"github.com/goplus/llgo/runtime/internal/runtime.iface" @reflect.TypeOf declare %"github.com/goplus/llgo/runtime/internal/runtime.iface" @reflect.MapOf(%"github.com/goplus/llgo/runtime/internal/runtime.iface", %"github.com/goplus/llgo/runtime/internal/runtime.iface") declare %reflect.Value @reflect.MakeMap(%"github.com/goplus/llgo/runtime/internal/runtime.iface") + +!llgo.useiface = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20} +!llgo.useifacemethod = !{!21, !22, !23, !24, !25, !26, !27, !28} +!llgo.methodoff = !{!29} +!llgo.reflectmethod = !{!30, !31} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callClosure", !"_llgo_closure$QIHBTaw1IFobr8yvWpq-2AJFm3xBNhdW_aNBicqUBGk"} +!1 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callClosure", !"_llgo_int"} +!2 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callClosure", !"_llgo_string"} +!3 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callFunc", !"_llgo_closure$QIHBTaw1IFobr8yvWpq-2AJFm3xBNhdW_aNBicqUBGk"} +!4 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callFunc", !"_llgo_int"} +!5 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callFunc", !"_llgo_string"} +!6 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callIMethod", !"*_llgo_github.com/goplus/llgo/cl/_testgo/reflect.T"} +!7 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callIMethod", !"_llgo_int"} +!8 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callIMethod", !"_llgo_string"} +!9 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callMethod", !"*_llgo_github.com/goplus/llgo/cl/_testgo/reflect.T"} +!10 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callMethod", !"_llgo_int"} +!11 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callMethod", !"_llgo_string"} +!12 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callSlice", !"_llgo_closure$FjMjjQr3-2iTiWyZP1IIQFOz0hUCa0OS6pEm5uVV6Pk"} +!13 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callSlice", !"_llgo_int"} +!14 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callSlice", !"[]_llgo_any"} +!15 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.demo", !"_llgo_string"} +!16 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.mapDemo1", !"map[_llgo_int]_llgo_string"} +!17 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.mapDemo1", !"_llgo_string"} +!18 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.mapDemo1", !"_llgo_int"} +!19 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.mapDemo2", !"_llgo_int"} +!20 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.mapDemo2", !"_llgo_string"} +!21 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callClosure", !"_llgo_reflect.Type", !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!22 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callFunc", !"_llgo_reflect.Type", !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!23 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callIMethod", !"_llgo_reflect.Type", !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!24 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callMethod", !"_llgo_reflect.Type", !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!25 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.mapDemo1", !"_llgo_reflect.Type", !"Key", !"_llgo_func$b6KOG2Oj7wt8ogb9H8QPbhEfXhxMMjdxRZgPLK_UOwI"} +!26 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.mapDemo1", !"_llgo_reflect.Type", !"Elem", !"_llgo_func$b6KOG2Oj7wt8ogb9H8QPbhEfXhxMMjdxRZgPLK_UOwI"} +!27 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.mapDemo2", !"_llgo_reflect.Type", !"Key", !"_llgo_func$b6KOG2Oj7wt8ogb9H8QPbhEfXhxMMjdxRZgPLK_UOwI"} +!28 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.mapDemo2", !"_llgo_reflect.Type", !"Elem", !"_llgo_func$b6KOG2Oj7wt8ogb9H8QPbhEfXhxMMjdxRZgPLK_UOwI"} +!29 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reflect.T", i32 0, !"Add", !"_llgo_func$ekGNsrYBSzltfAjxbl6T8H6Yq8j16wzqS3nDj2xxGMU"} +!30 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callIMethod"} +!31 = !{!"github.com/goplus/llgo/cl/_testgo/reflect.callMethod"} diff --git a/cl/_testgo/reflectfn/out.ll b/cl/_testgo/reflectfn/out.ll index 5d229b8573..d74eff7143 100644 --- a/cl/_testgo/reflectfn/out.ll +++ b/cl/_testgo/reflectfn/out.ll @@ -172,3 +172,8 @@ declare %reflect.Value @reflect.ValueOf(%"github.com/goplus/llgo/runtime/interna declare ptr @reflect.Value.UnsafePointer(%reflect.Value) declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintInt"(i64) + +!llgo.useiface = !{!0, !1} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/reflectfn.main", !"_llgo_closure$b7Su1hWaFih-M0M9hMk6nO_RD1K_GQu5WjIXQp6Q2e8"} +!1 = !{!"github.com/goplus/llgo/cl/_testgo/reflectfn.main", !"_llgo_Pointer"} diff --git a/cl/_testgo/reflectmethod/in.go b/cl/_testgo/reflectmethod/in.go new file mode 100644 index 0000000000..626d56b553 --- /dev/null +++ b/cl/_testgo/reflectmethod/in.go @@ -0,0 +1,40 @@ +package main + +import "reflect" + +type T struct{} + +func (T) M() {} + +func typeByNameConst() { + _, _ = reflect.TypeOf(T{}).MethodByName("M") +} + +func typeByNameDynamic(name string) { + _, _ = reflect.TypeOf(T{}).MethodByName(name) +} + +func typeByIndex() { + _ = reflect.TypeOf(T{}).Method(0) +} + +func valueByNameConst(v any) { + _ = reflect.ValueOf(v).MethodByName("M") +} + +func valueByNameDynamic(v any, name string) { + _ = reflect.ValueOf(v).MethodByName(name) +} + +func valueByIndex(v any) { + _ = reflect.ValueOf(v).Method(0) +} + +func main() { + typeByNameConst() + typeByNameDynamic("M") + typeByIndex() + valueByNameConst(T{}) + valueByNameDynamic(T{}, "M") + valueByIndex(T{}) +} diff --git a/cl/_testgo/reflectmethod/out.ll b/cl/_testgo/reflectmethod/out.ll new file mode 100644 index 0000000000..294f5e58de --- /dev/null +++ b/cl/_testgo/reflectmethod/out.ll @@ -0,0 +1,203 @@ +; ModuleID = 'github.com/goplus/llgo/cl/_testgo/reflectmethod' +source_filename = "github.com/goplus/llgo/cl/_testgo/reflectmethod" + +%"github.com/goplus/llgo/runtime/abi.StructType" = type { %"github.com/goplus/llgo/runtime/abi.Type", %"github.com/goplus/llgo/runtime/internal/runtime.String", %"github.com/goplus/llgo/runtime/internal/runtime.Slice" } +%"github.com/goplus/llgo/runtime/abi.Type" = type { i64, i64, i32, i8, i8, i8, i8, { ptr, ptr }, ptr, %"github.com/goplus/llgo/runtime/internal/runtime.String", ptr } +%"github.com/goplus/llgo/runtime/internal/runtime.String" = type { ptr, i64 } +%"github.com/goplus/llgo/runtime/internal/runtime.Slice" = type { ptr, i64, i64 } +%"github.com/goplus/llgo/runtime/abi.UncommonType" = type { %"github.com/goplus/llgo/runtime/internal/runtime.String", i16, i16, i32 } +%"github.com/goplus/llgo/runtime/abi.Method" = type { %"github.com/goplus/llgo/runtime/internal/runtime.String", ptr, ptr, ptr } +%"github.com/goplus/llgo/runtime/abi.PtrType" = type { %"github.com/goplus/llgo/runtime/abi.Type", ptr } +%"github.com/goplus/llgo/runtime/abi.FuncType" = type { %"github.com/goplus/llgo/runtime/abi.Type", %"github.com/goplus/llgo/runtime/internal/runtime.Slice", %"github.com/goplus/llgo/runtime/internal/runtime.Slice" } +%"github.com/goplus/llgo/cl/_testgo/reflectmethod.T" = type {} +%"github.com/goplus/llgo/runtime/internal/runtime.eface" = type { ptr, ptr } +%"github.com/goplus/llgo/runtime/internal/runtime.iface" = type { ptr, ptr } +%reflect.Method = type { %"github.com/goplus/llgo/runtime/internal/runtime.String", %"github.com/goplus/llgo/runtime/internal/runtime.String", %"github.com/goplus/llgo/runtime/internal/runtime.iface", %reflect.Value, i64 } +%reflect.Value = type { ptr, ptr, i64 } + +@"github.com/goplus/llgo/cl/_testgo/reflectmethod.init$guard" = global i1 false, align 1 +@0 = private unnamed_addr constant [1 x i8] c"M", align 1 +@"_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T" = weak_odr constant { %"github.com/goplus/llgo/runtime/abi.StructType", %"github.com/goplus/llgo/runtime/abi.UncommonType", [1 x %"github.com/goplus/llgo/runtime/abi.Method"] } { %"github.com/goplus/llgo/runtime/abi.StructType" { %"github.com/goplus/llgo/runtime/abi.Type" { i64 0, i64 0, i32 -217168049, i8 13, i8 1, i8 1, i8 25, { ptr, ptr } { ptr @"__llgo_stub.github.com/goplus/llgo/runtime/internal/runtime.memequal0", ptr null }, ptr null, %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @1, i64 6 }, ptr @"*_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T" }, %"github.com/goplus/llgo/runtime/internal/runtime.String" zeroinitializer, %"github.com/goplus/llgo/runtime/internal/runtime.Slice" zeroinitializer }, %"github.com/goplus/llgo/runtime/abi.UncommonType" { %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @2, i64 47 }, i16 1, i16 1, i32 24 }, [1 x %"github.com/goplus/llgo/runtime/abi.Method"] [%"github.com/goplus/llgo/runtime/abi.Method" { %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @0, i64 1 }, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", ptr @"github.com/goplus/llgo/cl/_testgo/reflectmethod.(*T).M", ptr @"github.com/goplus/llgo/cl/_testgo/reflectmethod.T.M" }] }, align 8 +@1 = private unnamed_addr constant [6 x i8] c"main.T", align 1 +@"*_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T" = weak_odr constant { %"github.com/goplus/llgo/runtime/abi.PtrType", %"github.com/goplus/llgo/runtime/abi.UncommonType", [1 x %"github.com/goplus/llgo/runtime/abi.Method"] } { %"github.com/goplus/llgo/runtime/abi.PtrType" { %"github.com/goplus/llgo/runtime/abi.Type" { i64 8, i64 8, i32 -682917738, i8 11, i8 8, i8 8, i8 54, { ptr, ptr } { ptr @"__llgo_stub.github.com/goplus/llgo/runtime/internal/runtime.memequalptr", ptr null }, ptr null, %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @1, i64 6 }, ptr null }, ptr @"_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T" }, %"github.com/goplus/llgo/runtime/abi.UncommonType" { %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @2, i64 47 }, i16 1, i16 1, i32 24 }, [1 x %"github.com/goplus/llgo/runtime/abi.Method"] [%"github.com/goplus/llgo/runtime/abi.Method" { %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @0, i64 1 }, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", ptr @"github.com/goplus/llgo/cl/_testgo/reflectmethod.(*T).M", ptr @"github.com/goplus/llgo/cl/_testgo/reflectmethod.(*T).M" }] }, align 8 +@2 = private unnamed_addr constant [47 x i8] c"github.com/goplus/llgo/cl/_testgo/reflectmethod", align 1 +@"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac" = weak_odr constant %"github.com/goplus/llgo/runtime/abi.FuncType" { %"github.com/goplus/llgo/runtime/abi.Type" { i64 8, i64 8, i32 -1790696805, i8 0, i8 8, i8 8, i8 51, { ptr, ptr } zeroinitializer, ptr null, %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @3, i64 6 }, ptr @"*_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac" }, %"github.com/goplus/llgo/runtime/internal/runtime.Slice" zeroinitializer, %"github.com/goplus/llgo/runtime/internal/runtime.Slice" zeroinitializer }, align 8 +@3 = private unnamed_addr constant [6 x i8] c"func()", align 1 +@"*_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac" = weak_odr constant %"github.com/goplus/llgo/runtime/abi.PtrType" { %"github.com/goplus/llgo/runtime/abi.Type" { i64 8, i64 8, i32 -130179135, i8 10, i8 8, i8 8, i8 54, { ptr, ptr } { ptr @"__llgo_stub.github.com/goplus/llgo/runtime/internal/runtime.memequalptr", ptr null }, ptr null, %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @3, i64 6 }, ptr null }, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac" }, align 8 + +define void @"github.com/goplus/llgo/cl/_testgo/reflectmethod.T.M"(%"github.com/goplus/llgo/cl/_testgo/reflectmethod.T" %0) { +_llgo_0: + ret void +} + +define void @"github.com/goplus/llgo/cl/_testgo/reflectmethod.(*T).M"(ptr %0) { +_llgo_0: + %1 = load %"github.com/goplus/llgo/cl/_testgo/reflectmethod.T", ptr %0, align 1 + call void @"github.com/goplus/llgo/cl/_testgo/reflectmethod.T.M"(%"github.com/goplus/llgo/cl/_testgo/reflectmethod.T" %1) + ret void +} + +define void @"github.com/goplus/llgo/cl/_testgo/reflectmethod.init"() { +_llgo_0: + %0 = load i1, ptr @"github.com/goplus/llgo/cl/_testgo/reflectmethod.init$guard", align 1 + br i1 %0, label %_llgo_2, label %_llgo_1 + +_llgo_1: ; preds = %_llgo_0 + store i1 true, ptr @"github.com/goplus/llgo/cl/_testgo/reflectmethod.init$guard", align 1 + call void @reflect.init() + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + ret void +} + +define void @"github.com/goplus/llgo/cl/_testgo/reflectmethod.main"() { +_llgo_0: + call void @"github.com/goplus/llgo/cl/_testgo/reflectmethod.typeByNameConst"() + call void @"github.com/goplus/llgo/cl/_testgo/reflectmethod.typeByNameDynamic"(%"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @0, i64 1 }) + call void @"github.com/goplus/llgo/cl/_testgo/reflectmethod.typeByIndex"() + %0 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 0) + store %"github.com/goplus/llgo/cl/_testgo/reflectmethod.T" zeroinitializer, ptr %0, align 1 + %1 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" { ptr @"_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T", ptr undef }, ptr %0, 1 + call void @"github.com/goplus/llgo/cl/_testgo/reflectmethod.valueByNameConst"(%"github.com/goplus/llgo/runtime/internal/runtime.eface" %1) + %2 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 0) + store %"github.com/goplus/llgo/cl/_testgo/reflectmethod.T" zeroinitializer, ptr %2, align 1 + %3 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" { ptr @"_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T", ptr undef }, ptr %2, 1 + call void @"github.com/goplus/llgo/cl/_testgo/reflectmethod.valueByNameDynamic"(%"github.com/goplus/llgo/runtime/internal/runtime.eface" %3, %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @0, i64 1 }) + %4 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 0) + store %"github.com/goplus/llgo/cl/_testgo/reflectmethod.T" zeroinitializer, ptr %4, align 1 + %5 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" { ptr @"_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T", ptr undef }, ptr %4, 1 + call void @"github.com/goplus/llgo/cl/_testgo/reflectmethod.valueByIndex"(%"github.com/goplus/llgo/runtime/internal/runtime.eface" %5) + ret void +} + +define void @"github.com/goplus/llgo/cl/_testgo/reflectmethod.typeByIndex"() { +_llgo_0: + %0 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 0) + store %"github.com/goplus/llgo/cl/_testgo/reflectmethod.T" zeroinitializer, ptr %0, align 1 + %1 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" { ptr @"_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T", ptr undef }, ptr %0, 1 + %2 = call %"github.com/goplus/llgo/runtime/internal/runtime.iface" @reflect.TypeOf(%"github.com/goplus/llgo/runtime/internal/runtime.eface" %1) + %3 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.IfacePtrData"(%"github.com/goplus/llgo/runtime/internal/runtime.iface" %2) + %4 = extractvalue %"github.com/goplus/llgo/runtime/internal/runtime.iface" %2, 0 + %5 = getelementptr ptr, ptr %4, i64 23 + %6 = load ptr, ptr %5, align 8 + %7 = insertvalue { ptr, ptr } undef, ptr %6, 0 + %8 = insertvalue { ptr, ptr } %7, ptr %3, 1 + %9 = extractvalue { ptr, ptr } %8, 1 + %10 = extractvalue { ptr, ptr } %8, 0 + %11 = call %reflect.Method %10(ptr %9, i64 0) + ret void +} + +define void @"github.com/goplus/llgo/cl/_testgo/reflectmethod.typeByNameConst"() { +_llgo_0: + %0 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 0) + store %"github.com/goplus/llgo/cl/_testgo/reflectmethod.T" zeroinitializer, ptr %0, align 1 + %1 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" { ptr @"_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T", ptr undef }, ptr %0, 1 + %2 = call %"github.com/goplus/llgo/runtime/internal/runtime.iface" @reflect.TypeOf(%"github.com/goplus/llgo/runtime/internal/runtime.eface" %1) + %3 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.IfacePtrData"(%"github.com/goplus/llgo/runtime/internal/runtime.iface" %2) + %4 = extractvalue %"github.com/goplus/llgo/runtime/internal/runtime.iface" %2, 0 + %5 = getelementptr ptr, ptr %4, i64 24 + %6 = load ptr, ptr %5, align 8 + %7 = insertvalue { ptr, ptr } undef, ptr %6, 0 + %8 = insertvalue { ptr, ptr } %7, ptr %3, 1 + %9 = extractvalue { ptr, ptr } %8, 1 + %10 = extractvalue { ptr, ptr } %8, 0 + %11 = call { %reflect.Method, i1 } %10(ptr %9, %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @0, i64 1 }) + %12 = extractvalue { %reflect.Method, i1 } %11, 0 + %13 = extractvalue { %reflect.Method, i1 } %11, 1 + ret void +} + +define void @"github.com/goplus/llgo/cl/_testgo/reflectmethod.typeByNameDynamic"(%"github.com/goplus/llgo/runtime/internal/runtime.String" %0) { +_llgo_0: + %1 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64 0) + store %"github.com/goplus/llgo/cl/_testgo/reflectmethod.T" zeroinitializer, ptr %1, align 1 + %2 = insertvalue %"github.com/goplus/llgo/runtime/internal/runtime.eface" { ptr @"_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T", ptr undef }, ptr %1, 1 + %3 = call %"github.com/goplus/llgo/runtime/internal/runtime.iface" @reflect.TypeOf(%"github.com/goplus/llgo/runtime/internal/runtime.eface" %2) + %4 = call ptr @"github.com/goplus/llgo/runtime/internal/runtime.IfacePtrData"(%"github.com/goplus/llgo/runtime/internal/runtime.iface" %3) + %5 = extractvalue %"github.com/goplus/llgo/runtime/internal/runtime.iface" %3, 0 + %6 = getelementptr ptr, ptr %5, i64 24 + %7 = load ptr, ptr %6, align 8 + %8 = insertvalue { ptr, ptr } undef, ptr %7, 0 + %9 = insertvalue { ptr, ptr } %8, ptr %4, 1 + %10 = extractvalue { ptr, ptr } %9, 1 + %11 = extractvalue { ptr, ptr } %9, 0 + %12 = call { %reflect.Method, i1 } %11(ptr %10, %"github.com/goplus/llgo/runtime/internal/runtime.String" %0) + %13 = extractvalue { %reflect.Method, i1 } %12, 0 + %14 = extractvalue { %reflect.Method, i1 } %12, 1 + ret void +} + +define void @"github.com/goplus/llgo/cl/_testgo/reflectmethod.valueByIndex"(%"github.com/goplus/llgo/runtime/internal/runtime.eface" %0) { +_llgo_0: + %1 = call %reflect.Value @reflect.ValueOf(%"github.com/goplus/llgo/runtime/internal/runtime.eface" %0) + %2 = call %reflect.Value @reflect.Value.Method(%reflect.Value %1, i64 0) + ret void +} + +define void @"github.com/goplus/llgo/cl/_testgo/reflectmethod.valueByNameConst"(%"github.com/goplus/llgo/runtime/internal/runtime.eface" %0) { +_llgo_0: + %1 = call %reflect.Value @reflect.ValueOf(%"github.com/goplus/llgo/runtime/internal/runtime.eface" %0) + %2 = call %reflect.Value @reflect.Value.MethodByName(%reflect.Value %1, %"github.com/goplus/llgo/runtime/internal/runtime.String" { ptr @0, i64 1 }) + ret void +} + +define void @"github.com/goplus/llgo/cl/_testgo/reflectmethod.valueByNameDynamic"(%"github.com/goplus/llgo/runtime/internal/runtime.eface" %0, %"github.com/goplus/llgo/runtime/internal/runtime.String" %1) { +_llgo_0: + %2 = call %reflect.Value @reflect.ValueOf(%"github.com/goplus/llgo/runtime/internal/runtime.eface" %0) + %3 = call %reflect.Value @reflect.Value.MethodByName(%reflect.Value %2, %"github.com/goplus/llgo/runtime/internal/runtime.String" %1) + ret void +} + +declare void @reflect.init() + +declare i1 @"github.com/goplus/llgo/runtime/internal/runtime.memequal0"(ptr, ptr) + +define linkonce i1 @"__llgo_stub.github.com/goplus/llgo/runtime/internal/runtime.memequal0"(ptr %0, ptr %1, ptr %2) { +_llgo_0: + %3 = tail call i1 @"github.com/goplus/llgo/runtime/internal/runtime.memequal0"(ptr %1, ptr %2) + ret i1 %3 +} + +declare i1 @"github.com/goplus/llgo/runtime/internal/runtime.memequalptr"(ptr, ptr) + +define linkonce i1 @"__llgo_stub.github.com/goplus/llgo/runtime/internal/runtime.memequalptr"(ptr %0, ptr %1, ptr %2) { +_llgo_0: + %3 = tail call i1 @"github.com/goplus/llgo/runtime/internal/runtime.memequalptr"(ptr %1, ptr %2) + ret i1 %3 +} + +declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64) + +declare %"github.com/goplus/llgo/runtime/internal/runtime.iface" @reflect.TypeOf(%"github.com/goplus/llgo/runtime/internal/runtime.eface") + +declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.IfacePtrData"(%"github.com/goplus/llgo/runtime/internal/runtime.iface") + +declare %reflect.Value @reflect.ValueOf(%"github.com/goplus/llgo/runtime/internal/runtime.eface") + +declare %reflect.Value @reflect.Value.Method(%reflect.Value, i64) + +declare %reflect.Value @reflect.Value.MethodByName(%reflect.Value, %"github.com/goplus/llgo/runtime/internal/runtime.String") + +!llgo.useiface = !{!0, !1, !2, !3} +!llgo.methodoff = !{!4, !5} +!llgo.reflectmethod = !{!6, !7, !8, !9} +!llgo.useifacemethod = !{!10, !11, !12} +!llgo.usenamedmethod = !{!13, !14} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmethod.main", !"_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T"} +!1 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmethod.typeByIndex", !"_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T"} +!2 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmethod.typeByNameConst", !"_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T"} +!3 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmethod.typeByNameDynamic", !"_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T"} +!4 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T", i32 0, !"M", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!5 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T", i32 0, !"M", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!6 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmethod.typeByIndex"} +!7 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmethod.typeByNameDynamic"} +!8 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmethod.valueByIndex"} +!9 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmethod.valueByNameDynamic"} +!10 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmethod.typeByIndex", !"_llgo_reflect.Type", !"Method", !"_llgo_func$FmJJGomlX5kINJGxQdQDCAkD89ySoMslAYFrziWInVc"} +!11 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmethod.typeByNameConst", !"_llgo_reflect.Type", !"MethodByName", !"_llgo_func$aM2cVUtLQbPq1YHtnabQiM7XJ5Cg5RyV6BIDWrqey7E"} +!12 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmethod.typeByNameDynamic", !"_llgo_reflect.Type", !"MethodByName", !"_llgo_func$aM2cVUtLQbPq1YHtnabQiM7XJ5Cg5RyV6BIDWrqey7E"} +!13 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmethod.typeByNameConst", !"M"} +!14 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmethod.valueByNameConst", !"M"} diff --git a/cl/_testgo/reflectmk/out.ll b/cl/_testgo/reflectmk/out.ll index 2fdb2b897e..0d8892f530 100644 --- a/cl/_testgo/reflectmk/out.ll +++ b/cl/_testgo/reflectmk/out.ll @@ -655,3 +655,31 @@ declare %"github.com/goplus/llgo/runtime/internal/runtime.String" @reflect.Value declare %reflect.Value @reflect.Value.MethodByName(%reflect.Value, %"github.com/goplus/llgo/runtime/internal/runtime.String") attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useiface = !{!0, !1, !2, !3, !4, !5, !6} +!llgo.methodoff = !{!7, !8, !9} +!llgo.useifacemethod = !{!10, !11, !12, !13, !14, !15, !16} +!llgo.reflectmethod = !{!17, !18, !19} +!llgo.usenamedmethod = !{!20} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmk.Point.String", !"_llgo_int"} +!1 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmk.main", !"*_llgo_github.com/goplus/llgo/cl/_testgo/reflectmk.Point"} +!2 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmk.main", !"_llgo_string"} +!3 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmk.method", !"*_llgo_github.com/goplus/llgo/cl/_testgo/reflectmk.Point"} +!4 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmk.method", !"_llgo_string"} +!5 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmk.methodByName", !"*_llgo_github.com/goplus/llgo/cl/_testgo/reflectmk.Point"} +!6 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmk.methodByName", !"_llgo_string"} +!7 = !{!"_llgo_github.com/goplus/llgo/cl/_testgo/reflectmk.Point", i32 0, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!8 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reflectmk.Point", i32 0, !"Set", !"_llgo_func$1H6zMZ_cfMoleeOtJ_eCCBwy0eczea5_BZyjKcZr1wQ"} +!9 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/reflectmk.Point", i32 1, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!10 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmk.main", !"_llgo_reflect.Type", !"Elem", !"_llgo_func$b6KOG2Oj7wt8ogb9H8QPbhEfXhxMMjdxRZgPLK_UOwI"} +!11 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmk.main", !"_llgo_reflect.Type", !"In", !"_llgo_func$dPYu3A0LoGTV2Hd8PW4KPw2ITiUSo9q-4Bg9ZrPITnY"} +!12 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmk.main", !"_llgo_reflect.Type", !"Out", !"_llgo_func$dPYu3A0LoGTV2Hd8PW4KPw2ITiUSo9q-4Bg9ZrPITnY"} +!13 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmk.main", !"_llgo_reflect.Type", !"Key", !"_llgo_func$b6KOG2Oj7wt8ogb9H8QPbhEfXhxMMjdxRZgPLK_UOwI"} +!14 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmk.main", !"_llgo_reflect.Type", !"Field", !"_llgo_func$Q3NYrysaKgu1MtMuLQwb-k5QcKGHihnt-tV_NlNJQFA"} +!15 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmk.main", !"_llgo_reflect.Type", !"Method", !"_llgo_func$FmJJGomlX5kINJGxQdQDCAkD89ySoMslAYFrziWInVc"} +!16 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmk.main", !"_llgo_reflect.Type", !"MethodByName", !"_llgo_func$aM2cVUtLQbPq1YHtnabQiM7XJ5Cg5RyV6BIDWrqey7E"} +!17 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmk.main"} +!18 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmk.method"} +!19 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmk.methodByName"} +!20 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmk.main", !"String"} diff --git a/cl/_testgo/reflectmkfn/out.ll b/cl/_testgo/reflectmkfn/out.ll index b620b7806d..a1317c51b5 100644 --- a/cl/_testgo/reflectmkfn/out.ll +++ b/cl/_testgo/reflectmkfn/out.ll @@ -204,3 +204,9 @@ declare i64 @reflect.Value.Int(%reflect.Value) declare %"github.com/goplus/llgo/runtime/internal/runtime.String" @strings.Repeat(%"github.com/goplus/llgo/runtime/internal/runtime.String", i64) declare %reflect.Value @reflect.ValueOf(%"github.com/goplus/llgo/runtime/internal/runtime.eface") + +!llgo.useiface = !{!0, !1, !2} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmkfn.main", !"_llgo_string"} +!1 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmkfn.main", !"_llgo_int"} +!2 = !{!"github.com/goplus/llgo/cl/_testgo/reflectmkfn.main$1", !"_llgo_string"} diff --git a/cl/_testgo/returnorder/out.ll b/cl/_testgo/returnorder/out.ll index 07635e5ad9..0bf9b508fe 100644 --- a/cl/_testgo/returnorder/out.ll +++ b/cl/_testgo/returnorder/out.ll @@ -140,3 +140,8 @@ declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintString"(%"gi declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintByte"(i8) attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useiface = !{!0, !1} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/returnorder.main", !"_llgo_int"} +!1 = !{!"github.com/goplus/llgo/cl/_testgo/returnorder.main", !"_llgo_string"} diff --git a/cl/_testgo/selects/out.ll b/cl/_testgo/selects/out.ll index fd4c4b5786..0a371a0b13 100644 --- a/cl/_testgo/selects/out.ll +++ b/cl/_testgo/selects/out.ll @@ -254,3 +254,8 @@ declare void @"github.com/goplus/llgo/runtime/internal/runtime.Panic"(%"github.c declare i1 @"github.com/goplus/llgo/runtime/internal/runtime.ChanRecv"(ptr, ptr, i64) attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useiface = !{!0, !1} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/selects.main", !"_llgo_string"} +!1 = !{!"github.com/goplus/llgo/cl/_testgo/selects.main$1", !"_llgo_string"} diff --git a/cl/_testgo/strucintf/out.ll b/cl/_testgo/strucintf/out.ll index a17d12f06d..088f304fd9 100644 --- a/cl/_testgo/strucintf/out.ll +++ b/cl/_testgo/strucintf/out.ll @@ -208,3 +208,7 @@ declare %"github.com/goplus/llgo/runtime/internal/runtime.eface" @"github.com/go declare %"github.com/goplus/llgo/runtime/internal/runtime.eface" @"github.com/goplus/llgo/cl/_testdata/foo.F"() attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useiface = !{!0} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/strucintf.Foo", !"github.com/goplus/llgo/cl/_testgo/strucintf.struct$MYpsoM99ZwFY087IpUOkIw1zjBA_sgFXVodmn1m-G88"} diff --git a/cl/_testgo/struczero/out.ll b/cl/_testgo/struczero/out.ll index 758d2535de..f91daba37c 100644 --- a/cl/_testgo/struczero/out.ll +++ b/cl/_testgo/struczero/out.ll @@ -198,3 +198,10 @@ declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintBool"(i1) declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64) attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.methodoff = !{!0, !1} +!llgo.useiface = !{!2} + +!0 = !{!"*_llgo_github.com/goplus/llgo/cl/_testdata/foo.Foo", i32 0, !"Pb", !"_llgo_func$bbS9EKnYgxbrRntc_6WJN6WLF9IKQADblvN_cLtKCqY"} +!1 = !{!"_llgo_github.com/goplus/llgo/cl/_testdata/foo.Foo", i32 0, !"Pb", !"_llgo_func$bbS9EKnYgxbrRntc_6WJN6WLF9IKQADblvN_cLtKCqY"} +!2 = !{!"github.com/goplus/llgo/cl/_testgo/struczero.main", !"_llgo_github.com/goplus/llgo/cl/_testdata/foo.Foo"} diff --git a/cl/_testgo/tpinst/out.ll b/cl/_testgo/tpinst/out.ll index 8918c8a929..17ac7f7662 100644 --- a/cl/_testgo/tpinst/out.ll +++ b/cl/_testgo/tpinst/out.ll @@ -258,3 +258,18 @@ _llgo_0: declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.IfaceType"(%"github.com/goplus/llgo/runtime/internal/runtime.iface") declare i1 @"github.com/goplus/llgo/runtime/internal/runtime.Implements"(ptr, ptr) + +!llgo.useiface = !{!0, !1, !2} +!llgo.methodoff = !{!3, !4, !5, !6} +!llgo.useifacemethod = !{!7, !8, !9} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/tpinst.demo", !"*_llgo_github.com/goplus/llgo/cl/_testgo/tpinst.M[int]"} +!1 = !{!"github.com/goplus/llgo/cl/_testgo/tpinst.demo", !"_llgo_string"} +!2 = !{!"github.com/goplus/llgo/cl/_testgo/tpinst.demo", !"*_llgo_github.com/goplus/llgo/cl/_testgo/tpinst.M[float64]"} +!3 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/tpinst.M[int]", i32 0, !"Value", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!4 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/tpinst.M[int]", i32 1, !"github.com/goplus/llgo/cl/_testgo/tpinst.value", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!5 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/tpinst.M[float64]", i32 0, !"Value", !"_llgo_func$UYiLlmcWxoOKZPPzvR4LByitNeKoVGoTrB_5ubdOWW8"} +!6 = !{!"*_llgo_github.com/goplus/llgo/cl/_testgo/tpinst.M[float64]", i32 1, !"github.com/goplus/llgo/cl/_testgo/tpinst.value", !"_llgo_func$UYiLlmcWxoOKZPPzvR4LByitNeKoVGoTrB_5ubdOWW8"} +!7 = !{!"github.com/goplus/llgo/cl/_testgo/tpinst.demo", !"_llgo_github.com/goplus/llgo/cl/_testgo/tpinst.I[int]", !"Value", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!8 = !{!"github.com/goplus/llgo/cl/_testgo/tpinst.demo", !"_llgo_github.com/goplus/llgo/cl/_testgo/tpinst.I[float64]", !"Value", !"_llgo_func$UYiLlmcWxoOKZPPzvR4LByitNeKoVGoTrB_5ubdOWW8"} +!9 = !{!"github.com/goplus/llgo/cl/_testgo/tpinst.demo", !"github.com/goplus/llgo/cl/_testgo/tpinst.iface$2sV9fFeqOv1SzesvwIdhTqCFzDT8ZX5buKUSAoHNSww", !"github.com/goplus/llgo/cl/_testgo/tpinst.value", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} diff --git a/cl/_testgo/tprecur/out.ll b/cl/_testgo/tprecur/out.ll index 29a138e87e..8864d275bf 100644 --- a/cl/_testgo/tprecur/out.ll +++ b/cl/_testgo/tprecur/out.ll @@ -145,3 +145,7 @@ _llgo_6: ; preds = %_llgo_4 declare %"github.com/goplus/llgo/runtime/internal/runtime.Slice" @"github.com/goplus/llgo/runtime/internal/runtime.MakeSlice"(i64, i64, i64) declare void @"github.com/goplus/llgo/runtime/internal/runtime.AssertIndexRange"(i1) + +!llgo.useiface = !{!0} + +!0 = !{!"github.com/goplus/llgo/cl/_testgo/tprecur.recursive", !"_llgo_string"} diff --git a/cl/_testrt/abinamed/out.ll b/cl/_testrt/abinamed/out.ll index 115b6a54ac..8183936fec 100644 --- a/cl/_testrt/abinamed/out.ll +++ b/cl/_testrt/abinamed/out.ll @@ -876,3 +876,168 @@ declare void @"github.com/goplus/llgo/runtime/internal/runtime.Panic"(%"github.c declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocZ"(i64) attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useiface = !{!0, !1, !2} +!llgo.methodoff = !{!3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43, !44, !45, !46, !47, !48, !49, !50, !51, !52, !53, !54, !55, !56, !57, !58, !59, !60, !61, !62, !63, !64, !65, !66, !67, !68, !69, !70, !71, !72, !73, !74, !75, !76, !77, !78, !79, !80, !81, !82, !83, !84, !85, !86, !87, !88, !89, !90, !91, !92, !93, !94, !95, !96, !97, !98, !99, !100, !101, !102, !103, !104, !105, !106, !107, !108, !109, !110, !111, !112, !113, !114, !115, !116, !117, !118, !119, !120, !121, !122, !123, !124, !125, !126, !127, !128, !129, !130, !131, !132, !133, !134, !135, !136, !137, !138, !139, !140, !141, !142, !143, !144, !145, !146, !147, !148, !149, !150, !151, !152, !153, !154, !155, !156, !157, !158, !159, !160} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/abinamed.main", !"_llgo_github.com/goplus/llgo/cl/_testrt/abinamed.T"} +!1 = !{!"github.com/goplus/llgo/cl/_testrt/abinamed.main", !"_llgo_github.com/goplus/llgo/runtime/abi.Type"} +!2 = !{!"github.com/goplus/llgo/cl/_testrt/abinamed.main", !"_llgo_string"} +!3 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 0, !"Align", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!4 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 0, !"Align", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!5 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 1, !"ArrayType", !"_llgo_func$E73lcQT8QN1_ra27XNBjrI9wUEDUjSPMu2bmnQKIbfk"} +!6 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 2, !"ChanDir", !"_llgo_func$Qwe8YykhcqDIDEcT1jS_t1iUv4Im6IdGf17ASgXRQdc"} +!7 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 3, !"Common", !"_llgo_func$w6XuV-1SmW103DbauPseXBpW50HpxXAEsUsGFibl0Uw"} +!8 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Method", i32 0, !"Exported", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!9 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Method", i32 1, !"Name", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!10 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Method", i32 2, !"PkgPath", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!11 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 0, !"Align", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!12 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 1, !"ArrayType", !"_llgo_func$E73lcQT8QN1_ra27XNBjrI9wUEDUjSPMu2bmnQKIbfk"} +!13 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 2, !"ChanDir", !"_llgo_func$Qwe8YykhcqDIDEcT1jS_t1iUv4Im6IdGf17ASgXRQdc"} +!14 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 3, !"Common", !"_llgo_func$w6XuV-1SmW103DbauPseXBpW50HpxXAEsUsGFibl0Uw"} +!15 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 4, !"Elem", !"_llgo_func$w6XuV-1SmW103DbauPseXBpW50HpxXAEsUsGFibl0Uw"} +!16 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 5, !"ExportedMethods", !"_llgo_func$fPOUeAcTITSSbJEvFFjAWZP6Eli7dk4j7E9mFFHRoNM"} +!17 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 6, !"FieldAlign", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!18 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 7, !"FuncType", !"_llgo_func$Jm50llMLYG9ysTYiSohNC-Ho1mhjzn-vnTRBILhJI88"} +!19 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 8, !"GcSlice", !"_llgo_func$LzCekhEgu6zUWu4l1EXz60BKkQEwZP0N14TLH8aZW6Q"} +!20 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 9, !"HasName", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!21 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 10, !"IfaceIndir", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!22 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Imethod", i32 0, !"Exported", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!23 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Imethod", i32 1, !"Name", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!24 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Imethod", i32 2, !"PkgPath", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!25 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 0, !"Align", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!26 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 1, !"ArrayType", !"_llgo_func$E73lcQT8QN1_ra27XNBjrI9wUEDUjSPMu2bmnQKIbfk"} +!27 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 2, !"ChanDir", !"_llgo_func$Qwe8YykhcqDIDEcT1jS_t1iUv4Im6IdGf17ASgXRQdc"} +!28 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 3, !"Common", !"_llgo_func$w6XuV-1SmW103DbauPseXBpW50HpxXAEsUsGFibl0Uw"} +!29 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 4, !"Elem", !"_llgo_func$w6XuV-1SmW103DbauPseXBpW50HpxXAEsUsGFibl0Uw"} +!30 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 5, !"ExportedMethods", !"_llgo_func$fPOUeAcTITSSbJEvFFjAWZP6Eli7dk4j7E9mFFHRoNM"} +!31 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 6, !"FieldAlign", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!32 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 7, !"FuncType", !"_llgo_func$Jm50llMLYG9ysTYiSohNC-Ho1mhjzn-vnTRBILhJI88"} +!33 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 8, !"GcSlice", !"_llgo_func$LzCekhEgu6zUWu4l1EXz60BKkQEwZP0N14TLH8aZW6Q"} +!34 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 9, !"HasName", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!35 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 10, !"IfaceIndir", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!36 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 11, !"InterfaceType", !"_llgo_func$gPJieW0gawapuP7u0nJWjqAizA6ianfpIMmF5SojVDM"} +!37 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 12, !"IsClosure", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!38 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 13, !"IsDirectIface", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!39 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 14, !"Key", !"_llgo_func$w6XuV-1SmW103DbauPseXBpW50HpxXAEsUsGFibl0Uw"} +!40 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Kind", i32 0, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!41 = !{!"_llgo_github.com/goplus/llgo/runtime/abi.Kind", i32 0, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!42 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 15, !"Kind", !"_llgo_func$Hsg8cfKiWmyMHfTCLbUouCMFmF6kp9x3qasAGPBLLfc"} +!43 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 16, !"Len", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!44 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 0, !"Align", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!45 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 1, !"ArrayType", !"_llgo_func$E73lcQT8QN1_ra27XNBjrI9wUEDUjSPMu2bmnQKIbfk"} +!46 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 2, !"ChanDir", !"_llgo_func$Qwe8YykhcqDIDEcT1jS_t1iUv4Im6IdGf17ASgXRQdc"} +!47 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 3, !"Common", !"_llgo_func$w6XuV-1SmW103DbauPseXBpW50HpxXAEsUsGFibl0Uw"} +!48 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 4, !"ExportedMethods", !"_llgo_func$fPOUeAcTITSSbJEvFFjAWZP6Eli7dk4j7E9mFFHRoNM"} +!49 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 5, !"FieldAlign", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!50 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 6, !"FuncType", !"_llgo_func$Jm50llMLYG9ysTYiSohNC-Ho1mhjzn-vnTRBILhJI88"} +!51 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 7, !"GcSlice", !"_llgo_func$LzCekhEgu6zUWu4l1EXz60BKkQEwZP0N14TLH8aZW6Q"} +!52 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 8, !"HasName", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!53 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 9, !"HashMightPanic", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!54 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 10, !"IfaceIndir", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!55 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 11, !"IndirectElem", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!56 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 12, !"IndirectKey", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!57 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 13, !"InterfaceType", !"_llgo_func$gPJieW0gawapuP7u0nJWjqAizA6ianfpIMmF5SojVDM"} +!58 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 14, !"IsClosure", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!59 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 15, !"IsDirectIface", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!60 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 16, !"Kind", !"_llgo_func$Hsg8cfKiWmyMHfTCLbUouCMFmF6kp9x3qasAGPBLLfc"} +!61 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 17, !"Len", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!62 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 18, !"MapType", !"_llgo_func$v23QoXYwI62Le4EtGc42fZr4iF7nBhA8A8t9lvpy0QY"} +!63 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 19, !"NeedKeyUpdate", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!64 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 20, !"NumMethod", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!65 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 21, !"Pointers", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!66 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 22, !"ReflexiveKey", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!67 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 23, !"Size", !"_llgo_func$1kITCsyu7hFLMxHLR7kDlvu4SOra_HtrtdFUQH9P13s"} +!68 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 24, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!69 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructField", i32 0, !"Embedded", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!70 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructField", i32 1, !"Exported", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!71 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 0, !"Align", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!72 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 1, !"ArrayType", !"_llgo_func$E73lcQT8QN1_ra27XNBjrI9wUEDUjSPMu2bmnQKIbfk"} +!73 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 2, !"ChanDir", !"_llgo_func$Qwe8YykhcqDIDEcT1jS_t1iUv4Im6IdGf17ASgXRQdc"} +!74 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 3, !"Common", !"_llgo_func$w6XuV-1SmW103DbauPseXBpW50HpxXAEsUsGFibl0Uw"} +!75 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 4, !"Elem", !"_llgo_func$w6XuV-1SmW103DbauPseXBpW50HpxXAEsUsGFibl0Uw"} +!76 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 5, !"ExportedMethods", !"_llgo_func$fPOUeAcTITSSbJEvFFjAWZP6Eli7dk4j7E9mFFHRoNM"} +!77 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 6, !"FieldAlign", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!78 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 7, !"FuncType", !"_llgo_func$Jm50llMLYG9ysTYiSohNC-Ho1mhjzn-vnTRBILhJI88"} +!79 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 8, !"GcSlice", !"_llgo_func$LzCekhEgu6zUWu4l1EXz60BKkQEwZP0N14TLH8aZW6Q"} +!80 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 9, !"HasName", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!81 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 10, !"IfaceIndir", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!82 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 11, !"InterfaceType", !"_llgo_func$gPJieW0gawapuP7u0nJWjqAizA6ianfpIMmF5SojVDM"} +!83 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 12, !"IsClosure", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!84 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 13, !"IsDirectIface", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!85 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 14, !"Key", !"_llgo_func$w6XuV-1SmW103DbauPseXBpW50HpxXAEsUsGFibl0Uw"} +!86 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 15, !"Kind", !"_llgo_func$Hsg8cfKiWmyMHfTCLbUouCMFmF6kp9x3qasAGPBLLfc"} +!87 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 16, !"Len", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!88 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 17, !"MapType", !"_llgo_func$v23QoXYwI62Le4EtGc42fZr4iF7nBhA8A8t9lvpy0QY"} +!89 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 18, !"NumMethod", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!90 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 19, !"Pointers", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!91 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 20, !"Size", !"_llgo_func$1kITCsyu7hFLMxHLR7kDlvu4SOra_HtrtdFUQH9P13s"} +!92 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 21, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!93 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 22, !"StructType", !"_llgo_func$JNZyRh9Ldf2v-LKH-spUrxoORHTTH5NO358kWdhabp0"} +!94 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.UncommonType", i32 0, !"ExportedMethods", !"_llgo_func$fPOUeAcTITSSbJEvFFjAWZP6Eli7dk4j7E9mFFHRoNM"} +!95 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.UncommonType", i32 1, !"Methods", !"_llgo_func$fPOUeAcTITSSbJEvFFjAWZP6Eli7dk4j7E9mFFHRoNM"} +!96 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.StructType", i32 23, !"Uncommon", !"_llgo_func$iG49bujiXjI2lVflYdE0hPXlCAABL-XKRANSNJEKOio"} +!97 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 25, !"StructType", !"_llgo_func$JNZyRh9Ldf2v-LKH-spUrxoORHTTH5NO358kWdhabp0"} +!98 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.MapType", i32 26, !"Uncommon", !"_llgo_func$iG49bujiXjI2lVflYdE0hPXlCAABL-XKRANSNJEKOio"} +!99 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 17, !"MapType", !"_llgo_func$v23QoXYwI62Le4EtGc42fZr4iF7nBhA8A8t9lvpy0QY"} +!100 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 18, !"NumMethod", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!101 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 19, !"Pointers", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!102 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 20, !"Size", !"_llgo_func$1kITCsyu7hFLMxHLR7kDlvu4SOra_HtrtdFUQH9P13s"} +!103 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 21, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!104 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 22, !"StructType", !"_llgo_func$JNZyRh9Ldf2v-LKH-spUrxoORHTTH5NO358kWdhabp0"} +!105 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.InterfaceType", i32 23, !"Uncommon", !"_llgo_func$iG49bujiXjI2lVflYdE0hPXlCAABL-XKRANSNJEKOio"} +!106 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 11, !"InterfaceType", !"_llgo_func$gPJieW0gawapuP7u0nJWjqAizA6ianfpIMmF5SojVDM"} +!107 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 12, !"IsClosure", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!108 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 13, !"IsDirectIface", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!109 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 14, !"Key", !"_llgo_func$w6XuV-1SmW103DbauPseXBpW50HpxXAEsUsGFibl0Uw"} +!110 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 15, !"Kind", !"_llgo_func$Hsg8cfKiWmyMHfTCLbUouCMFmF6kp9x3qasAGPBLLfc"} +!111 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 16, !"Len", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!112 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 17, !"MapType", !"_llgo_func$v23QoXYwI62Le4EtGc42fZr4iF7nBhA8A8t9lvpy0QY"} +!113 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 18, !"NumMethod", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!114 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 19, !"Pointers", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!115 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 20, !"Size", !"_llgo_func$1kITCsyu7hFLMxHLR7kDlvu4SOra_HtrtdFUQH9P13s"} +!116 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 21, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!117 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 22, !"StructType", !"_llgo_func$JNZyRh9Ldf2v-LKH-spUrxoORHTTH5NO358kWdhabp0"} +!118 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 23, !"Uncommon", !"_llgo_func$iG49bujiXjI2lVflYdE0hPXlCAABL-XKRANSNJEKOio"} +!119 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.FuncType", i32 24, !"Variadic", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!120 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 4, !"ExportedMethods", !"_llgo_func$fPOUeAcTITSSbJEvFFjAWZP6Eli7dk4j7E9mFFHRoNM"} +!121 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 5, !"FieldAlign", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!122 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 6, !"FuncType", !"_llgo_func$Jm50llMLYG9ysTYiSohNC-Ho1mhjzn-vnTRBILhJI88"} +!123 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 7, !"GcSlice", !"_llgo_func$LzCekhEgu6zUWu4l1EXz60BKkQEwZP0N14TLH8aZW6Q"} +!124 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 8, !"HasName", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!125 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 9, !"IfaceIndir", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!126 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 10, !"InterfaceType", !"_llgo_func$gPJieW0gawapuP7u0nJWjqAizA6ianfpIMmF5SojVDM"} +!127 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 11, !"IsClosure", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!128 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 12, !"IsDirectIface", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!129 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 13, !"Key", !"_llgo_func$w6XuV-1SmW103DbauPseXBpW50HpxXAEsUsGFibl0Uw"} +!130 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 14, !"Kind", !"_llgo_func$Hsg8cfKiWmyMHfTCLbUouCMFmF6kp9x3qasAGPBLLfc"} +!131 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 15, !"MapType", !"_llgo_func$v23QoXYwI62Le4EtGc42fZr4iF7nBhA8A8t9lvpy0QY"} +!132 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 16, !"NumMethod", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!133 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 17, !"Pointers", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!134 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 18, !"Size", !"_llgo_func$1kITCsyu7hFLMxHLR7kDlvu4SOra_HtrtdFUQH9P13s"} +!135 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 19, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!136 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 20, !"StructType", !"_llgo_func$JNZyRh9Ldf2v-LKH-spUrxoORHTTH5NO358kWdhabp0"} +!137 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.ArrayType", i32 21, !"Uncommon", !"_llgo_func$iG49bujiXjI2lVflYdE0hPXlCAABL-XKRANSNJEKOio"} +!138 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 1, !"ArrayType", !"_llgo_func$E73lcQT8QN1_ra27XNBjrI9wUEDUjSPMu2bmnQKIbfk"} +!139 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 2, !"ChanDir", !"_llgo_func$Qwe8YykhcqDIDEcT1jS_t1iUv4Im6IdGf17ASgXRQdc"} +!140 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 3, !"Common", !"_llgo_func$w6XuV-1SmW103DbauPseXBpW50HpxXAEsUsGFibl0Uw"} +!141 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 4, !"Elem", !"_llgo_func$w6XuV-1SmW103DbauPseXBpW50HpxXAEsUsGFibl0Uw"} +!142 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 5, !"ExportedMethods", !"_llgo_func$fPOUeAcTITSSbJEvFFjAWZP6Eli7dk4j7E9mFFHRoNM"} +!143 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 6, !"FieldAlign", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!144 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 7, !"FuncType", !"_llgo_func$Jm50llMLYG9ysTYiSohNC-Ho1mhjzn-vnTRBILhJI88"} +!145 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 8, !"GcSlice", !"_llgo_func$LzCekhEgu6zUWu4l1EXz60BKkQEwZP0N14TLH8aZW6Q"} +!146 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 9, !"HasName", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!147 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 10, !"IfaceIndir", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!148 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 11, !"InterfaceType", !"_llgo_func$gPJieW0gawapuP7u0nJWjqAizA6ianfpIMmF5SojVDM"} +!149 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 12, !"IsClosure", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!150 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 13, !"IsDirectIface", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!151 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 14, !"Key", !"_llgo_func$w6XuV-1SmW103DbauPseXBpW50HpxXAEsUsGFibl0Uw"} +!152 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 15, !"Kind", !"_llgo_func$Hsg8cfKiWmyMHfTCLbUouCMFmF6kp9x3qasAGPBLLfc"} +!153 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 16, !"Len", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!154 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 17, !"MapType", !"_llgo_func$v23QoXYwI62Le4EtGc42fZr4iF7nBhA8A8t9lvpy0QY"} +!155 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 18, !"NumMethod", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} +!156 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 19, !"Pointers", !"_llgo_func$YHeRw3AOvQtzv982-ZO3Yn8vh3Fx89RM3VvI8E4iKVk"} +!157 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 20, !"Size", !"_llgo_func$1kITCsyu7hFLMxHLR7kDlvu4SOra_HtrtdFUQH9P13s"} +!158 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 21, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!159 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 22, !"StructType", !"_llgo_func$JNZyRh9Ldf2v-LKH-spUrxoORHTTH5NO358kWdhabp0"} +!160 = !{!"*_llgo_github.com/goplus/llgo/runtime/abi.Type", i32 23, !"Uncommon", !"_llgo_func$iG49bujiXjI2lVflYdE0hPXlCAABL-XKRANSNJEKOio"} diff --git a/cl/_testrt/abitype/out.ll b/cl/_testrt/abitype/out.ll index 4387799496..ffeb3b7191 100644 --- a/cl/_testrt/abitype/out.ll +++ b/cl/_testrt/abitype/out.ll @@ -115,3 +115,9 @@ _llgo_0: %3 = tail call i1 @"github.com/goplus/llgo/runtime/internal/runtime.memequal8"(ptr %1, ptr %2) ret i1 %3 } + +!llgo.useiface = !{!0, !1, !2} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/abitype.main", !"_llgo_int32"} +!1 = !{!"github.com/goplus/llgo/cl/_testrt/abitype.main", !"_llgo_string"} +!2 = !{!"github.com/goplus/llgo/cl/_testrt/abitype.main", !"_llgo_uint8"} diff --git a/cl/_testrt/any/out.ll b/cl/_testrt/any/out.ll index 3e9de5bb75..46cc5f89b7 100644 --- a/cl/_testrt/any/out.ll +++ b/cl/_testrt/any/out.ll @@ -117,3 +117,10 @@ _llgo_0: } declare i32 @printf(ptr, ...) + +!llgo.useiface = !{!0, !1, !2, !3} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/any.hi", !"_llgo_string"} +!1 = !{!"github.com/goplus/llgo/cl/_testrt/any.incVal", !"_llgo_string"} +!2 = !{!"github.com/goplus/llgo/cl/_testrt/any.main", !"*_llgo_int8"} +!3 = !{!"github.com/goplus/llgo/cl/_testrt/any.main", !"_llgo_int"} diff --git a/cl/_testrt/asmfull/out.ll b/cl/_testrt/asmfull/out.ll index 16f7f2b67c..3003033ff0 100644 --- a/cl/_testrt/asmfull/out.ll +++ b/cl/_testrt/asmfull/out.ll @@ -170,3 +170,7 @@ declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintString"(%"gi declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintByte"(i8) declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintUint"(i64) + +!llgo.useiface = !{!0} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/asmfull.main", !"_llgo_int"} diff --git a/cl/_testrt/builtin/out.ll b/cl/_testrt/builtin/out.ll index d8763d900e..3d87645d10 100644 --- a/cl/_testrt/builtin/out.ll +++ b/cl/_testrt/builtin/out.ll @@ -538,3 +538,7 @@ declare %"github.com/goplus/llgo/runtime/internal/runtime.String" @"github.com/g declare i1 @"github.com/goplus/llgo/runtime/internal/runtime.StringEqual"(%"github.com/goplus/llgo/runtime/internal/runtime.String", %"github.com/goplus/llgo/runtime/internal/runtime.String") declare i1 @"github.com/goplus/llgo/runtime/internal/runtime.StringLess"(%"github.com/goplus/llgo/runtime/internal/runtime.String", %"github.com/goplus/llgo/runtime/internal/runtime.String") + +!llgo.useiface = !{!0} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/builtin.main", !"_llgo_int"} diff --git a/cl/_testrt/cast/out.ll b/cl/_testrt/cast/out.ll index e11c754dfb..60a9a3a899 100644 --- a/cl/_testrt/cast/out.ll +++ b/cl/_testrt/cast/out.ll @@ -347,3 +347,19 @@ _llgo_0: declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64) declare void @"github.com/goplus/llgo/runtime/internal/runtime.Panic"(%"github.com/goplus/llgo/runtime/internal/runtime.eface") + +!llgo.useiface = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/cast.cvt32Fto32", !"_llgo_string"} +!1 = !{!"github.com/goplus/llgo/cl/_testrt/cast.cvt32Fto32U", !"_llgo_string"} +!2 = !{!"github.com/goplus/llgo/cl/_testrt/cast.cvt32Fto64F", !"_llgo_string"} +!3 = !{!"github.com/goplus/llgo/cl/_testrt/cast.cvt32Fto8", !"_llgo_string"} +!4 = !{!"github.com/goplus/llgo/cl/_testrt/cast.cvt32Fto8U", !"_llgo_string"} +!5 = !{!"github.com/goplus/llgo/cl/_testrt/cast.cvt32to64", !"_llgo_string"} +!6 = !{!"github.com/goplus/llgo/cl/_testrt/cast.cvt64Fto32F", !"_llgo_string"} +!7 = !{!"github.com/goplus/llgo/cl/_testrt/cast.cvt64Uto64F", !"_llgo_string"} +!8 = !{!"github.com/goplus/llgo/cl/_testrt/cast.cvt64to64F", !"_llgo_string"} +!9 = !{!"github.com/goplus/llgo/cl/_testrt/cast.cvt64to8", !"_llgo_string"} +!10 = !{!"github.com/goplus/llgo/cl/_testrt/cast.cvt64to8U", !"_llgo_string"} +!11 = !{!"github.com/goplus/llgo/cl/_testrt/cast.cvtFtoUintptr", !"_llgo_string"} +!12 = !{!"github.com/goplus/llgo/cl/_testrt/cast.cvtUinptr", !"_llgo_string"} diff --git a/cl/_testrt/closurebound/out.ll b/cl/_testrt/closurebound/out.ll index 2f5c3ccca1..f83ad0ad1e 100644 --- a/cl/_testrt/closurebound/out.ll +++ b/cl/_testrt/closurebound/out.ll @@ -115,3 +115,7 @@ _llgo_0: } declare void @"github.com/goplus/llgo/runtime/internal/runtime.Panic"(%"github.com/goplus/llgo/runtime/internal/runtime.eface") + +!llgo.useiface = !{!0} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/closurebound.main", !"_llgo_string"} diff --git a/cl/_testrt/closureiface/out.ll b/cl/_testrt/closureiface/out.ll index f72e4e6545..ae25889567 100644 --- a/cl/_testrt/closureiface/out.ll +++ b/cl/_testrt/closureiface/out.ll @@ -137,3 +137,8 @@ _llgo_0: } declare void @"github.com/goplus/llgo/runtime/internal/runtime.Panic"(%"github.com/goplus/llgo/runtime/internal/runtime.eface") + +!llgo.useiface = !{!0, !1} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/closureiface.main", !"_llgo_closure$QIHBTaw1IFobr8yvWpq-2AJFm3xBNhdW_aNBicqUBGk"} +!1 = !{!"github.com/goplus/llgo/cl/_testrt/closureiface.main", !"_llgo_string"} diff --git a/cl/_testrt/eface/out.ll b/cl/_testrt/eface/out.ll index c22f938e4a..9f010ab52f 100644 --- a/cl/_testrt/eface/out.ll +++ b/cl/_testrt/eface/out.ll @@ -372,3 +372,29 @@ _llgo_0: } declare i1 @"github.com/goplus/llgo/runtime/internal/runtime.structequal"(ptr, ptr, ptr) + +!llgo.useiface = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20} +!llgo.methodoff = !{!21} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"_llgo_bool"} +!1 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"_llgo_int"} +!2 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"_llgo_int8"} +!3 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"_llgo_int16"} +!4 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"_llgo_int32"} +!5 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"_llgo_int64"} +!6 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"_llgo_uint"} +!7 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"_llgo_uint8"} +!8 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"_llgo_uint16"} +!9 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"_llgo_uint32"} +!10 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"_llgo_uint64"} +!11 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"_llgo_uintptr"} +!12 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"_llgo_float32"} +!13 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"_llgo_float64"} +!14 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"[10]_llgo_int"} +!15 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"_llgo_closure$b7Su1hWaFih-M0M9hMk6nO_RD1K_GQu5WjIXQp6Q2e8"} +!16 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"*_llgo_int"} +!17 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"[]_llgo_int"} +!18 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"_llgo_string"} +!19 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"github.com/goplus/llgo/cl/_testrt/eface.struct$RKbUG45GE4henGMAdmt0Rju0JptyR8NsX7IZLsOI0OM"} +!20 = !{!"github.com/goplus/llgo/cl/_testrt/eface.main", !"_llgo_github.com/goplus/llgo/cl/_testrt/eface.T"} +!21 = !{!"*_llgo_github.com/goplus/llgo/cl/_testrt/eface.T", i32 0, !"Invoke", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} diff --git a/cl/_testrt/float2any/out.ll b/cl/_testrt/float2any/out.ll index bdb89f4039..b3f35e8d1f 100644 --- a/cl/_testrt/float2any/out.ll +++ b/cl/_testrt/float2any/out.ll @@ -157,3 +157,10 @@ _llgo_0: %3 = tail call i1 @"github.com/goplus/llgo/runtime/internal/runtime.f64equal"(ptr %1, ptr %2) ret i1 %3 } + +!llgo.useiface = !{!0, !1, !2, !3} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/float2any.check32", !"_llgo_string"} +!1 = !{!"github.com/goplus/llgo/cl/_testrt/float2any.check64", !"_llgo_string"} +!2 = !{!"github.com/goplus/llgo/cl/_testrt/float2any.main", !"_llgo_float32"} +!3 = !{!"github.com/goplus/llgo/cl/_testrt/float2any.main", !"_llgo_float64"} diff --git a/cl/_testrt/funcdecl/out.ll b/cl/_testrt/funcdecl/out.ll index f14070e0e8..7b4e584801 100644 --- a/cl/_testrt/funcdecl/out.ll +++ b/cl/_testrt/funcdecl/out.ll @@ -168,3 +168,8 @@ declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintBool"(i1) declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocZ"(i64) declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintString"(%"github.com/goplus/llgo/runtime/internal/runtime.String") + +!llgo.useiface = !{!0, !1} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/funcdecl.check", !"_llgo_closure$b7Su1hWaFih-M0M9hMk6nO_RD1K_GQu5WjIXQp6Q2e8"} +!1 = !{!"github.com/goplus/llgo/cl/_testrt/funcdecl.check", !"_llgo_string"} diff --git a/cl/_testrt/makemap/out.ll b/cl/_testrt/makemap/out.ll index 0478ede4eb..e8cde99e0a 100644 --- a/cl/_testrt/makemap/out.ll +++ b/cl/_testrt/makemap/out.ll @@ -950,3 +950,14 @@ declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocZ"(i64) declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.NewChan"(i64, i64) attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useiface = !{!0, !1, !2, !3, !4, !5, !6, !7} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/makemap.make1", !"_llgo_string"} +!1 = !{!"github.com/goplus/llgo/cl/_testrt/makemap.make2", !"_llgo_github.com/goplus/llgo/cl/_testrt/makemap.N1"} +!2 = !{!"github.com/goplus/llgo/cl/_testrt/makemap.make2", !"_llgo_string"} +!3 = !{!"github.com/goplus/llgo/cl/_testrt/makemap.make3", !"_llgo_github.com/goplus/llgo/cl/_testrt/makemap.K"} +!4 = !{!"github.com/goplus/llgo/cl/_testrt/makemap.make3", !"_llgo_string"} +!5 = !{!"github.com/goplus/llgo/cl/_testrt/makemap.make4", !"_llgo_github.com/goplus/llgo/cl/_testrt/makemap.K2"} +!6 = !{!"github.com/goplus/llgo/cl/_testrt/makemap.make4", !"_llgo_string"} +!7 = !{!"github.com/goplus/llgo/cl/_testrt/makemap.make5", !"chan _llgo_int"} diff --git a/cl/_testrt/mapclosure/out.ll b/cl/_testrt/mapclosure/out.ll index ecb0094a6b..8c3f207305 100644 --- a/cl/_testrt/mapclosure/out.ll +++ b/cl/_testrt/mapclosure/out.ll @@ -247,3 +247,12 @@ declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.NewItab"(ptr, ptr) declare i1 @"github.com/goplus/llgo/runtime/internal/runtime.StringEqual"(%"github.com/goplus/llgo/runtime/internal/runtime.String", %"github.com/goplus/llgo/runtime/internal/runtime.String") declare void @"github.com/goplus/llgo/runtime/internal/runtime.Panic"(%"github.com/goplus/llgo/runtime/internal/runtime.eface") + +!llgo.useifacemethod = !{!0} +!llgo.useiface = !{!1, !2} +!llgo.methodoff = !{!3} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/mapclosure.demo", !"_llgo_github.com/goplus/llgo/cl/_testrt/mapclosure.Type", !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} +!1 = !{!"github.com/goplus/llgo/cl/_testrt/mapclosure.main", !"*_llgo_github.com/goplus/llgo/cl/_testrt/mapclosure.typ"} +!2 = !{!"github.com/goplus/llgo/cl/_testrt/mapclosure.main", !"_llgo_string"} +!3 = !{!"*_llgo_github.com/goplus/llgo/cl/_testrt/mapclosure.typ", i32 0, !"String", !"_llgo_func$zNDVRsWTIpUPKouNUS805RGX--IV9qVK8B31IZbg5to"} diff --git a/cl/_testrt/methodthunk/out.ll b/cl/_testrt/methodthunk/out.ll index 03d85892cd..16272128ba 100644 --- a/cl/_testrt/methodthunk/out.ll +++ b/cl/_testrt/methodthunk/out.ll @@ -235,3 +235,13 @@ _llgo_0: } declare void @"github.com/goplus/llgo/runtime/internal/runtime.Panic"(%"github.com/goplus/llgo/runtime/internal/runtime.eface") + +!llgo.useiface = !{!0, !1, !2} +!llgo.methodoff = !{!3, !4, !5} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/methodthunk.main", !"_llgo_closure$31N-NdXOzvOy55m3NGAY_hdZ_NIdtCAe5V7uk7-a5HU"} +!1 = !{!"github.com/goplus/llgo/cl/_testrt/methodthunk.main", !"_llgo_closure$ygdobeQSbhO1hSbeWA66ORl_cNKHor-iD8MqRFtuWHg"} +!2 = !{!"github.com/goplus/llgo/cl/_testrt/methodthunk.main", !"_llgo_string"} +!3 = !{!"*_llgo_github.com/goplus/llgo/cl/_testrt/methodthunk.inner", i32 0, !"M", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!4 = !{!"*_llgo_github.com/goplus/llgo/cl/_testrt/methodthunk.outer", i32 0, !"M", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!5 = !{!"*_llgo_github.com/goplus/llgo/cl/_testrt/methodthunk.InnerInt", i32 0, !"M", !"_llgo_func$ETeB8WwW04JEq0ztcm-XPTJtuYvtpkjIsAc0-2NT9zA"} diff --git a/cl/_testrt/namedslice/out.ll b/cl/_testrt/namedslice/out.ll index 9a077471fd..e7c16d690e 100644 --- a/cl/_testrt/namedslice/out.ll +++ b/cl/_testrt/namedslice/out.ll @@ -105,3 +105,8 @@ _llgo_0: } declare void @"github.com/goplus/llgo/runtime/internal/runtime.Panic"(%"github.com/goplus/llgo/runtime/internal/runtime.eface") + +!llgo.useiface = !{!0, !1} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/namedslice.main", !"_llgo_github.com/goplus/llgo/cl/_testrt/namedslice.MyBytes"} +!1 = !{!"github.com/goplus/llgo/cl/_testrt/namedslice.main", !"_llgo_string"} diff --git a/cl/_testrt/panic/out.ll b/cl/_testrt/panic/out.ll index 8b6ef551e9..80613b79cc 100644 --- a/cl/_testrt/panic/out.ll +++ b/cl/_testrt/panic/out.ll @@ -53,3 +53,7 @@ _llgo_0: declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64) declare void @"github.com/goplus/llgo/runtime/internal/runtime.Panic"(%"github.com/goplus/llgo/runtime/internal/runtime.eface") + +!llgo.useiface = !{!0} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/panic.main", !"_llgo_string"} diff --git a/cl/_testrt/tpabi/out.ll b/cl/_testrt/tpabi/out.ll index 4b21f43520..15483cc31c 100644 --- a/cl/_testrt/tpabi/out.ll +++ b/cl/_testrt/tpabi/out.ll @@ -212,3 +212,15 @@ declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintPointer"(ptr declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintInt"(i64) attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useiface = !{!0, !1, !2} +!llgo.methodoff = !{!3, !4, !5} +!llgo.useifacemethod = !{!6} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/tpabi.main", !"_llgo_github.com/goplus/llgo/cl/_testrt/tpabi.T[string,int]"} +!1 = !{!"github.com/goplus/llgo/cl/_testrt/tpabi.main", !"_llgo_string"} +!2 = !{!"github.com/goplus/llgo/cl/_testrt/tpabi.main", !"*_llgo_github.com/goplus/llgo/cl/_testrt/tpabi.T[string,int]"} +!3 = !{!"*_llgo_github.com/goplus/llgo/cl/_testrt/tpabi.T[string,int]", i32 0, !"Demo", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!4 = !{!"*_llgo_github.com/goplus/llgo/cl/_testrt/tpabi.T[string,int]", i32 1, !"Info", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!5 = !{!"_llgo_github.com/goplus/llgo/cl/_testrt/tpabi.T[string,int]", i32 0, !"Info", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} +!6 = !{!"github.com/goplus/llgo/cl/_testrt/tpabi.main", !"_llgo_github.com/goplus/llgo/cl/_testrt/tpabi.I", !"Demo", !"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac"} diff --git a/cl/_testrt/tpmap/out.ll b/cl/_testrt/tpmap/out.ll index c1000c1607..5707242238 100644 --- a/cl/_testrt/tpmap/out.ll +++ b/cl/_testrt/tpmap/out.ll @@ -221,3 +221,7 @@ declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintByte"(i8) declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintBool"(i1) attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useiface = !{!0} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/tpmap.main", !"_llgo_int"} diff --git a/cl/_testrt/tpmethod/out.ll b/cl/_testrt/tpmethod/out.ll index dafa1b61c9..d88e4c7878 100644 --- a/cl/_testrt/tpmethod/out.ll +++ b/cl/_testrt/tpmethod/out.ll @@ -218,3 +218,13 @@ _llgo_0: declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.NewItab"(ptr, ptr) attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useifacemethod = !{!0} +!llgo.useiface = !{!1} +!llgo.methodoff = !{!2, !3, !4} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/tpmethod.main", !"_llgo_github.com/goplus/llgo/cl/_testrt/tpmethod.Future[github.com/goplus/llgo/cl/_testrt/tpmethod.Tuple[error]]", !"Then", !"_llgo_func$YDtAFTesCi1EpIfGs4nqPSJzLIDwkg-8FAbVKMCx8cg"} +!1 = !{!"github.com/goplus/llgo/cl/_testrt/tpmethod.Async[github.com/goplus/llgo/cl/_testrt/tpmethod.Tuple[error]]", !"*_llgo_github.com/goplus/llgo/cl/_testrt/tpmethod.future[github.com/goplus/llgo/cl/_testrt/tpmethod.Tuple[error]]"} +!2 = !{!"*_llgo_github.com/goplus/llgo/cl/_testrt/tpmethod.Tuple[error]", i32 0, !"Get", !"_llgo_func$8rsrSd_r3UHd_2DiYTyaOKR7BYkei4zw5ysG35KF38w"} +!3 = !{!"_llgo_github.com/goplus/llgo/cl/_testrt/tpmethod.Tuple[error]", i32 0, !"Get", !"_llgo_func$8rsrSd_r3UHd_2DiYTyaOKR7BYkei4zw5ysG35KF38w"} +!4 = !{!"*_llgo_github.com/goplus/llgo/cl/_testrt/tpmethod.future[github.com/goplus/llgo/cl/_testrt/tpmethod.Tuple[error]]", i32 0, !"Then", !"_llgo_func$YDtAFTesCi1EpIfGs4nqPSJzLIDwkg-8FAbVKMCx8cg"} diff --git a/cl/_testrt/tpunsafe/out.ll b/cl/_testrt/tpunsafe/out.ll index 8073bf6211..1cece0f248 100644 --- a/cl/_testrt/tpunsafe/out.ll +++ b/cl/_testrt/tpunsafe/out.ll @@ -208,3 +208,8 @@ _llgo_0: declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64) declare void @"github.com/goplus/llgo/runtime/internal/runtime.Panic"(%"github.com/goplus/llgo/runtime/internal/runtime.eface") + +!llgo.useiface = !{!0, !1} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/tpunsafe.(*M[bool]).check", !"_llgo_string"} +!1 = !{!"github.com/goplus/llgo/cl/_testrt/tpunsafe.(*M[int64]).check", !"_llgo_string"} diff --git a/cl/_testrt/typed/out.ll b/cl/_testrt/typed/out.ll index 02e99d3eb4..2db14d8a86 100644 --- a/cl/_testrt/typed/out.ll +++ b/cl/_testrt/typed/out.ll @@ -172,3 +172,9 @@ _llgo_0: declare void @"github.com/goplus/llgo/runtime/internal/runtime.PrintInt"(i64) attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useiface = !{!0, !1, !2} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/typed.main", !"_llgo_github.com/goplus/llgo/cl/_testrt/typed.T"} +!1 = !{!"github.com/goplus/llgo/cl/_testrt/typed.main", !"_llgo_string"} +!2 = !{!"github.com/goplus/llgo/cl/_testrt/typed.main", !"_llgo_github.com/goplus/llgo/cl/_testrt/typed.A"} diff --git a/cl/_testrt/unsafe/out.ll b/cl/_testrt/unsafe/out.ll index b06cb5ae90..f26be89be4 100644 --- a/cl/_testrt/unsafe/out.ll +++ b/cl/_testrt/unsafe/out.ll @@ -252,3 +252,7 @@ declare i1 @"github.com/goplus/llgo/runtime/internal/runtime.StringEqual"(%"gith declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocZ"(i64) declare void @"github.com/goplus/llgo/runtime/internal/runtime.AssertIndexRange"(i1) + +!llgo.useiface = !{!0} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/unsafe.main", !"_llgo_string"} diff --git a/cl/_testrt/vamethod/out.ll b/cl/_testrt/vamethod/out.ll index 4995830cc2..1c4dedb452 100644 --- a/cl/_testrt/vamethod/out.ll +++ b/cl/_testrt/vamethod/out.ll @@ -239,3 +239,16 @@ declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.AllocU"(i64) declare void @"github.com/goplus/llgo/runtime/internal/runtime.Panic"(%"github.com/goplus/llgo/runtime/internal/runtime.eface") attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: write) } + +!llgo.useiface = !{!0, !1} +!llgo.methodoff = !{!2, !3, !4, !5} +!llgo.useifacemethod = !{!6, !7} + +!0 = !{!"github.com/goplus/llgo/cl/_testrt/vamethod.main", !"*_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.CFmt"} +!1 = !{!"github.com/goplus/llgo/cl/_testrt/vamethod.main", !"_llgo_string"} +!2 = !{!"*_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.T", i32 0, !"Printf", !"_llgo_func$sSO5Bw-E3E7TeJqIJF_OmmojTYyqWBhYrUwNYJNw7Bs"} +!3 = !{!"_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.CFmt", i32 0, !"Printf", !"_llgo_func$sSO5Bw-E3E7TeJqIJF_OmmojTYyqWBhYrUwNYJNw7Bs"} +!4 = !{!"*_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.CFmt", i32 0, !"Printf", !"_llgo_func$sSO5Bw-E3E7TeJqIJF_OmmojTYyqWBhYrUwNYJNw7Bs"} +!5 = !{!"*_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.CFmt", i32 1, !"SetFormat", !"_llgo_func$vAfTC3ZLX0_lZI-ZNliu0_DkE266FSmKXxj_cqKPPkA"} +!6 = !{!"github.com/goplus/llgo/cl/_testrt/vamethod.main", !"_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.IFmt", !"SetFormat", !"_llgo_func$vAfTC3ZLX0_lZI-ZNliu0_DkE266FSmKXxj_cqKPPkA"} +!7 = !{!"github.com/goplus/llgo/cl/_testrt/vamethod.main", !"_llgo_github.com/goplus/llgo/cl/_testrt/vamethod.IFmt", !"Printf", !"_llgo_func$sSO5Bw-E3E7TeJqIJF_OmmojTYyqWBhYrUwNYJNw7Bs"} diff --git a/cl/instr.go b/cl/instr.go index c13facae9f..6e8b9a43b4 100644 --- a/cl/instr.go +++ b/cl/instr.go @@ -52,6 +52,60 @@ func constBool(v ssa.Value) (ret bool, ok bool) { return } +func isNamedType(t types.Type, pkgPath, name string) bool { + named, ok := types.Unalias(t).(*types.Named) + if !ok { + return false + } + obj := named.Obj() + return obj != nil && obj.Name() == name && obj.Pkg() != nil && obj.Pkg().Path() == pkgPath +} + +func staticCallMethod(call *ssa.CallCommon) (recv types.Type, method string, ok bool) { + fn := call.StaticCallee() + if fn == nil || fn.Signature == nil || fn.Signature.Recv() == nil { + return nil, "", false + } + return fn.Signature.Recv().Type(), fn.Name(), true +} + +func (p *context) markReflectMethodCall(call *ssa.CallCommon) { + owner := p.fn.Name() + + if method := call.Method; method != nil { + if !isNamedType(call.Value.Type(), "reflect", "Type") { + return + } + switch method.Name() { + case "Method": + p.pkg.EmitReflectMethod(owner) + case "MethodByName": + if name, ok := constStr(call.Args[0]); ok { + p.pkg.EmitUseNamedMethod(owner, name) + return + } + p.pkg.EmitReflectMethod(owner) + } + return + } + + recv, methodName, ok := staticCallMethod(call) + if ok && isNamedType(recv, "reflect", "Value") { + switch methodName { + case "Method": + p.pkg.EmitReflectMethod(owner) + case "MethodByName": + if method, ok := constStr(call.Args[len(call.Args)-1]); ok { + p.pkg.EmitUseNamedMethod(owner, method) + return + } + p.pkg.EmitReflectMethod(owner) + } + return + } + +} + // func pystr(string) *py.Object func pystr(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) { if len(args) == 1 { @@ -679,6 +733,7 @@ func (p *context) pkgNoInit(pkg *types.Package) bool { // ----------------------------------------------------------------------------- func (p *context) call(b llssa.Builder, act llssa.DoAction, call *ssa.CallCommon) (ret llssa.Expr) { + p.markReflectMethodCall(call) cv := call.Value if mthd := call.Method; mthd != nil { o := p.compileValue(b, cv) diff --git a/internal/build/build.go b/internal/build/build.go index ae14ce01c8..4d5d06d667 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -38,6 +38,7 @@ import ( "golang.org/x/tools/go/ssa" "github.com/goplus/llgo/cl" + "github.com/goplus/llgo/internal/build/dce" "github.com/goplus/llgo/internal/cabi" "github.com/goplus/llgo/internal/clang" "github.com/goplus/llgo/internal/crosscompile" @@ -999,6 +1000,11 @@ func linkMainPkg(ctx *context, pkg *packages.Package, pkgs []*aPackage, outputPa methodByName: methodByName, abiSymbols: linkedModuleGlobals(linkedOrder), }) + if ctx.buildConf.BuildMode == BuildModeExe { + if err := applyDCEOverrides(ctx, linkedOrder, entryPkg, verbose); err != nil { + return err + } + } entryObjFile, err := exportObject(ctx, "entry_main", entryPkg.ExportFile, []byte(entryPkg.LPkg.String())) if err != nil { return err @@ -1054,6 +1060,42 @@ func linkedModuleGlobals(pkgs []Package) map[string]none { return seen } +func dceEntryRoots() []string { + return []string{"main", "_start", "__main_argc_argv"} +} + +func dceSourceModules(pkgs []Package) []gllvm.Module { + mods := make([]gllvm.Module, 0, len(pkgs)) + for _, pkg := range pkgs { + if pkg == nil || pkg.LPkg == nil { + continue + } + mods = append(mods, pkg.LPkg.Module()) + } + return mods +} + +func applyDCEOverrides(ctx *context, pkgs []Package, entryPkg Package, verbose bool) error { + srcMods := dceSourceModules(pkgs) + mods := append(append([]gllvm.Module{}, srcMods...), entryPkg.LPkg.Module()) + result, err := dce.Analyze(mods, dceEntryRoots()) + if err != nil { + return fmt.Errorf("analyze link-time method reachability: %w", err) + } + if verbose { + report := dce.FormatResult(result) + if report == "" { + fmt.Fprintln(os.Stderr, "[dce] live methods: none") + } else { + fmt.Fprintf(os.Stderr, "[dce] live methods:\n%s", report) + } + } + if err := dce.EmitStrongTypeOverrides(entryPkg.LPkg.Module(), srcMods, result); err != nil { + return fmt.Errorf("emit dce type overrides: %w", err) + } + return nil +} + // isRuntimePkg reports whether the package path belongs to the llgo runtime tree. func isRuntimePkg(pkgPath string) bool { rtRoot := env.LLGoRuntimePkg diff --git a/internal/build/dce/analyze.go b/internal/build/dce/analyze.go new file mode 100644 index 0000000000..7014999afe --- /dev/null +++ b/internal/build/dce/analyze.go @@ -0,0 +1,309 @@ +package dce + +import ( + "sort" + "strconv" + "strings" + "unicode" + + llvm "github.com/goplus/llvm" +) + +// Result is the phase-1 method liveness output keyed by concrete type symbol. +// Each inner set contains the live abi.Method slot indexes for that type. +type Result map[string]map[int]struct{} + +// Input is the preprocessed analyzer input built from LLVM modules. +// The goal is to isolate LLVM scanning in BuildInput so the core analysis +// can operate on plain Go data structures. +type Input struct { + OrdinaryEdges map[string]map[string]struct{} + TypeChildren map[string]map[string]struct{} + MethodRefs map[string]map[int]map[string]struct{} + + UseIface []UseIfaceRow + UseIfaceMethod []UseIfaceMethodRow + MethodOff []MethodOffRow + UseNamedMethod []UseNamedMethodRow + ReflectMethod []ReflectMethodRow +} + +type UseIfaceRow struct { + Owner string + Target string +} + +type UseIfaceMethodRow struct { + Owner string + Target string + Name string + MTyp string +} + +type MethodOffRow struct { + TypeName string + Index int + Name string + MTyp string +} + +type UseNamedMethodRow struct { + Owner string + Name string +} + +type ReflectMethodRow struct { + Owner string +} + +type methodSig struct { + Name string + MTyp string +} + +type analyzer struct { + input Input + + reachable map[string]struct{} + worklist []string + usedInIface map[string]struct{} + ifaceDemand map[methodSig]struct{} + namedDemand map[string]struct{} + reflectSeen bool + result Result +} + +// Analyze is the package-level entry point used by the build pipeline. +// It first builds a pure-Go Input from the provided modules, then runs the +// phase-1 method reachability analysis on that input. +func Analyze(mods []llvm.Module, roots []string) (Result, error) { + input, err := BuildInput(mods) + if err != nil { + return nil, err + } + return AnalyzeInput(input, roots), nil +} + +// AnalyzeInput runs the phase-1 method reachability analysis on preprocessed +// analyzer input. +func AnalyzeInput(input Input, roots []string) Result { + a := analyzer{ + input: input, + reachable: make(map[string]struct{}), + usedInIface: make(map[string]struct{}), + ifaceDemand: make(map[methodSig]struct{}), + namedDemand: make(map[string]struct{}), + result: make(Result), + } + for _, root := range roots { + a.markReachable(root) + } + for { + a.flood() + changed := a.activateMetadata() + changed = a.markMethods() || changed + if len(a.worklist) == 0 && !changed { + break + } + } + a.ensurePrunableTypes() + return a.result +} + +func (a *analyzer) flood() { + for len(a.worklist) != 0 { + last := len(a.worklist) - 1 + sym := a.worklist[last] + a.worklist = a.worklist[:last] + for dst := range a.input.OrdinaryEdges[sym] { + a.markReachable(dst) + } + } +} + +func (a *analyzer) activateMetadata() bool { + changed := false + for _, row := range a.input.UseIface { + if a.isReachable(row.Owner) { + changed = a.markUsedInIface(row.Target) || changed + } + } + for _, row := range a.input.UseIfaceMethod { + if a.isReachable(row.Owner) { + changed = a.addIfaceDemand(methodSig{Name: row.Name, MTyp: row.MTyp}) || changed + } + } + for _, row := range a.input.UseNamedMethod { + if a.isReachable(row.Owner) { + changed = a.addNamedDemand(row.Name) || changed + } + } + for _, row := range a.input.ReflectMethod { + if a.isReachable(row.Owner) && !a.reflectSeen { + a.reflectSeen = true + changed = true + } + } + return changed +} + +func (a *analyzer) markMethods() bool { + changed := false + for _, row := range a.input.MethodOff { + if !a.isUsedInIface(row.TypeName) || !a.shouldKeepMethod(row) { + continue + } + if !a.addLiveMethod(row.TypeName, row.Index) { + continue + } + changed = true + for sym := range a.input.MethodRefs[row.TypeName][row.Index] { + if a.markReachable(sym) { + changed = true + } + } + } + return changed +} + +func (a *analyzer) shouldKeepMethod(row MethodOffRow) bool { + if _, ok := a.ifaceDemand[methodSig{Name: row.Name, MTyp: row.MTyp}]; ok { + return true + } + if _, ok := a.namedDemand[row.Name]; ok { + return true + } + return a.reflectSeen && isExportedMethod(row.Name) +} + +func (a *analyzer) markReachable(sym string) bool { + if sym == "" { + return false + } + if _, ok := a.reachable[sym]; ok { + return false + } + a.reachable[sym] = struct{}{} + a.worklist = append(a.worklist, sym) + return true +} + +func (a *analyzer) markUsedInIface(typeName string) bool { + if typeName == "" { + return false + } + changed := false + work := []string{typeName} + for len(work) != 0 { + last := len(work) - 1 + sym := work[last] + work = work[:last] + if _, ok := a.usedInIface[sym]; ok { + continue + } + a.usedInIface[sym] = struct{}{} + changed = true + for child := range a.input.TypeChildren[sym] { + work = append(work, child) + } + } + return changed +} + +func (a *analyzer) addIfaceDemand(sig methodSig) bool { + if sig.Name == "" || sig.MTyp == "" { + return false + } + if _, ok := a.ifaceDemand[sig]; ok { + return false + } + a.ifaceDemand[sig] = struct{}{} + return true +} + +func (a *analyzer) addNamedDemand(name string) bool { + if name == "" { + return false + } + if _, ok := a.namedDemand[name]; ok { + return false + } + a.namedDemand[name] = struct{}{} + return true +} + +func (a *analyzer) addLiveMethod(typeName string, index int) bool { + byIndex := a.result[typeName] + if byIndex == nil { + byIndex = make(map[int]struct{}) + a.result[typeName] = byIndex + } + if _, ok := byIndex[index]; ok { + return false + } + byIndex[index] = struct{}{} + return true +} + +func (a *analyzer) isReachable(sym string) bool { + _, ok := a.reachable[sym] + return ok +} + +func (a *analyzer) isUsedInIface(typeName string) bool { + _, ok := a.usedInIface[typeName] + return ok +} + +func (a *analyzer) ensurePrunableTypes() { + for _, row := range a.input.MethodOff { + if !a.isUsedInIface(row.TypeName) { + continue + } + if _, ok := a.result[row.TypeName]; ok { + continue + } + a.result[row.TypeName] = make(map[int]struct{}) + } +} + +func isExportedMethod(name string) bool { + for _, r := range name { + return unicode.IsUpper(r) + } + return false +} + +// FormatResult renders the analyzer output as stable text lines: +// +// type symbol: [sorted method indexes] +func FormatResult(result Result) string { + if len(result) == 0 { + return "" + } + typeNames := make([]string, 0, len(result)) + for typeName := range result { + typeNames = append(typeNames, typeName) + } + sort.Strings(typeNames) + + var b strings.Builder + for _, typeName := range typeNames { + indexes := make([]int, 0, len(result[typeName])) + for index := range result[typeName] { + indexes = append(indexes, index) + } + sort.Ints(indexes) + + b.WriteString(typeName) + b.WriteString(": [") + for i, index := range indexes { + if i != 0 { + b.WriteByte(' ') + } + b.WriteString(strconv.Itoa(index)) + } + b.WriteString("]\n") + } + return b.String() +} diff --git a/internal/build/dce/analyze_test.go b/internal/build/dce/analyze_test.go new file mode 100644 index 0000000000..8a0661d9ed --- /dev/null +++ b/internal/build/dce/analyze_test.go @@ -0,0 +1,562 @@ +package dce + +import ( + "bytes" + "os" + "path/filepath" + "reflect" + "testing" + + llvm "github.com/goplus/llvm" +) + +func TestAnalyzeEmpty(t *testing.T) { + got, err := Analyze(nil, nil) + if err != nil { + t.Fatalf("Analyze(nil, nil) error = %v", err) + } + if len(got) != 0 { + t.Fatalf("Analyze(nil, nil) = %#v, want empty result", got) + } +} + +func TestBuildInputEmpty(t *testing.T) { + input, err := BuildInput([]llvm.Module{}) + if err != nil { + t.Fatalf("BuildInput(empty) error = %v", err) + } + if input.OrdinaryEdges == nil { + t.Fatal("BuildInput(empty) returned nil OrdinaryEdges") + } + if input.TypeChildren == nil { + t.Fatal("BuildInput(empty) returned nil TypeChildren") + } + if input.MethodRefs == nil { + t.Fatal("BuildInput(empty) returned nil MethodRefs") + } +} + +func TestBuildInputReadsMetadataAndOrdinaryEdges(t *testing.T) { + ctx := llvm.NewContext() + defer ctx.Dispose() + + mod := ctx.NewModule("test") + defer mod.Dispose() + + void := ctx.VoidType() + fnType := llvm.FunctionType(void, nil, false) + caller := llvm.AddFunction(mod, "caller", fnType) + callee := llvm.AddFunction(mod, "callee", fnType) + + builder := ctx.NewBuilder() + defer builder.Dispose() + entry := ctx.AddBasicBlock(caller, "entry") + builder.SetInsertPointAtEnd(entry) + builder.CreateCall(fnType, callee, nil, "") + builder.CreateRetVoid() + + target := llvm.AddGlobal(mod, ctx.Int32Type(), "target") + target.SetInitializer(llvm.ConstInt(ctx.Int32Type(), 7, false)) + holder := llvm.AddGlobal(mod, llvm.PointerType(ctx.Int32Type(), 0), "holder") + holder.SetInitializer(target) + + mod.AddNamedMetadataOperand(llgoUseIfaceMetadata, ctx.MDNode([]llvm.Metadata{ + ctx.MDString("owner.useiface"), + ctx.MDString("_llgo_type.T"), + })) + mod.AddNamedMetadataOperand(llgoUseIfaceMethodMetadata, ctx.MDNode([]llvm.Metadata{ + ctx.MDString("owner.ifacemethod"), + ctx.MDString("_llgo_iface.I"), + ctx.MDString("M"), + ctx.MDString("_llgo_func$abc"), + })) + mod.AddNamedMetadataOperand(llgoMethodOffMetadata, ctx.MDNode([]llvm.Metadata{ + ctx.MDString("_llgo_type.T"), + llvm.ConstInt(ctx.Int32Type(), 3, false).ConstantAsMetadata(), + ctx.MDString("M"), + ctx.MDString("_llgo_func$abc"), + })) + mod.AddNamedMetadataOperand(llgoUseNamedMethodMetadata, ctx.MDNode([]llvm.Metadata{ + ctx.MDString("owner.named"), + ctx.MDString("M"), + })) + mod.AddNamedMetadataOperand(llgoReflectMethodMetadata, ctx.MDNode([]llvm.Metadata{ + ctx.MDString("owner.reflect"), + })) + + input, err := BuildInput([]llvm.Module{mod}) + if err != nil { + t.Fatalf("BuildInput(module) error = %v", err) + } + + if _, ok := input.OrdinaryEdges["caller"]["callee"]; !ok { + t.Fatalf("OrdinaryEdges[caller] missing callee: %#v", input.OrdinaryEdges["caller"]) + } + if _, ok := input.OrdinaryEdges["holder"]["target"]; !ok { + t.Fatalf("OrdinaryEdges[holder] missing target: %#v", input.OrdinaryEdges["holder"]) + } + + if got, want := input.UseIface, []UseIfaceRow{{ + Owner: "owner.useiface", + Target: "_llgo_type.T", + }}; !reflect.DeepEqual(got, want) { + t.Fatalf("UseIface = %#v, want %#v", got, want) + } + if got, want := input.UseIfaceMethod, []UseIfaceMethodRow{{ + Owner: "owner.ifacemethod", + Target: "_llgo_iface.I", + Name: "M", + MTyp: "_llgo_func$abc", + }}; !reflect.DeepEqual(got, want) { + t.Fatalf("UseIfaceMethod = %#v, want %#v", got, want) + } + if got, want := input.MethodOff, []MethodOffRow{{ + TypeName: "_llgo_type.T", + Index: 3, + Name: "M", + MTyp: "_llgo_func$abc", + }}; !reflect.DeepEqual(got, want) { + t.Fatalf("MethodOff = %#v, want %#v", got, want) + } + if got, want := input.UseNamedMethod, []UseNamedMethodRow{{ + Owner: "owner.named", + Name: "M", + }}; !reflect.DeepEqual(got, want) { + t.Fatalf("UseNamedMethod = %#v, want %#v", got, want) + } + if got, want := input.ReflectMethod, []ReflectMethodRow{{ + Owner: "owner.reflect", + }}; !reflect.DeepEqual(got, want) { + t.Fatalf("ReflectMethod = %#v, want %#v", got, want) + } +} + +func TestBuildInputReadsTypeChildren(t *testing.T) { + ctx := llvm.NewContext() + defer ctx.Dispose() + + mod := ctx.NewModule("types") + defer mod.Dispose() + + i32 := ctx.Int32Type() + abiType := ctx.StructCreateNamed(runtimeABIPrefix + "Type") + abiType.StructSetBody([]llvm.Type{i32}, false) + + zeroABIType := llvm.ConstNamedStruct(abiType, []llvm.Value{ + llvm.ConstInt(i32, 0, false), + }) + + typeC := llvm.AddGlobal(mod, abiType, "_llgo_type.C") + typeC.SetInitializer(zeroABIType) + + typeBType := llvm.StructType([]llvm.Type{abiType, llvm.PointerType(abiType, 0)}, false) + typeB := llvm.AddGlobal(mod, typeBType, "_llgo_type.B") + typeB.SetInitializer(llvm.ConstNamedStruct(typeBType, []llvm.Value{ + zeroABIType, + typeC, + })) + + helperElem := llvm.PointerType(abiType, 0) + helper := llvm.AddGlobal(mod, llvm.ArrayType(helperElem, 1), "helper") + helper.SetInitializer(llvm.ConstArray(helperElem, []llvm.Value{typeB})) + + typeAType := llvm.StructType([]llvm.Type{abiType, llvm.PointerType(helper.GlobalValueType(), 0)}, false) + typeA := llvm.AddGlobal(mod, typeAType, "_llgo_type.A") + typeA.SetInitializer(llvm.ConstNamedStruct(typeAType, []llvm.Value{ + zeroABIType, + helper, + })) + + input, err := BuildInput([]llvm.Module{mod}) + if err != nil { + t.Fatalf("BuildInput(type children) error = %v", err) + } + + if got, want := input.TypeChildren["_llgo_type.A"], map[string]struct{}{ + "_llgo_type.B": {}, + }; !reflect.DeepEqual(got, want) { + t.Fatalf("TypeChildren[A] = %#v, want %#v", got, want) + } + if got, want := input.TypeChildren["_llgo_type.B"], map[string]struct{}{ + "_llgo_type.C": {}, + }; !reflect.DeepEqual(got, want) { + t.Fatalf("TypeChildren[B] = %#v, want %#v", got, want) + } + if _, ok := input.TypeChildren["_llgo_type.C"]; ok { + t.Fatalf("TypeChildren[C] = %#v, want no direct children", input.TypeChildren["_llgo_type.C"]) + } + if _, ok := input.TypeChildren["helper"]; ok { + t.Fatalf("TypeChildren[helper] = %#v, helper global should not be a type node", input.TypeChildren["helper"]) + } +} + +func TestBuildInputSeparatesMethodRefsFromOrdinaryEdges(t *testing.T) { + ctx := llvm.NewContext() + defer ctx.Dispose() + + mod := ctx.NewModule("methods") + defer mod.Dispose() + + i32 := ctx.Int32Type() + void := ctx.VoidType() + + abiType := ctx.StructCreateNamed(runtimeABIPrefix + "Type") + abiType.StructSetBody([]llvm.Type{i32}, false) + uncommonType := ctx.StructCreateNamed(runtimeABIPrefix + "UncommonType") + uncommonType.StructSetBody([]llvm.Type{i32}, false) + methodType := ctx.StructCreateNamed(runtimeABIPrefix + "Method") + methodType.StructSetBody([]llvm.Type{ + abiType, + llvm.PointerType(void, 0), + llvm.PointerType(void, 0), + llvm.PointerType(void, 0), + }, false) + + zeroABIType := llvm.ConstNamedStruct(abiType, []llvm.Value{ + llvm.ConstInt(i32, 0, false), + }) + zeroUncommon := llvm.ConstNamedStruct(uncommonType, []llvm.Value{ + llvm.ConstInt(i32, 0, false), + }) + + mtyp := llvm.AddGlobal(mod, abiType, "_llgo_func$abc") + mtyp.SetInitializer(zeroABIType) + + fnType := llvm.FunctionType(void, nil, false) + ifn := llvm.AddFunction(mod, "pkg.T.ifn", fnType) + ifnBlock := ctx.AddBasicBlock(ifn, "entry") + builder := ctx.NewBuilder() + defer builder.Dispose() + builder.SetInsertPointAtEnd(ifnBlock) + builder.CreateRetVoid() + + tfn := llvm.AddFunction(mod, "pkg.T.tfn", fnType) + tfnBlock := ctx.AddBasicBlock(tfn, "entry") + builder.SetInsertPointAtEnd(tfnBlock) + builder.CreateRetVoid() + + methods := llvm.ConstArray(methodType, []llvm.Value{ + llvm.ConstNamedStruct(methodType, []llvm.Value{ + zeroABIType, + mtyp, + ifn, + tfn, + }), + }) + typeTType := llvm.StructType([]llvm.Type{abiType, uncommonType, llvm.ArrayType(methodType, 1)}, false) + typeT := llvm.AddGlobal(mod, typeTType, "_llgo_type.T") + typeT.SetInitializer(llvm.ConstNamedStruct(typeTType, []llvm.Value{ + zeroABIType, + zeroUncommon, + methods, + })) + + input, err := BuildInput([]llvm.Module{mod}) + if err != nil { + t.Fatalf("BuildInput(method refs) error = %v", err) + } + + if got, want := input.MethodRefs["_llgo_type.T"][0], map[string]struct{}{ + "_llgo_func$abc": {}, + "pkg.T.ifn": {}, + "pkg.T.tfn": {}, + }; !reflect.DeepEqual(got, want) { + t.Fatalf("MethodRefs[T][0] = %#v, want %#v", got, want) + } + if got := input.OrdinaryEdges["_llgo_type.T"]; len(got) != 0 { + t.Fatalf("OrdinaryEdges[type] = %#v, want no method refs in ordinary graph", got) + } +} + +func TestAnalyzeInputFollowsMethodRefs(t *testing.T) { + input := Input{ + OrdinaryEdges: map[string]map[string]struct{}{ + "root": {"owner.useiface": {}}, + "method.one": {"owner.named": {}}, + }, + TypeChildren: make(map[string]map[string]struct{}), + MethodRefs: map[string]map[int]map[string]struct{}{ + "_llgo_type.T": { + 0: {"method.one": {}}, + 1: {"method.two": {}}, + }, + }, + UseIface: []UseIfaceRow{{ + Owner: "owner.useiface", + Target: "_llgo_type.T", + }}, + UseIfaceMethod: []UseIfaceMethodRow{{ + Owner: "owner.useiface", + Name: "IfaceM", + MTyp: "_llgo_func$iface", + }}, + MethodOff: []MethodOffRow{ + {TypeName: "_llgo_type.T", Index: 0, Name: "IfaceM", MTyp: "_llgo_func$iface"}, + {TypeName: "_llgo_type.T", Index: 1, Name: "NamedM", MTyp: "_llgo_func$named"}, + }, + UseNamedMethod: []UseNamedMethodRow{{ + Owner: "owner.named", + Name: "NamedM", + }}, + } + + got := AnalyzeInput(input, []string{"root"}) + want := Result{ + "_llgo_type.T": { + 0: {}, + 1: {}, + }, + } + if !reflect.DeepEqual(got, want) { + t.Fatalf("AnalyzeInput(method refs) = %#v, want %#v", got, want) + } +} + +func TestAnalyzeInputPropagatesUsedInIfaceToChildTypes(t *testing.T) { + input := Input{ + OrdinaryEdges: map[string]map[string]struct{}{ + "root": {"owner.useiface": {}}, + }, + TypeChildren: map[string]map[string]struct{}{ + "_llgo_type.Parent": {"_llgo_type.Child": {}}, + }, + MethodRefs: map[string]map[int]map[string]struct{}{ + "_llgo_type.Child": {0: {"child.method": {}}}, + }, + UseIface: []UseIfaceRow{{ + Owner: "owner.useiface", + Target: "_llgo_type.Parent", + }}, + UseIfaceMethod: []UseIfaceMethodRow{{ + Owner: "owner.useiface", + Name: "M", + MTyp: "_llgo_func$child", + }}, + MethodOff: []MethodOffRow{{ + TypeName: "_llgo_type.Child", + Index: 0, + Name: "M", + MTyp: "_llgo_func$child", + }}, + } + + got := AnalyzeInput(input, []string{"root"}) + want := Result{ + "_llgo_type.Child": {0: {}}, + } + if !reflect.DeepEqual(got, want) { + t.Fatalf("AnalyzeInput(used in iface) = %#v, want %#v", got, want) + } +} + +func TestAnalyzeInputReflectKeepsExportedMethods(t *testing.T) { + input := Input{ + OrdinaryEdges: map[string]map[string]struct{}{ + "root": {"owner.reflect": {}}, + }, + TypeChildren: make(map[string]map[string]struct{}), + MethodRefs: make(map[string]map[int]map[string]struct{}), + UseIface: []UseIfaceRow{{ + Owner: "owner.reflect", + Target: "_llgo_type.T", + }}, + ReflectMethod: []ReflectMethodRow{{ + Owner: "owner.reflect", + }}, + MethodOff: []MethodOffRow{ + {TypeName: "_llgo_type.T", Index: 0, Name: "Exported", MTyp: "_llgo_func$exported"}, + {TypeName: "_llgo_type.T", Index: 1, Name: "pkg.unexported", MTyp: "_llgo_func$unexported"}, + }, + } + + got := AnalyzeInput(input, []string{"root"}) + want := Result{ + "_llgo_type.T": {0: {}}, + } + if !reflect.DeepEqual(got, want) { + t.Fatalf("AnalyzeInput(reflect) = %#v, want %#v", got, want) + } +} + +func TestAnalyzeInputKeepsEmptyMethodSetsForPrunableTypes(t *testing.T) { + input := Input{ + UseIface: []UseIfaceRow{{ + Owner: "main", + Target: "_llgo_type.T", + }}, + MethodOff: []MethodOffRow{{ + TypeName: "_llgo_type.T", + Index: 0, + Name: "M", + MTyp: "_llgo_func$M", + }}, + } + + got := AnalyzeInput(input, []string{"main"}) + want := Result{ + "_llgo_type.T": {}, + } + if !reflect.DeepEqual(got, want) { + t.Fatalf("AnalyzeInput(empty method set) = %#v, want %#v", got, want) + } +} + +func TestAnalyzeClosureallModule(t *testing.T) { + mod := loadIRModule(t, "../../../cl/_testgo/closureall/out.ll") + got, err := Analyze([]llvm.Module{mod}, []string{ + "github.com/goplus/llgo/cl/_testgo/closureall.main", + }) + if err != nil { + t.Fatalf("Analyze(closureall) error = %v", err) + } + want := Result{ + "_llgo_github.com/goplus/llgo/cl/_testgo/closureall.S": {}, + "*_llgo_github.com/goplus/llgo/cl/_testgo/closureall.S": {0: {}}, + } + if !reflect.DeepEqual(got, want) { + t.Fatalf("Analyze(closureall) = %#v, want %#v", got, want) + } +} + +func TestAnalyzeReflectmethodModule(t *testing.T) { + mod := loadIRModule(t, "../../../cl/_testgo/reflectmethod/out.ll") + got, err := Analyze([]llvm.Module{mod}, []string{ + "github.com/goplus/llgo/cl/_testgo/reflectmethod.main", + }) + if err != nil { + t.Fatalf("Analyze(reflectmethod) error = %v", err) + } + want := Result{ + "*_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T": {0: {}}, + "_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T": {0: {}}, + } + if !reflect.DeepEqual(got, want) { + t.Fatalf("Analyze(reflectmethod) = %#v, want %#v", got, want) + } +} + +func TestAnalyzeInvokeModule(t *testing.T) { + mod := loadIRModule(t, "../../../cl/_testgo/invoke/out.ll") + got, err := Analyze([]llvm.Module{mod}, []string{ + "github.com/goplus/llgo/cl/_testgo/invoke.main", + }) + if err != nil { + t.Fatalf("Analyze(invoke) error = %v", err) + } + want := Result{ + "*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T": {0: {}}, + "*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T1": {0: {}}, + "*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T2": {0: {}}, + "*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T3": {0: {}}, + "*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T4": {0: {}}, + "*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T5": {0: {}}, + "*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T6": {0: {}}, + "_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T": {0: {}}, + "_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T1": {0: {}}, + "_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T2": {0: {}}, + "_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T4": {0: {}}, + "_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T5": {0: {}}, + "_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T6": {0: {}}, + } + if !reflect.DeepEqual(got, want) { + t.Fatalf("Analyze(invoke) = %#v, want %#v", got, want) + } +} + +func TestFormatResult(t *testing.T) { + result := Result{ + "_llgo_type.B": {2: {}, 0: {}}, + "_llgo_type.A": {1: {}}, + } + got := FormatResult(result) + want := "_llgo_type.A: [1]\n_llgo_type.B: [0 2]\n" + if got != want { + t.Fatalf("FormatResult() = %q, want %q", got, want) + } +} + +func TestAnalyzeModuleOutputs(t *testing.T) { + tests := []struct { + name string + llPath string + root string + golden string + }{ + { + name: "closureall", + llPath: "../../../cl/_testgo/closureall/out.ll", + root: "github.com/goplus/llgo/cl/_testgo/closureall.main", + golden: "testdata/closureall.txt", + }, + { + name: "invoke", + llPath: "../../../cl/_testgo/invoke/out.ll", + root: "github.com/goplus/llgo/cl/_testgo/invoke.main", + golden: "testdata/invoke.txt", + }, + { + name: "reader", + llPath: "../../../cl/_testgo/reader/out.ll", + root: "github.com/goplus/llgo/cl/_testgo/reader.main", + golden: "testdata/reader.txt", + }, + { + name: "reflectmethod", + llPath: "../../../cl/_testgo/reflectmethod/out.ll", + root: "github.com/goplus/llgo/cl/_testgo/reflectmethod.main", + golden: "testdata/reflectmethod.txt", + }, + { + name: "ifaceconv", + llPath: "../../../cl/_testgo/ifaceconv/out.ll", + root: "github.com/goplus/llgo/cl/_testgo/ifaceconv.main", + golden: "testdata/ifaceconv.txt", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mod := loadIRModule(t, tt.llPath) + got, err := Analyze([]llvm.Module{mod}, []string{tt.root}) + if err != nil { + t.Fatalf("Analyze(%s) error = %v", tt.name, err) + } + assertGoldenText(t, tt.golden, FormatResult(got)) + }) + } +} + +func loadIRModule(t *testing.T, rel string) llvm.Module { + t.Helper() + + path := filepath.Clean(rel) + if _, err := os.Stat(path); err != nil { + t.Fatalf("Stat(%s) error = %v", path, err) + } + buf, err := llvm.NewMemoryBufferFromFile(path) + if err != nil { + t.Fatalf("NewMemoryBufferFromFile(%s) error = %v", path, err) + } + + ctx := llvm.NewContext() + t.Cleanup(ctx.Dispose) + + mod, err := (&ctx).ParseIR(buf) + if err != nil { + t.Fatalf("ParseIR(%s) error = %v", path, err) + } + t.Cleanup(mod.Dispose) + return mod +} + +func assertGoldenText(t *testing.T, rel string, got string) { + t.Helper() + + path := filepath.Clean(rel) + want, err := os.ReadFile(path) + if err != nil { + t.Fatalf("ReadFile(%s) error = %v", path, err) + } + if !bytes.Equal([]byte(got), want) { + t.Fatalf("golden mismatch for %s\n==> got:\n%s==> want:\n%s", path, got, string(want)) + } +} diff --git a/internal/build/dce/graph.go b/internal/build/dce/graph.go new file mode 100644 index 0000000000..19b3eee203 --- /dev/null +++ b/internal/build/dce/graph.go @@ -0,0 +1,443 @@ +package dce + +/* +#include + +typedef struct LLVMOpaqueModule *LLVMModuleRef; +typedef struct LLVMOpaqueValue *LLVMValueRef; + +unsigned LLVMGetNamedMetadataNumOperands(LLVMModuleRef M, const char *Name); +void LLVMGetNamedMetadataOperands(LLVMModuleRef M, const char *Name, LLVMValueRef *Dest); +unsigned LLVMGetMDNodeNumOperands(LLVMValueRef V); +void LLVMGetMDNodeOperands(LLVMValueRef V, LLVMValueRef *Dest); +const char *LLVMGetMDString(LLVMValueRef V, unsigned *Length); + +static unsigned llgoNamedMetadataNumOperands(void *M, const char *Name) { + return LLVMGetNamedMetadataNumOperands((LLVMModuleRef)M, Name); +} + +static void llgoNamedMetadataOperands(void *M, const char *Name, LLVMValueRef *Dest) { + LLVMGetNamedMetadataOperands((LLVMModuleRef)M, Name, Dest); +} + +static unsigned llgoMDNodeNumOperands(void *V) { + return LLVMGetMDNodeNumOperands((LLVMValueRef)V); +} + +static void llgoMDNodeOperands(void *V, LLVMValueRef *Dest) { + LLVMGetMDNodeOperands((LLVMValueRef)V, Dest); +} + +static const char *llgoMDString(void *V, unsigned *Length) { + return LLVMGetMDString((LLVMValueRef)V, Length); +} +*/ +import "C" + +import ( + "fmt" + "strings" + "unsafe" + + llvm "github.com/goplus/llvm" +) + +const ( + llgoUseIfaceMetadata = "llgo.useiface" + llgoUseIfaceMethodMetadata = "llgo.useifacemethod" + llgoMethodOffMetadata = "llgo.methodoff" + llgoUseNamedMethodMetadata = "llgo.usenamedmethod" + llgoReflectMethodMetadata = "llgo.reflectmethod" + + runtimeABIPrefix = "github.com/goplus/llgo/runtime/abi." +) + +// BuildInput constructs the phase-1 analyzer input from LLVM modules. +// This stage centralizes LLVM scanning so the core analysis can run on +// plain Go data structures. +func BuildInput(mods []llvm.Module) (Input, error) { + input := Input{ + OrdinaryEdges: make(map[string]map[string]struct{}), + TypeChildren: make(map[string]map[string]struct{}), + MethodRefs: make(map[string]map[int]map[string]struct{}), + } + for _, mod := range mods { + if mod.IsNil() { + continue + } + scanModuleOrdinaryEdges(input.OrdinaryEdges, mod) + scanModuleTypeChildren(input.TypeChildren, mod) + scanModuleMethodRefs(input.MethodRefs, mod) + if err := scanModuleMetadata(&input, mod); err != nil { + return Input{}, err + } + } + return input, nil +} + +func scanModuleOrdinaryEdges(edges map[string]map[string]struct{}, mod llvm.Module) { + for fn := mod.FirstFunction(); !fn.IsNil(); fn = llvm.NextFunction(fn) { + src := fn.Name() + if src == "" || fn.IsDeclaration() { + continue + } + for bb := fn.FirstBasicBlock(); !bb.IsNil(); bb = llvm.NextBasicBlock(bb) { + for inst := bb.FirstInstruction(); !inst.IsNil(); inst = llvm.NextInstruction(inst) { + collectValueEdges(edges, src, inst) + } + } + } + for g := mod.FirstGlobal(); !g.IsNil(); g = llvm.NextGlobal(g) { + src := g.Name() + if src == "" { + continue + } + init := g.Initializer() + if init.IsNil() { + continue + } + if isTypeGlobal(g) { + collectTypeGlobalOrdinaryEdges(edges, src, g) + continue + } + collectValueEdges(edges, src, init) + } +} + +func collectTypeGlobalOrdinaryEdges(edges map[string]map[string]struct{}, src string, g llvm.Value) { + init := g.Initializer() + if init.IsNil() { + return + } + if !hasUncommonTypeLayout(g.GlobalValueType()) || init.OperandsCount() != 3 { + collectValueEdges(edges, src, init) + return + } + collectValueEdges(edges, src, init.Operand(0)) + collectValueEdges(edges, src, init.Operand(1)) +} + +func collectValueEdges(edges map[string]map[string]struct{}, src string, root llvm.Value) { + seen := make(map[unsafe.Pointer]struct{}) + var visit func(v llvm.Value) + visit = func(v llvm.Value) { + if v.IsNil() { + return + } + ptr := unsafe.Pointer(v.C) + if _, ok := seen[ptr]; ok { + return + } + seen[ptr] = struct{}{} + + if dst := symbolNameOf(v); dst != "" { + addEdge(edges, src, dst) + } + for i := 0; i < v.OperandsCount(); i++ { + visit(v.Operand(i)) + } + } + visit(root) +} + +func addEdge(edges map[string]map[string]struct{}, src, dst string) { + if src == "" || dst == "" { + return + } + out := edges[src] + if out == nil { + out = make(map[string]struct{}) + edges[src] = out + } + out[dst] = struct{}{} +} + +func symbolNameOf(v llvm.Value) string { + if v.IsNil() || v.IsAGlobalValue().IsNil() { + return "" + } + return v.Name() +} + +func scanModuleTypeChildren(typeChildren map[string]map[string]struct{}, mod llvm.Module) { + globals := make(map[string]llvm.Value) + for g := mod.FirstGlobal(); !g.IsNil(); g = llvm.NextGlobal(g) { + if name := g.Name(); name != "" { + globals[name] = g + } + } + for _, g := range globals { + if !isTypeGlobal(g) { + continue + } + scanTypeChildren(typeChildren, g) + } +} + +func scanTypeChildren(typeChildren map[string]map[string]struct{}, g llvm.Value) { + src := g.Name() + init := g.Initializer() + if src == "" || init.IsNil() { + return + } + seen := make(map[unsafe.Pointer]struct{}) + var visit func(v llvm.Value) + visit = func(v llvm.Value) { + if v.IsNil() { + return + } + ptr := unsafe.Pointer(v.C) + if _, ok := seen[ptr]; ok { + return + } + seen[ptr] = struct{}{} + + for i := 0; i < v.OperandsCount(); i++ { + op := v.Operand(i) + if op.IsNil() { + continue + } + if !op.IsAGlobalVariable().IsNil() { + dst := op.Name() + if dst == "" || dst == src { + continue + } + if isTypeGlobal(op) { + addEdge(typeChildren, src, dst) + continue + } + if init := op.Initializer(); !init.IsNil() { + visit(init) + } + continue + } + visit(op) + } + } + visit(init) +} + +func scanModuleMethodRefs(methodRefs map[string]map[int]map[string]struct{}, mod llvm.Module) { + for g := mod.FirstGlobal(); !g.IsNil(); g = llvm.NextGlobal(g) { + if !isTypeGlobal(g) { + continue + } + scanMethodRefs(methodRefs, g) + } +} + +func scanMethodRefs(methodRefs map[string]map[int]map[string]struct{}, g llvm.Value) { + if !hasUncommonTypeLayout(g.GlobalValueType()) { + return + } + init := g.Initializer() + if init.IsNil() || init.OperandsCount() != 3 { + return + } + methods := init.Operand(2) + for i := 0; i < methods.OperandsCount(); i++ { + method := methods.Operand(i) + if method.IsNil() || method.OperandsCount() != 4 { + continue + } + for j := 1; j < 4; j++ { + if ref := symbolNameOf(method.Operand(j)); ref != "" { + addMethodRef(methodRefs, g.Name(), i, ref) + } + } + } +} + +func addMethodRef(methodRefs map[string]map[int]map[string]struct{}, typeName string, index int, sym string) { + if typeName == "" || sym == "" { + return + } + byIndex := methodRefs[typeName] + if byIndex == nil { + byIndex = make(map[int]map[string]struct{}) + methodRefs[typeName] = byIndex + } + refs := byIndex[index] + if refs == nil { + refs = make(map[string]struct{}) + byIndex[index] = refs + } + refs[sym] = struct{}{} +} + +func isTypeGlobal(v llvm.Value) bool { + if v.IsNil() || v.IsAGlobalVariable().IsNil() { + return false + } + return isABITypeDescriptor(v.GlobalValueType()) +} + +func isABITypeDescriptor(t llvm.Type) bool { + if t.IsNil() || t.TypeKind() != llvm.StructTypeKind { + return false + } + if isRuntimeABIType(t) { + return true + } + elems := t.StructElementTypes() + return len(elems) != 0 && isRuntimeABIType(elems[0]) +} + +func isRuntimeABIType(t llvm.Type) bool { + return t.TypeKind() == llvm.StructTypeKind && strings.HasPrefix(t.StructName(), runtimeABIPrefix) +} + +func hasUncommonTypeLayout(t llvm.Type) bool { + if t.IsNil() || t.TypeKind() != llvm.StructTypeKind { + return false + } + elems := t.StructElementTypes() + return len(elems) == 3 && elems[1].TypeKind() == llvm.StructTypeKind && elems[1].StructName() == runtimeABIPrefix+"UncommonType" +} + +func scanModuleMetadata(input *Input, mod llvm.Module) error { + if err := scanUseIface(input, mod); err != nil { + return err + } + if err := scanUseIfaceMethod(input, mod); err != nil { + return err + } + if err := scanMethodOff(input, mod); err != nil { + return err + } + if err := scanUseNamedMethod(input, mod); err != nil { + return err + } + if err := scanReflectMethod(input, mod); err != nil { + return err + } + return nil +} + +func scanUseIface(input *Input, mod llvm.Module) error { + rows, err := namedMetadataRows(mod, llgoUseIfaceMetadata) + if err != nil { + return err + } + for _, row := range rows { + if len(row) != 2 { + return fmt.Errorf("%s row has %d fields, want 2", llgoUseIfaceMetadata, len(row)) + } + input.UseIface = append(input.UseIface, UseIfaceRow{ + Owner: mdString(row[0]), + Target: mdString(row[1]), + }) + } + return nil +} + +func scanUseIfaceMethod(input *Input, mod llvm.Module) error { + rows, err := namedMetadataRows(mod, llgoUseIfaceMethodMetadata) + if err != nil { + return err + } + for _, row := range rows { + if len(row) != 4 { + return fmt.Errorf("%s row has %d fields, want 4", llgoUseIfaceMethodMetadata, len(row)) + } + input.UseIfaceMethod = append(input.UseIfaceMethod, UseIfaceMethodRow{ + Owner: mdString(row[0]), + Target: mdString(row[1]), + Name: mdString(row[2]), + MTyp: mdString(row[3]), + }) + } + return nil +} + +func scanMethodOff(input *Input, mod llvm.Module) error { + rows, err := namedMetadataRows(mod, llgoMethodOffMetadata) + if err != nil { + return err + } + for _, row := range rows { + if len(row) != 4 { + return fmt.Errorf("%s row has %d fields, want 4", llgoMethodOffMetadata, len(row)) + } + input.MethodOff = append(input.MethodOff, MethodOffRow{ + TypeName: mdString(row[0]), + Index: int(row[1].ZExtValue()), + Name: mdString(row[2]), + MTyp: mdString(row[3]), + }) + } + return nil +} + +func scanUseNamedMethod(input *Input, mod llvm.Module) error { + rows, err := namedMetadataRows(mod, llgoUseNamedMethodMetadata) + if err != nil { + return err + } + for _, row := range rows { + if len(row) != 2 { + return fmt.Errorf("%s row has %d fields, want 2", llgoUseNamedMethodMetadata, len(row)) + } + input.UseNamedMethod = append(input.UseNamedMethod, UseNamedMethodRow{ + Owner: mdString(row[0]), + Name: mdString(row[1]), + }) + } + return nil +} + +func scanReflectMethod(input *Input, mod llvm.Module) error { + rows, err := namedMetadataRows(mod, llgoReflectMethodMetadata) + if err != nil { + return err + } + for _, row := range rows { + if len(row) != 1 { + return fmt.Errorf("%s row has %d fields, want 1", llgoReflectMethodMetadata, len(row)) + } + input.ReflectMethod = append(input.ReflectMethod, ReflectMethodRow{ + Owner: mdString(row[0]), + }) + } + return nil +} + +func namedMetadataRows(mod llvm.Module, name string) ([][]llvm.Value, error) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + + n := int(C.llgoNamedMetadataNumOperands(unsafe.Pointer(mod.C), cname)) + if n == 0 { + return nil, nil + } + ops := make([]llvm.Value, n) + C.llgoNamedMetadataOperands(unsafe.Pointer(mod.C), cname, (*C.LLVMValueRef)(unsafe.Pointer(&ops[0]))) + rows := make([][]llvm.Value, 0, n) + for _, op := range ops { + row, err := mdNodeOperands(op) + if err != nil { + return nil, fmt.Errorf("%s: %w", name, err) + } + rows = append(rows, row) + } + return rows, nil +} + +func mdNodeOperands(node llvm.Value) ([]llvm.Value, error) { + n := int(C.llgoMDNodeNumOperands(unsafe.Pointer(node.C))) + if n < 0 { + return nil, fmt.Errorf("invalid mdnode operand count") + } + if n == 0 { + return nil, nil + } + ops := make([]llvm.Value, n) + C.llgoMDNodeOperands(unsafe.Pointer(node.C), (*C.LLVMValueRef)(unsafe.Pointer(&ops[0]))) + return ops, nil +} + +func mdString(v llvm.Value) string { + var n C.unsigned + s := C.llgoMDString(unsafe.Pointer(v.C), &n) + return C.GoStringN(s, C.int(n)) +} diff --git a/internal/build/dce/rewrite.go b/internal/build/dce/rewrite.go new file mode 100644 index 0000000000..0e6927af1a --- /dev/null +++ b/internal/build/dce/rewrite.go @@ -0,0 +1,308 @@ +package dce + +import ( + "fmt" + "sort" + + llvm "github.com/goplus/llvm" +) + +// EmitStrongTypeOverrides copies method-bearing ABI type globals into dst as +// strong definitions and clears dead abi.Method slots according to result. +// Linking the resulting module ahead of package archives lets these strong +// symbols override the original weak definitions. +func EmitStrongTypeOverrides(dst llvm.Module, srcMods []llvm.Module, result Result) error { + if dst.IsNil() { + return fmt.Errorf("destination module is nil") + } + if len(result) == 0 { + return nil + } + + srcTypes := make(map[string]llvm.Value) + for _, mod := range srcMods { + for g := mod.FirstGlobal(); !g.IsNil(); g = llvm.NextGlobal(g) { + name := g.Name() + if name == "" { + continue + } + if _, ok := srcTypes[name]; ok { + continue + } + srcTypes[name] = g + } + } + + typeNames := make([]string, 0, len(result)) + for typeName := range result { + typeNames = append(typeNames, typeName) + } + sort.Strings(typeNames) + + emitter := newOverrideEmitter(dst) + for _, typeName := range typeNames { + if shouldSkipOverride(typeName) { + continue + } + srcType := srcTypes[typeName] + if srcType.IsNil() { + return fmt.Errorf("missing source type global %q", typeName) + } + methodsVal, elemTy, ok := methodArray(srcType.Initializer()) + if !ok { + return fmt.Errorf("type global %q has no abi.Method array", typeName) + } + if methodsVal.OperandsCount() == 0 { + continue + } + if err := emitter.emitTypeOverride(srcType, methodsVal, elemTy, result[typeName]); err != nil { + return fmt.Errorf("emit override %q: %w", typeName, err) + } + } + return nil +} + +func shouldSkipOverride(typeName string) bool { + // reflect.Type values use *rtype identity as part of interface/map-key + // behavior. Overriding these concrete type symbols in the entry module can + // split identity across weak/original and strong/override copies, which + // breaks lookups such as map[reflect.Type]bool in testing/fuzz support. + switch typeName { + case "_llgo_reflect.rtype", "*_llgo_reflect.rtype", + "_llgo_internal/reflectlite.rtype", "*_llgo_internal/reflectlite.rtype": + return true + } + return false +} + +type overrideEmitter struct { + dst llvm.Module + values map[llvm.Value]llvm.Value +} + +func newOverrideEmitter(dst llvm.Module) *overrideEmitter { + return &overrideEmitter{ + dst: dst, + values: make(map[llvm.Value]llvm.Value), + } +} + +func (e *overrideEmitter) emitTypeOverride(srcType, methodsVal llvm.Value, elemTy llvm.Type, keepIdx map[int]struct{}) error { + init := srcType.Initializer() + dstType, err := e.ensureOverrideGlobal(srcType) + if err != nil { + return err + } + e.values[srcType] = dstType + + fields := make([]llvm.Value, init.OperandsCount()) + for i := 0; i < init.OperandsCount()-1; i++ { + clone, err := e.cloneConst(init.Operand(i)) + if err != nil { + return err + } + fields[i] = clone + } + + methodCount := methodsVal.OperandsCount() + methods := make([]llvm.Value, methodCount) + zeroText := llvm.ConstPointerNull(elemTy.StructElementTypes()[2]) + for i := 0; i < methodCount; i++ { + orig := methodsVal.Operand(i) + if _, ok := keepIdx[i]; ok { + clone, err := e.cloneConst(orig) + if err != nil { + return err + } + methods[i] = clone + continue + } + nameField, err := e.cloneConst(orig.Operand(0)) + if err != nil { + return err + } + mtypField, err := e.cloneConst(orig.Operand(1)) + if err != nil { + return err + } + methods[i] = llvm.ConstNamedStruct(elemTy, []llvm.Value{nameField, mtypField, zeroText, zeroText}) + } + fields[len(fields)-1] = llvm.ConstArray(elemTy, methods) + + dstType.SetInitializer(constStructOfType(init.Type(), fields)) + dstType.SetGlobalConstant(true) + dstType.SetLinkage(llvm.ExternalLinkage) + copyGlobalAttrs(dstType, srcType) + return nil +} + +func (e *overrideEmitter) ensureOverrideGlobal(src llvm.Value) (llvm.Value, error) { + name := src.Name() + if name == "" { + return llvm.Value{}, fmt.Errorf("type global has empty name") + } + dst := e.dst.NamedGlobal(name) + if dst.IsNil() { + dst = llvm.AddGlobal(e.dst, src.GlobalValueType(), name) + } + e.values[src] = dst + return dst, nil +} + +func (e *overrideEmitter) cloneConst(v llvm.Value) (llvm.Value, error) { + if v.IsNil() { + return llvm.Value{}, nil + } + if mapped, ok := e.values[v]; ok { + return mapped, nil + } + switch { + case !v.IsAGlobalValue().IsNil(): + clone, err := e.cloneGlobalValue(v) + if err != nil { + return llvm.Value{}, err + } + e.values[v] = clone + return clone, nil + case !v.IsAConstantStruct().IsNil(): + ops, err := e.cloneOperands(v) + if err != nil { + return llvm.Value{}, err + } + clone := constStructOfType(v.Type(), ops) + e.values[v] = clone + return clone, nil + case !v.IsAConstantArray().IsNil(): + ops, err := e.cloneOperands(v) + if err != nil { + return llvm.Value{}, err + } + clone := llvm.ConstArray(v.Type().ElementType(), ops) + e.values[v] = clone + return clone, nil + } + return v, nil +} + +func (e *overrideEmitter) cloneOperands(v llvm.Value) ([]llvm.Value, error) { + ops := make([]llvm.Value, v.OperandsCount()) + for i := 0; i < v.OperandsCount(); i++ { + clone, err := e.cloneConst(v.Operand(i)) + if err != nil { + return nil, err + } + ops[i] = clone + } + return ops, nil +} + +func (e *overrideEmitter) cloneGlobalValue(v llvm.Value) (llvm.Value, error) { + if mapped, ok := e.values[v]; ok { + return mapped, nil + } + if fn := v.IsAFunction(); !fn.IsNil() { + name := fn.Name() + if name == "" { + return llvm.Value{}, fmt.Errorf("function ref has empty name") + } + dstFn := e.dst.NamedFunction(name) + if dstFn.IsNil() { + dstFn = llvm.AddFunction(e.dst, name, fn.GlobalValueType()) + } + e.values[v] = dstFn + return dstFn, nil + } + if gv := v.IsAGlobalVariable(); !gv.IsNil() { + clone, err := e.cloneGlobalVariable(gv) + if err != nil { + return llvm.Value{}, err + } + e.values[v] = clone + return clone, nil + } + name := v.Name() + if name != "" { + dstG := e.dst.NamedGlobal(name) + if dstG.IsNil() { + dstG = llvm.AddGlobal(e.dst, v.GlobalValueType(), name) + dstG.SetLinkage(llvm.ExternalLinkage) + } + e.values[v] = dstG + return dstG, nil + } + return llvm.Value{}, fmt.Errorf("unsupported global ref kind") +} + +func (e *overrideEmitter) cloneGlobalVariable(src llvm.Value) (llvm.Value, error) { + if mapped, ok := e.values[src]; ok { + return mapped, nil + } + name := src.Name() + local := name == "" || isLocalLinkage(src.Linkage()) + if !local { + dst := e.dst.NamedGlobal(name) + if dst.IsNil() { + dst = llvm.AddGlobal(e.dst, src.GlobalValueType(), name) + dst.SetLinkage(llvm.ExternalLinkage) + } + e.values[src] = dst + return dst, nil + } + + dst := llvm.AddGlobal(e.dst, src.GlobalValueType(), "") + e.values[src] = dst + copyGlobalAttrs(dst, src) + dst.SetLinkage(src.Linkage()) + dst.SetGlobalConstant(src.IsGlobalConstant()) + if init := src.Initializer(); !init.IsNil() { + cloneInit, err := e.cloneConst(init) + if err != nil { + return llvm.Value{}, err + } + dst.SetInitializer(cloneInit) + } + return dst, nil +} + +func copyGlobalAttrs(dst, src llvm.Value) { + dst.SetVisibility(src.Visibility()) + if sec := src.Section(); sec != "" { + dst.SetSection(sec) + } + dst.SetThreadLocal(src.IsThreadLocal()) + if align := src.Alignment(); align > 0 { + dst.SetAlignment(align) + } +} + +func isLocalLinkage(l llvm.Linkage) bool { + return l == llvm.PrivateLinkage || l == llvm.InternalLinkage +} + +func constStructOfType(typ llvm.Type, fields []llvm.Value) llvm.Value { + if typ.StructName() != "" { + return llvm.ConstNamedStruct(typ, fields) + } + return llvm.ConstStruct(fields, typ.IsStructPacked()) +} + +func methodArray(init llvm.Value) (llvm.Value, llvm.Type, bool) { + if init.IsNil() || init.OperandsCount() == 0 { + return llvm.Value{}, llvm.Type{}, false + } + methodsVal := init.Operand(init.OperandsCount() - 1) + if methodsVal.Type().TypeKind() != llvm.ArrayTypeKind { + return llvm.Value{}, llvm.Type{}, false + } + elemTy := methodsVal.Type().ElementType() + if elemTy.TypeKind() != llvm.StructTypeKind { + return llvm.Value{}, llvm.Type{}, false + } + if elemTy.StructName() != runtimeABIPrefix+"Method" { + return llvm.Value{}, llvm.Type{}, false + } + if elemTy.StructElementTypesCount() != 4 { + return llvm.Value{}, llvm.Type{}, false + } + return methodsVal, elemTy, true +} diff --git a/internal/build/dce/rewrite_test.go b/internal/build/dce/rewrite_test.go new file mode 100644 index 0000000000..38cf4de00a --- /dev/null +++ b/internal/build/dce/rewrite_test.go @@ -0,0 +1,94 @@ +package dce + +import ( + "testing" + + llvm "github.com/goplus/llvm" +) + +func TestEmitStrongTypeOverrides(t *testing.T) { + ctx := llvm.NewContext() + defer ctx.Dispose() + + src := ctx.NewModule("src") + defer src.Dispose() + dst := ctx.NewModule("dst") + defer dst.Dispose() + + i32 := ctx.Int32Type() + void := ctx.VoidType() + textPtr := llvm.PointerType(void, 0) + + abiType := ctx.StructCreateNamed(runtimeABIPrefix + "Type") + abiType.StructSetBody([]llvm.Type{i32}, false) + uncommonType := ctx.StructCreateNamed(runtimeABIPrefix + "UncommonType") + uncommonType.StructSetBody([]llvm.Type{i32}, false) + methodType := ctx.StructCreateNamed(runtimeABIPrefix + "Method") + methodType.StructSetBody([]llvm.Type{i32, i32, textPtr, textPtr}, false) + + zeroABIType := llvm.ConstNamedStruct(abiType, []llvm.Value{ + llvm.ConstInt(i32, 0, false), + }) + zeroUncommon := llvm.ConstNamedStruct(uncommonType, []llvm.Value{ + llvm.ConstInt(i32, 0, false), + }) + + keepFn := llvm.AddFunction(src, "keep.fn", llvm.FunctionType(void, nil, false)) + dropFn := llvm.AddFunction(src, "drop.fn", llvm.FunctionType(void, nil, false)) + + methods := llvm.ConstArray(methodType, []llvm.Value{ + llvm.ConstNamedStruct(methodType, []llvm.Value{ + llvm.ConstInt(i32, 11, false), + llvm.ConstInt(i32, 21, false), + keepFn, + keepFn, + }), + llvm.ConstNamedStruct(methodType, []llvm.Value{ + llvm.ConstInt(i32, 12, false), + llvm.ConstInt(i32, 22, false), + dropFn, + dropFn, + }), + }) + + typeTType := llvm.StructType([]llvm.Type{abiType, uncommonType, methods.Type()}, false) + typeT := llvm.AddGlobal(src, typeTType, "_llgo_type.T") + typeT.SetInitializer(llvm.ConstNamedStruct(typeTType, []llvm.Value{ + zeroABIType, + zeroUncommon, + methods, + })) + typeT.SetGlobalConstant(true) + typeT.SetLinkage(llvm.WeakODRLinkage) + + result := Result{ + "_llgo_type.T": { + 0: {}, + }, + } + if err := EmitStrongTypeOverrides(dst, []llvm.Module{src}, result); err != nil { + t.Fatalf("EmitStrongTypeOverrides() error = %v", err) + } + + override := dst.NamedGlobal("_llgo_type.T") + if override.IsNil() { + t.Fatal("override type global not emitted") + } + if override.Linkage() != llvm.ExternalLinkage { + t.Fatalf("override linkage = %v, want ExternalLinkage", override.Linkage()) + } + + overrideMethods, _, ok := methodArray(override.Initializer()) + if !ok { + t.Fatal("override initializer missing abi.Method array") + } + if got := overrideMethods.Operand(0).Operand(2).Name(); got != "keep.fn" { + t.Fatalf("keep slot Ifn = %q, want keep.fn", got) + } + if !overrideMethods.Operand(1).Operand(2).IsNull() { + t.Fatalf("dead slot Ifn = %v, want null", overrideMethods.Operand(1).Operand(2)) + } + if !overrideMethods.Operand(1).Operand(3).IsNull() { + t.Fatalf("dead slot Tfn = %v, want null", overrideMethods.Operand(1).Operand(3)) + } +} diff --git a/internal/build/dce/testdata/closureall.txt b/internal/build/dce/testdata/closureall.txt new file mode 100644 index 0000000000..226bdc61ff --- /dev/null +++ b/internal/build/dce/testdata/closureall.txt @@ -0,0 +1,2 @@ +*_llgo_github.com/goplus/llgo/cl/_testgo/closureall.S: [0] +_llgo_github.com/goplus/llgo/cl/_testgo/closureall.S: [] diff --git a/internal/build/dce/testdata/ifaceconv.txt b/internal/build/dce/testdata/ifaceconv.txt new file mode 100644 index 0000000000..ad322fdbd2 --- /dev/null +++ b/internal/build/dce/testdata/ifaceconv.txt @@ -0,0 +1,4 @@ +*_llgo_github.com/goplus/llgo/cl/_testgo/ifaceconv.C1: [] +*_llgo_github.com/goplus/llgo/cl/_testgo/ifaceconv.C2: [] +_llgo_github.com/goplus/llgo/cl/_testgo/ifaceconv.C1: [] +_llgo_github.com/goplus/llgo/cl/_testgo/ifaceconv.C2: [] diff --git a/internal/build/dce/testdata/invoke.txt b/internal/build/dce/testdata/invoke.txt new file mode 100644 index 0000000000..5be442ef1c --- /dev/null +++ b/internal/build/dce/testdata/invoke.txt @@ -0,0 +1,13 @@ +*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T: [0] +*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T1: [0] +*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T2: [0] +*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T3: [0] +*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T4: [0] +*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T5: [0] +*_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T6: [0] +_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T: [0] +_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T1: [0] +_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T2: [0] +_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T4: [0] +_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T5: [0] +_llgo_github.com/goplus/llgo/cl/_testgo/invoke.T6: [0] diff --git a/internal/build/dce/testdata/reader.txt b/internal/build/dce/testdata/reader.txt new file mode 100644 index 0000000000..73608c5ffc --- /dev/null +++ b/internal/build/dce/testdata/reader.txt @@ -0,0 +1,2 @@ +*_llgo_github.com/goplus/llgo/cl/_testgo/reader.errorString: [] +*_llgo_github.com/goplus/llgo/cl/_testgo/reader.stringReader: [1] diff --git a/internal/build/dce/testdata/reflectmethod.txt b/internal/build/dce/testdata/reflectmethod.txt new file mode 100644 index 0000000000..b3e8cb1d45 --- /dev/null +++ b/internal/build/dce/testdata/reflectmethod.txt @@ -0,0 +1,2 @@ +*_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T: [0] +_llgo_github.com/goplus/llgo/cl/_testgo/reflectmethod.T: [0] diff --git a/ssa/abitype.go b/ssa/abitype.go index cb5fd4a98d..294ad09ae7 100644 --- a/ssa/abitype.go +++ b/ssa/abitype.go @@ -197,10 +197,7 @@ func (b Builder) abiInterfaceImethods(t *types.Interface, name string) llvm.Valu for i := 0; i < n; i++ { f := t.Method(i) var values []llvm.Value - name := f.Name() - if !token.IsExported(name) { - name = abi.FullName(f.Pkg(), name) - } + name := mthName(f) values = append(values, b.Str(name).impl) ftyp := funcType(prog, f.Type()) values = append(values, b.abiType(ftyp).impl) @@ -405,6 +402,7 @@ func (b Builder) abiUncommonMethods(t types.Type, mset *types.MethodSet) llvm.Va ft := prog.rtType("Method") n := mset.Len() fields := make([]llvm.Value, n) + typeName, _ := prog.abi.TypeName(t) pkg, _ := b.abiUncommonPkg(t) anonymous := pkg == nil if anonymous { @@ -412,20 +410,21 @@ func (b Builder) abiUncommonMethods(t types.Type, mset *types.MethodSet) llvm.Va } for i := 0; i < n; i++ { m := mset.At(i) - obj := m.Obj() - mName := obj.Name() - name := b.Str(mName).impl - if !token.IsExported(mName) { - name = b.Str(abi.FullName(obj.Pkg(), mName)).impl + obj := m.Obj().(*types.Func) + rawName := obj.Name() + fullName := mthName(obj) + name := b.Str(rawName).impl + if fullName != rawName { + name = b.Str(fullName).impl } mSig := m.Type().(*types.Signature) var tfn, ifn llvm.Value - tfn = b.abiMethodFunc(anonymous, pkg, mName, mSig) + tfn = b.abiMethodFunc(anonymous, pkg, rawName, mSig) ifn = tfn if _, ok := m.Recv().Underlying().(*types.Pointer); !ok { pRecv := types.NewVar(token.NoPos, pkg, "", types.NewPointer(mSig.Recv().Type())) pSig := types.NewSignature(pRecv, mSig.Params(), mSig.Results(), mSig.Variadic()) - ifn = b.abiMethodFunc(anonymous, pkg, mName, pSig) + ifn = b.abiMethodFunc(anonymous, pkg, rawName, pSig) } var values []llvm.Value values = append(values, name) @@ -434,10 +433,20 @@ func (b Builder) abiUncommonMethods(t types.Type, mset *types.MethodSet) llvm.Va values = append(values, ifn) values = append(values, tfn) fields[i] = llvm.ConstNamedStruct(ft.ll, values) + mtypName, _ := prog.abi.TypeName(ftyp) + b.Pkg.emitMethodOff(typeName, i, fullName, mtypName) } return llvm.ConstArray(ft.ll, fields) } +func mthName(method *types.Func) string { + name := method.Name() + if !token.IsExported(name) { + return abi.FullName(method.Pkg(), name) + } + return name +} + // closure func type func funcType(prog Program, typ types.Type) types.Type { ftyp := prog.Type(typ, InGo) diff --git a/ssa/interface.go b/ssa/interface.go index 2b2df13028..ca750b6d8f 100644 --- a/ssa/interface.go +++ b/ssa/interface.go @@ -81,6 +81,15 @@ func (b Builder) Imethod(intf Expr, method *types.Func) Expr { } tclosure := prog.Type(sig, InGo) i := iMethodOf(rawIntf, method.Name()) + ownerName := b.Func.impl.Name() + intfTypeName, _ := prog.abi.TypeName(intf.raw.Type) + mtypName, _ := prog.abi.TypeName(funcType(prog, method.Type())) + b.Pkg.emitUseIfaceMethod( + ownerName, + intfTypeName, + mthName(method), + mtypName, + ) data := b.InlineCall(b.Pkg.rtFunc("IfacePtrData"), intf) impl := intf.impl itab := Expr{b.faceItab(impl), prog.VoidPtrPtr()} @@ -115,6 +124,14 @@ func (b Builder) MakeInterface(tinter Type, x Expr) (ret Expr) { } prog := b.Prog typ := x.Type + // Emit useiface only for concrete-to-interface conversions. If the source + // value is already an interface, this conversion does not expose a new + // concrete type to deadcode analysis. + if _, ok := typ.raw.Type.Underlying().(*types.Interface); !ok { + ownerName := b.Func.impl.Name() + typeName, _ := prog.abi.TypeName(typ.raw.Type) + b.Pkg.emitUseIface(ownerName, typeName) + } tabi := b.abiType(typ.raw.Type) kind, _, lvl := abi.DataKindOf(typ.raw.Type, 0, prog.is32Bits) switch kind { diff --git a/ssa/mdtest/metadata.go b/ssa/mdtest/metadata.go new file mode 100644 index 0000000000..c62c94927c --- /dev/null +++ b/ssa/mdtest/metadata.go @@ -0,0 +1,94 @@ +// Package mdtest provides test-only wrappers that mirror the named metadata +// read APIs we expect to add to github.com/goplus/llvm. Because this package +// cannot add methods to llvm.Module/llvm.Value, it exposes package-level +// helpers with the same data model so callers can later switch to direct +// goplus/llvm APIs with minimal churn. +package mdtest + +/* +#include + +typedef struct LLVMOpaqueModule *LLVMModuleRef; +typedef struct LLVMOpaqueValue *LLVMValueRef; + +unsigned LLVMGetNamedMetadataNumOperands(LLVMModuleRef M, const char *Name); +void LLVMGetNamedMetadataOperands(LLVMModuleRef M, const char *Name, LLVMValueRef *Dest); +unsigned LLVMGetMDNodeNumOperands(LLVMValueRef V); +void LLVMGetMDNodeOperands(LLVMValueRef V, LLVMValueRef *Dest); +const char *LLVMGetMDString(LLVMValueRef V, unsigned *Length); +LLVMValueRef LLVMIsAMDString(LLVMValueRef Val); + +static unsigned llgoNamedMetadataNumOperands(void *M, const char *Name) { + return LLVMGetNamedMetadataNumOperands((LLVMModuleRef)M, Name); +} + +static void llgoNamedMetadataOperands(void *M, const char *Name, LLVMValueRef *Dest) { + LLVMGetNamedMetadataOperands((LLVMModuleRef)M, Name, Dest); +} + +static unsigned llgoMDNodeNumOperands(void *V) { + return LLVMGetMDNodeNumOperands((LLVMValueRef)V); +} + +static void llgoMDNodeOperands(void *V, LLVMValueRef *Dest) { + LLVMGetMDNodeOperands((LLVMValueRef)V, Dest); +} + +static const char *llgoMDString(void *V, unsigned *Length) { + return LLVMGetMDString((LLVMValueRef)V, Length); +} + +static int llgoIsMDString(void *V) { + return LLVMIsAMDString((LLVMValueRef)V) != 0; +} + +*/ +import "C" + +import ( + "unsafe" + + "github.com/goplus/llvm" +) + +func GetNamedMetadataNumOperands(mod llvm.Module, name string) int { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + return int(C.llgoNamedMetadataNumOperands(unsafe.Pointer(mod.C), cname)) +} + +func GetNamedMetadataOperands(mod llvm.Module, name string) []llvm.Value { + n := GetNamedMetadataNumOperands(mod, name) + if n != 0 { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + values := make([]llvm.Value, n) + C.llgoNamedMetadataOperands(unsafe.Pointer(mod.C), cname, (*C.LLVMValueRef)(unsafe.Pointer(&values[0]))) + return values + } + return nil +} + +func GetMDNodeNumOperands(v llvm.Value) int { + return int(C.llgoMDNodeNumOperands(unsafe.Pointer(v.C))) +} + +func GetMDNodeOperands(v llvm.Value) []llvm.Value { + n := GetMDNodeNumOperands(v) + if n != 0 { + values := make([]llvm.Value, n) + C.llgoMDNodeOperands(unsafe.Pointer(v.C), (*C.LLVMValueRef)(unsafe.Pointer(&values[0]))) + return values + } + return nil +} + +func IsAMDString(v llvm.Value) bool { + return C.llgoIsMDString(unsafe.Pointer(v.C)) != 0 +} + +func GetMDString(v llvm.Value) string { + var n C.uint + s := C.llgoMDString(unsafe.Pointer(v.C), &n) + return C.GoStringN(s, C.int(n)) +} diff --git a/ssa/mdtest/metadata_test.go b/ssa/mdtest/metadata_test.go new file mode 100644 index 0000000000..49b057a565 --- /dev/null +++ b/ssa/mdtest/metadata_test.go @@ -0,0 +1,44 @@ +package mdtest + +import ( + "testing" + + "github.com/goplus/llvm" +) + +func TestNamedMetadataReadAPIs(t *testing.T) { + ctx := llvm.NewContext() + mod := ctx.NewModule("m") + mod.AddNamedMetadataOperand("llgo.test", ctx.MDNode([]llvm.Metadata{ + ctx.MDString("owner"), + llvm.ConstInt(ctx.Int32Type(), 7, false).ConstantAsMetadata(), + ctx.MDString("name"), + })) + + if got := GetNamedMetadataNumOperands(mod, "llgo.test"); got != 1 { + t.Fatalf("GetNamedMetadataNumOperands = %d, want 1", got) + } + rows := GetNamedMetadataOperands(mod, "llgo.test") + if len(rows) != 1 { + t.Fatalf("GetNamedMetadataOperands len = %d, want 1", len(rows)) + } + fields := GetMDNodeOperands(rows[0]) + if len(fields) != 3 { + t.Fatalf("GetMDNodeOperands len = %d, want 3", len(fields)) + } + if !IsAMDString(fields[0]) { + t.Fatal("field[0] should be MDString") + } + if got := GetMDString(fields[0]); got != "owner" { + t.Fatalf("GetMDString(field[0]) = %q, want %q", got, "owner") + } + if got := fields[1].ZExtValue(); got != 7 { + t.Fatalf("ConstIntGetZExtValue(field[1]) = %d, want 7", got) + } + if !IsAMDString(fields[2]) { + t.Fatal("field[2] should be MDString") + } + if got := GetMDString(fields[2]); got != "name" { + t.Fatalf("GetMDString(field[2]) = %q, want %q", got, "name") + } +} diff --git a/ssa/metadata.go b/ssa/metadata.go new file mode 100644 index 0000000000..72b530b135 --- /dev/null +++ b/ssa/metadata.go @@ -0,0 +1,146 @@ +package ssa + +import ( + "go/token" + "strconv" + "strings" + + "github.com/goplus/llvm" +) + +const ( + // llgoUseIfaceMetadata is a module-level named metadata table whose rows are + // {owner name, concrete type name}. Each row means that if the named owner + // function is reachable, the named concrete type should enter the UsedInIface + // semantic state during deadcode analysis. Metadata stores only symbol names + // so emission does not force extra LLVM globals into the module. + llgoUseIfaceMetadata = "llgo.useiface" + // llgoUseIfaceMethodMetadata is a module-level named metadata table whose + // rows are {owner name, interface type name, normalized method name, mtyp + // name}. Each row means that if the named owner function is reachable, the + // referenced interface method demand should participate in later method + // matching. + llgoUseIfaceMethodMetadata = "llgo.useifacemethod" + // llgoMethodOffMetadata is a module-level named metadata table whose rows are + // {concrete type name, method index, normalized method name, mtyp name}. Each + // row describes one concrete method candidate in the canonical abi.Method + // order. + llgoMethodOffMetadata = "llgo.methodoff" + // llgoUseNamedMethodMetadata is a module-level named metadata table whose + // rows are {owner name, normalized method name}. Each row means that if the + // named owner function is reachable, deadcode analysis should treat the named + // method as requested by MethodByName-like semantics. + llgoUseNamedMethodMetadata = "llgo.usenamedmethod" + // llgoReflectMethodMetadata is a module-level named metadata table whose rows + // are {owner name}. Each row means that if the named owner function is + // reachable, deadcode analysis should conservatively keep reachable exported + // methods for reflection-driven method lookup. + llgoReflectMethodMetadata = "llgo.reflectmethod" +) + +type semMetaEmitter struct { + seen map[string]struct{} +} + +func newSemMetaEmitter() *semMetaEmitter { + return &semMetaEmitter{ + seen: make(map[string]struct{}), + } +} + +func (e *semMetaEmitter) add(mod llvm.Module, table, key string, fields ...llvm.Metadata) { + fullKey := table + ":" + key + if _, ok := e.seen[fullKey]; ok { + return + } + e.seen[fullKey] = struct{}{} + mod.AddNamedMetadataOperand(table, mod.Context().MDNode(fields)) +} + +func metadataKey(parts ...string) string { + return strings.Join(parts, ":") +} + +func metadataString(ctx llvm.Context, s string) llvm.Metadata { + return ctx.MDString(s) +} + +func metadataInt32(ctx llvm.Context, i int) llvm.Metadata { + return llvm.ConstInt(ctx.Int32Type(), uint64(i), false).ConstantAsMetadata() +} + +func (p Package) emitUseIface(owner, target string) { + ctx := p.mod.Context() + p.semMetaEmitter.add( + p.mod, + llgoUseIfaceMetadata, + metadataKey(owner, target), + metadataString(ctx, owner), + metadataString(ctx, target), + ) +} + +func (p Package) emitUseIfaceMethod(owner, target, name, mtyp string) { + ctx := p.mod.Context() + p.semMetaEmitter.add( + p.mod, + llgoUseIfaceMethodMetadata, + metadataKey(owner, target, name, mtyp), + metadataString(ctx, owner), + metadataString(ctx, target), + metadataString(ctx, name), + metadataString(ctx, mtyp), + ) +} + +func (p Package) emitMethodOff(owner string, index int, name, mtyp string) { + if owner == "" || name == "" || mtyp == "" { + return + } + ctx := p.mod.Context() + p.semMetaEmitter.add( + p.mod, + llgoMethodOffMetadata, + metadataKey(owner, strconv.Itoa(index), name, mtyp), + metadataString(ctx, owner), + metadataInt32(ctx, index), + metadataString(ctx, name), + metadataString(ctx, mtyp), + ) +} + +func (p Package) emitUseNamedMethod(owner, name string) { + if !token.IsExported(name) && p.Path() != "" { + name = p.Path() + "." + name + } + ctx := p.mod.Context() + p.semMetaEmitter.add( + p.mod, + llgoUseNamedMethodMetadata, + metadataKey(owner, name), + metadataString(ctx, owner), + metadataString(ctx, name), + ) +} + +func (p Package) emitReflectMethod(owner string) { + ctx := p.mod.Context() + p.semMetaEmitter.add( + p.mod, + llgoReflectMethodMetadata, + owner, + metadataString(ctx, owner), + ) +} + +// EmitUseNamedMethod records a MethodByName-like exact method-name demand for +// later whole-program deadcode analysis. +func (p Package) EmitUseNamedMethod(owner, name string) { + p.emitUseNamedMethod(owner, name) +} + +// EmitReflectMethod records a conservative reflection marker for later +// whole-program deadcode analysis. +func (p Package) EmitReflectMethod(owner string) { + p.emitReflectMethod(owner) +} diff --git a/ssa/package.go b/ssa/package.go index 492ff4317d..09393741ea 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -458,7 +458,10 @@ func (p Program) NewPackage(name, pkgPath string) Package { ret := &aPackage{ mod: mod, path: pkgPath, Prog: p, vars: gbls, fns: fns, pyobjs: pyobjs, pymods: pymods, strs: strs, - di: nil, cu: nil, glbDbgVars: glbDbgVars, + semMetaEmitter: newSemMetaEmitter(), + di: nil, + cu: nil, + glbDbgVars: glbDbgVars, export: make(map[string]string), preserveSyms: make(map[string]struct{}), llvmUsedValues: make([]llvm.Value, 0, 4), @@ -705,7 +708,8 @@ type aPackage struct { mod llvm.Module path string - Prog Program + Prog Program + semMetaEmitter *semMetaEmitter di diBuilder cu CompilationUnit diff --git a/ssa/ssa_test.go b/ssa/ssa_test.go index b48bf949d1..6f23460e87 100644 --- a/ssa/ssa_test.go +++ b/ssa/ssa_test.go @@ -33,6 +33,7 @@ import ( "unsafe" "github.com/goplus/gogen/packages" + "github.com/goplus/llgo/ssa/mdtest" "github.com/goplus/llvm" ) @@ -439,6 +440,7 @@ func TestIfaceMethodClosureCallIR(t *testing.T) { rawIface := types.NewInterfaceType([]*types.Func{rawMeth}, nil) rawIface.Complete() namedIface := types.NewNamed(types.NewTypeName(0, pkgTypes, "IFmt", nil), rawIface, nil) + pkgTypes.Scope().Insert(namedIface.Obj()) recv := types.NewVar(0, pkgTypes, "recv", namedIface) recvSig := types.NewSignatureType(recv, nil, nil, types.NewTuple(VArg()), types.NewTuple(types.NewVar(0, nil, "", types.Typ[types.Int])), true) @@ -474,7 +476,139 @@ _llgo_0: } declare ptr @"github.com/goplus/llgo/runtime/internal/runtime.IfacePtrData"(%"github.com/goplus/llgo/runtime/internal/runtime.iface") + +!llgo.useifacemethod = !{!0} + +!0 = !{!"caller", !"_llgo_foo/bar.IFmt", !"Printf", !"_llgo_func$_RYiBYcSxJjuvzYmA4xYm18hT18pH0_ng6z76aK77Bk"} `) + + useIfaceMethodRows := mdtest.GetNamedMetadataOperands(pkg.Module(), llgoUseIfaceMethodMetadata) + requireMetadataRows(t, llgoUseIfaceMethodMetadata, useIfaceMethodRows, 1) + useIfaceMethodFields := requireMetadataFields(t, llgoUseIfaceMethodMetadata, useIfaceMethodRows[0], 4) + requireMDString(t, llgoUseIfaceMethodMetadata, useIfaceMethodFields, 0, "caller") + requireMDString(t, llgoUseIfaceMethodMetadata, useIfaceMethodFields, 1, "_llgo_foo/bar.IFmt") + requireMDString(t, llgoUseIfaceMethodMetadata, useIfaceMethodFields, 2, "Printf") + requireMDString(t, llgoUseIfaceMethodMetadata, useIfaceMethodFields, 3, "_llgo_func$_RYiBYcSxJjuvzYmA4xYm18hT18pH0_ng6z76aK77Bk") +} + +func TestNamedMetadataReadback(t *testing.T) { + prog := NewProgram(nil) + prog.sizes = types.SizesFor("gc", runtime.GOARCH) + prog.SetRuntime(func() *types.Package { + pkg, err := importer.For("source", nil).Import(PkgRuntime) + if err != nil { + t.Fatal(err) + } + return pkg + }) + + pkgTypes := types.NewPackage("foo/bar", "bar") + + rawIfaceSig := types.NewSignatureType(nil, nil, nil, + types.NewTuple(types.NewVar(0, nil, "x", types.Typ[types.Int])), + types.NewTuple(types.NewVar(0, nil, "", types.Typ[types.Int])), + false) + rawIfaceMeth := types.NewFunc(0, pkgTypes, "Add", rawIfaceSig) + rawIface := types.NewInterfaceType([]*types.Func{rawIfaceMeth}, nil) + rawIface.Complete() + + namedIface := types.NewNamed(types.NewTypeName(0, pkgTypes, "IFmt", nil), rawIface, nil) + pkgTypes.Scope().Insert(namedIface.Obj()) + + ifaceRecv := types.NewVar(0, pkgTypes, "recv", namedIface) + ifaceMethSig := types.NewSignatureType(ifaceRecv, nil, nil, + types.NewTuple(types.NewVar(0, nil, "x", types.Typ[types.Int])), + types.NewTuple(types.NewVar(0, nil, "", types.Typ[types.Int])), + false) + ifaceMeth := types.NewFunc(0, pkgTypes, "Add", ifaceMethSig) + + namedStruct := types.NewNamed(types.NewTypeName(0, pkgTypes, "S", nil), types.NewStruct(nil, nil), nil) + pkgTypes.Scope().Insert(namedStruct.Obj()) + structRecv := types.NewVar(0, pkgTypes, "recv", types.NewPointer(namedStruct)) + structMethSig := types.NewSignatureType(structRecv, nil, nil, + types.NewTuple(types.NewVar(0, nil, "x", types.Typ[types.Int])), + types.NewTuple(types.NewVar(0, nil, "", types.Typ[types.Int])), + false) + structMeth := types.NewFunc(0, pkgTypes, "Add", structMethSig) + namedStruct.AddMethod(structMeth) + + pkg := prog.NewPackage("bar", "foo/bar") + caller := pkg.NewFunc("caller", types.NewSignatureType(nil, nil, nil, nil, + types.NewTuple(types.NewVar(0, nil, "", types.Typ[types.Int])), false), InGo) + b := caller.MakeBody(1) + ptrType := prog.Type(types.NewPointer(namedStruct), InGo) + ifaceType := prog.Type(namedIface, InGo) + x := prog.Zero(ptrType) + intf := b.MakeInterface(ifaceType, x) + closure := b.Imethod(intf, ifaceMeth) + b.Return(b.Call(closure, prog.Val(1))) + + mtypName, _ := prog.abi.TypeName(funcType(prog, structMeth.Type())) + structTypeName, _ := prog.abi.TypeName(types.NewPointer(namedStruct)) + ifaceTypeName, _ := prog.abi.TypeName(namedIface) + + useIfaceRows := mdtest.GetNamedMetadataOperands(pkg.Module(), llgoUseIfaceMetadata) + requireMetadataRows(t, llgoUseIfaceMetadata, useIfaceRows, 1) + useIfaceFields := requireMetadataFields(t, llgoUseIfaceMetadata, useIfaceRows[0], 2) + requireMDString(t, llgoUseIfaceMetadata, useIfaceFields, 0, "caller") + requireMDString(t, llgoUseIfaceMetadata, useIfaceFields, 1, structTypeName) + + methodOffRows := mdtest.GetNamedMetadataOperands(pkg.Module(), llgoMethodOffMetadata) + requireMetadataRows(t, llgoMethodOffMetadata, methodOffRows, 1) + methodOffFields := requireMetadataFields(t, llgoMethodOffMetadata, methodOffRows[0], 4) + requireMDString(t, llgoMethodOffMetadata, methodOffFields, 0, structTypeName) + requireMDUint(t, llgoMethodOffMetadata, methodOffFields, 1, 0) + requireMDString(t, llgoMethodOffMetadata, methodOffFields, 2, "Add") + requireMDString(t, llgoMethodOffMetadata, methodOffFields, 3, mtypName) + + useIfaceMethodRows := mdtest.GetNamedMetadataOperands(pkg.Module(), llgoUseIfaceMethodMetadata) + requireMetadataRows(t, llgoUseIfaceMethodMetadata, useIfaceMethodRows, 1) + useIfaceMethodFields := requireMetadataFields(t, llgoUseIfaceMethodMetadata, useIfaceMethodRows[0], 4) + requireMDString(t, llgoUseIfaceMethodMetadata, useIfaceMethodFields, 0, "caller") + requireMDString(t, llgoUseIfaceMethodMetadata, useIfaceMethodFields, 1, ifaceTypeName) + requireMDString(t, llgoUseIfaceMethodMetadata, useIfaceMethodFields, 2, "Add") + requireMDString(t, llgoUseIfaceMethodMetadata, useIfaceMethodFields, 3, mtypName) +} + +func requireMetadataRows(t *testing.T, table string, rows []llvm.Value, want int) { + t.Helper() + if got := len(rows); got != want { + t.Fatalf("%s rows len = %d, want %d", table, got, want) + } +} + +func requireMetadataFields(t *testing.T, table string, row llvm.Value, want int) []llvm.Value { + t.Helper() + fields := mdtest.GetMDNodeOperands(row) + if got := len(fields); got != want { + t.Fatalf("%s field len = %d, want %d", table, got, want) + } + return fields +} + +func requireMDString(t *testing.T, table string, fields []llvm.Value, index int, want string) { + t.Helper() + if index >= len(fields) { + t.Fatalf("%s field index %d out of range", table, index) + } + if !mdtest.IsAMDString(fields[index]) { + t.Fatalf("%s field[%d] should be MDString", table, index) + } + got := mdtest.GetMDString(fields[index]) + if got != want { + t.Fatalf("%s field[%d] string = %q, want %q", table, index, got, want) + } +} + +func requireMDUint(t *testing.T, table string, fields []llvm.Value, index int, want uint64) { + t.Helper() + if index >= len(fields) { + t.Fatalf("%s field index %d out of range", table, index) + } + got := fields[index].ZExtValue() + if got != want { + t.Fatalf("%s field[%d] uint = %d, want %d", table, index, got, want) + } } func TestClosureCtxHelpers(t *testing.T) {