Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(15)

Side by Side Diff: src/cmd/5g/ggen.c

Issue 92760044: code review 92760044: runtime: use duff zero and copy to initialize memory (Closed)
Patch Set: diff -r a6cb2adc55eb https://khr%40golang.org@code.google.com/p/go/ Created 10 years, 11 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/cmd/5g/cgen.c ('k') | src/cmd/5g/peep.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 #undef EXTERN 5 #undef EXTERN
6 #define EXTERN 6 #define EXTERN
7 #include <u.h> 7 #include <u.h>
8 #include <libc.h> 8 #include <libc.h>
9 #include "gg.h" 9 #include "gg.h"
10 #include "opt.h" 10 #include "opt.h"
11 11
12 static Prog* appendpp(Prog*, int, int, int, int32, int, int, int32); 12 static Prog* appendpp(Prog*, int, int, int, int32, int, int, int32);
13 static Prog *zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *r0);
13 14
14 void 15 void
15 defframe(Prog *ptxt) 16 defframe(Prog *ptxt)
16 { 17 {
17 » uint32 frame; 18 » uint32 frame, r0;
18 » Prog *p, *p1; 19 » Prog *p;
20 » vlong hi, lo;
19 NodeList *l; 21 NodeList *l;
20 Node *n; 22 Node *n;
21 vlong i;
22 23
23 // fill in argument size 24 // fill in argument size
24 ptxt->to.type = D_CONST2; 25 ptxt->to.type = D_CONST2;
25 ptxt->to.offset2 = rnd(curfn->type->argwid, widthptr); 26 ptxt->to.offset2 = rnd(curfn->type->argwid, widthptr);
26 27
27 // fill in final stack size 28 // fill in final stack size
28 frame = rnd(stksize+maxarg, widthptr); 29 frame = rnd(stksize+maxarg, widthptr);
29 ptxt->to.offset = frame; 30 ptxt->to.offset = frame;
30 ········ 31 ········
31 // insert code to contain ambiguously live variables 32 // insert code to contain ambiguously live variables
32 // so that garbage collector only sees initialized values 33 // so that garbage collector only sees initialized values
33 // when it looks for pointers. 34 // when it looks for pointers.
34 //
35 // TODO: determine best way to zero the given values.
36 // among other problems, R0 is initialized to 0 multiple times,
37 // but that's really the tip of the iceberg.
38 p = ptxt; 35 p = ptxt;
36 lo = hi = 0;
37 r0 = 0;
39 for(l=curfn->dcl; l != nil; l = l->next) { 38 for(l=curfn->dcl; l != nil; l = l->next) {
40 n = l->n; 39 n = l->n;
41 if(!n->needzero) 40 if(!n->needzero)
42 continue; 41 continue;
43 if(n->class != PAUTO) 42 if(n->class != PAUTO)
44 fatal("needzero class %d", n->class); 43 fatal("needzero class %d", n->class);
45 if(n->type->width % widthptr != 0 || n->xoffset % widthptr != 0 || n->type->width == 0) 44 if(n->type->width % widthptr != 0 || n->xoffset % widthptr != 0 || n->type->width == 0)
46 fatal("var %lN has size %d offset %d", n, (int)n->type-> width, (int)n->xoffset); 45 fatal("var %lN has size %d offset %d", n, (int)n->type-> width, (int)n->xoffset);
47 » » if(n->type->width <= 8*widthptr) { 46 » » if(lo != hi && n->xoffset + n->type->width >= lo - 2*widthptr) {
48 » » » p = appendpp(p, AMOVW, D_CONST, NREG, 0, D_REG, 0, 0); 47 » » » // merge with range we already have
49 » » » for(i = 0; i < n->type->width; i += widthptr)· 48 » » » lo = rnd(n->xoffset, widthptr);
50 » » » » p = appendpp(p, AMOVW, D_REG, 0, 0, D_OREG, REGS P, 4+frame+n->xoffset+i); 49 » » » continue;
51 » » } else {
52 » » » p = appendpp(p, AMOVW, D_CONST, NREG, 0, D_REG, 0, 0);
53 » » » p = appendpp(p, AADD, D_CONST, NREG, 4+frame+n->xoffset, D_REG, 1, 0);
54 » » » p->reg = REGSP;»
55 » » » p = appendpp(p, AADD, D_CONST, NREG, n->type->width, D_R EG, 2, 0);»·····
56 » » » p->reg = 1;»····
57 » » » p1 = p = appendpp(p, AMOVW, D_REG, 0, 0, D_OREG, 1, 4);»
58 » » » p->scond |= C_PBIT;»····
59 » » » p = appendpp(p, ACMP, D_REG, 1, 0, D_NONE, 0, 0);»······
60 » » » p->reg = 2;»····
61 » » » p = appendpp(p, ABNE, D_NONE, NREG, 0, D_BRANCH, NREG, 0 );»·····
62 » » » patch(p, p1);
63 } 50 }
64 » }»······ 51 » » // zero old range
52 » » p = zerorange(p, frame, lo, hi, &r0);
53
54 » » // set new range
55 » » hi = n->xoffset + n->type->width;
56 » » lo = n->xoffset;
57 » }
58 » // zero final range
59 » zerorange(p, frame, lo, hi, &r0);
60 }
61
62 static Prog*
63 zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *r0)
64 {
65 » vlong cnt, i;
66 » Prog *p1;
67 » Node *f;
68
69 » cnt = hi - lo;
70 » if(cnt == 0)
71 » » return p;
72 » if(*r0 == 0) {
73 » » p = appendpp(p, AMOVW, D_CONST, NREG, 0, D_REG, 0, 0);
74 » » *r0 = 1;
75 » }
76 » if(cnt < 4*widthptr) {
77 » » for(i = 0; i < cnt; i += widthptr)·
78 » » » p = appendpp(p, AMOVW, D_REG, 0, 0, D_OREG, REGSP, 4+fra me+lo+i);
79 » } else if(cnt <= 128*widthptr) {
80 » » p = appendpp(p, AADD, D_CONST, NREG, 4+frame+lo, D_REG, 1, 0);
81 » » p->reg = REGSP;
82 » » p = appendpp(p, ADUFFZERO, D_NONE, NREG, 0, D_OREG, NREG, 0);
83 » » f = sysfunc("duffzero");
84 » » naddr(f, &p->to, 1);
85 » » afunclit(&p->to, f);
86 » » p->to.offset = 4*(128-cnt/widthptr);
87 » } else {
88 » » p = appendpp(p, AADD, D_CONST, NREG, 4+frame+lo, D_REG, 1, 0);
89 » » p->reg = REGSP;
90 » » p = appendpp(p, AADD, D_CONST, NREG, cnt, D_REG, 2, 0);
91 » » p->reg = 1;
92 » » p1 = p = appendpp(p, AMOVW, D_REG, 0, 0, D_OREG, 1, 4);
93 » » p->scond |= C_PBIT;
94 » » p = appendpp(p, ACMP, D_REG, 1, 0, D_NONE, 0, 0);
95 » » p->reg = 2;
96 » » p = appendpp(p, ABNE, D_NONE, NREG, 0, D_BRANCH, NREG, 0);
97 » » patch(p, p1);
98 » }
99 » return p;
65 } 100 }
66 101
67 static Prog*···· 102 static Prog*····
68 appendpp(Prog *p, int as, int ftype, int freg, int32 foffset, int ttype, int tre g, int32 toffset)······· 103 appendpp(Prog *p, int as, int ftype, int freg, int32 foffset, int ttype, int tre g, int32 toffset)·······
69 {······· 104 {·······
70 Prog *q;········ 105 Prog *q;········
71 ················ 106 ················
72 q = mal(sizeof(*q));···· 107 q = mal(sizeof(*q));····
73 clearp(q);······ 108 clearp(q);······
74 q->as = as;····· 109 q->as = as;·····
(...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after
822 gmove(&n2, res); 857 gmove(&n2, res);
823 858
824 regfree(&n1); 859 regfree(&n1);
825 regfree(&n2); 860 regfree(&n2);
826 } 861 }
827 862
828 void 863 void
829 clearfat(Node *nl) 864 clearfat(Node *nl)
830 { 865 {
831 uint32 w, c, q; 866 uint32 w, c, q;
832 » Node dst, nc, nz, end; 867 » Node dst, nc, nz, end, r0, r1, *f;
833 Prog *p, *pl; 868 Prog *p, *pl;
834 869
835 /* clear a fat object */ 870 /* clear a fat object */
836 if(debug['g']) 871 if(debug['g'])
837 dump("\nclearfat", nl); 872 dump("\nclearfat", nl);
838 873
839 w = nl->type->width; 874 w = nl->type->width;
840 // Avoid taking the address for simple enough types. 875 // Avoid taking the address for simple enough types.
841 if(componentgen(N, nl)) 876 if(componentgen(N, nl))
842 return; 877 return;
843 878
844 c = w % 4; // bytes 879 c = w % 4; // bytes
845 q = w / 4; // quads 880 q = w / 4; // quads
846 881
847 » regalloc(&dst, types[tptr], N); 882 » r0.op = OREGISTER;
883 » r0.val.u.reg = REGALLOC_R0;
884 » r1.op = OREGISTER;
885 » r1.val.u.reg = REGALLOC_R0 + 1;
886 » regalloc(&dst, types[tptr], &r1);
848 agen(nl, &dst); 887 agen(nl, &dst);
849 nodconst(&nc, types[TUINT32], 0); 888 nodconst(&nc, types[TUINT32], 0);
850 » regalloc(&nz, types[TUINT32], 0); 889 » regalloc(&nz, types[TUINT32], &r0);
851 cgen(&nc, &nz); 890 cgen(&nc, &nz);
852 891
853 » if(q >= 4) { 892 » if(q > 128) {
854 regalloc(&end, types[tptr], N); 893 regalloc(&end, types[tptr], N);
855 p = gins(AMOVW, &dst, &end); 894 p = gins(AMOVW, &dst, &end);
856 p->from.type = D_CONST; 895 p->from.type = D_CONST;
857 p->from.offset = q*4; 896 p->from.offset = q*4;
858 897
859 p = gins(AMOVW, &nz, &dst); 898 p = gins(AMOVW, &nz, &dst);
860 p->to.type = D_OREG; 899 p->to.type = D_OREG;
861 p->to.offset = 4; 900 p->to.offset = 4;
862 p->scond |= C_PBIT; 901 p->scond |= C_PBIT;
863 pl = p; 902 pl = p;
864 903
865 p = gins(ACMP, &dst, N); 904 p = gins(ACMP, &dst, N);
866 raddr(&end, p); 905 raddr(&end, p);
867 patch(gbranch(ABNE, T, 0), pl); 906 patch(gbranch(ABNE, T, 0), pl);
868 907
869 regfree(&end); 908 regfree(&end);
909 } else if(q >= 4) {
910 f = sysfunc("duffzero");
911 p = gins(ADUFFZERO, N, f);
912 afunclit(&p->to, f);
913 // 4 and 128 = magic constants: see ../../pkg/runtime/asm_arm.s
914 p->to.offset = 4*(128-q);
870 } else 915 } else
871 while(q > 0) { 916 while(q > 0) {
872 p = gins(AMOVW, &nz, &dst); 917 p = gins(AMOVW, &nz, &dst);
873 p->to.type = D_OREG; 918 p->to.type = D_OREG;
874 p->to.offset = 4; 919 p->to.offset = 4;
875 p->scond |= C_PBIT; 920 p->scond |= C_PBIT;
876 //print("1. %P\n", p); 921 //print("1. %P\n", p);
877 q--; 922 q--;
878 } 923 }
879 924
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 p1->to.reg = reg; 966 p1->to.reg = reg;
922 p1->to.offset = 0; 967 p1->to.offset = 0;
923 p1->scond = C_SCOND_EQ; 968 p1->scond = C_SCOND_EQ;
924 p->as = ACMP; 969 p->as = ACMP;
925 p->from.type = D_CONST; 970 p->from.type = D_CONST;
926 p->from.reg = NREG; 971 p->from.reg = NREG;
927 p->from.offset = 0; 972 p->from.offset = 0;
928 p->reg = reg; 973 p->reg = reg;
929 } 974 }
930 } 975 }
OLDNEW
« no previous file with comments | « src/cmd/5g/cgen.c ('k') | src/cmd/5g/peep.c » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b