LEFT | RIGHT |
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 /* | 5 /* |
6 * portable half of code generator. | 6 * portable half of code generator. |
7 * mainly statements and control flow. | 7 * mainly statements and control flow. |
8 */ | 8 */ |
9 | 9 |
10 #include "go.h" | 10 #include "go.h" |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 n = l->n; | 48 n = l->n; |
49 if(n->op == ONAME && n->class == PHEAP-1) { | 49 if(n->op == ONAME && n->class == PHEAP-1) { |
50 // heap address variable; finish the job | 50 // heap address variable; finish the job |
51 // started in addrescapes. | 51 // started in addrescapes. |
52 s = n->sym; | 52 s = n->sym; |
53 tempname(n, n->type); | 53 tempname(n, n->type); |
54 n->sym = s; | 54 n->sym = s; |
55 } | 55 } |
56 if(n->op != ONAME || n->class != PAUTO) | 56 if(n->op != ONAME || n->class != PAUTO) |
57 continue; | 57 continue; |
58 » » if (n->xoffset != BADWIDTH) | 58 » » if(n->xoffset != BADWIDTH) |
59 continue; | 59 continue; |
60 if(n->type == T) | 60 if(n->type == T) |
61 continue; | 61 continue; |
62 dowidth(n->type); | 62 dowidth(n->type); |
63 w = n->type->width; | 63 w = n->type->width; |
64 if(w >= MAXWIDTH) | 64 if(w >= MAXWIDTH) |
65 fatal("bad width"); | 65 fatal("bad width"); |
66 stksize += w; | 66 stksize += w; |
67 stksize = rnd(stksize, n->type->align); | 67 stksize = rnd(stksize, n->type->align); |
68 if(thechar == '5') | 68 if(thechar == '5') |
(...skipping 12 matching lines...) Expand all Loading... |
81 addrescapes(Node *n) | 81 addrescapes(Node *n) |
82 { | 82 { |
83 char buf[100]; | 83 char buf[100]; |
84 switch(n->op) { | 84 switch(n->op) { |
85 default: | 85 default: |
86 // probably a type error already. | 86 // probably a type error already. |
87 // dump("addrescapes", n); | 87 // dump("addrescapes", n); |
88 break; | 88 break; |
89 | 89 |
90 case ONAME: | 90 case ONAME: |
91 » » if (n == nodfp) | 91 » » if(n == nodfp) |
92 break; | 92 break; |
93 | 93 |
94 // if this is a tmpname (PAUTO), it was tagged by tmpname as not
escaping. | 94 // if this is a tmpname (PAUTO), it was tagged by tmpname as not
escaping. |
95 // on PPARAM it means something different. | 95 // on PPARAM it means something different. |
96 » » if (n->class == PAUTO && n->noescape) | 96 » » if(n->class == PAUTO && n->esc == EscNever) |
97 » » » break; | 97 » » » break; |
98 | 98 |
99 » » if (!debug['s'] && n->noescape) | 99 » » if(!debug['s'] && n->esc != EscUnknown) |
100 » » » fatal("without escape analysis, only PAUTO's should have
noescape: %N", n); | 100 » » » fatal("without escape analysis, only PAUTO's should have
esc: %N", n); |
101 | 101 |
102 switch(n->class) { | 102 switch(n->class) { |
103 case PPARAMREF: | 103 case PPARAMREF: |
104 addrescapes(n->defn); | 104 addrescapes(n->defn); |
105 break; | 105 break; |
106 case PPARAM: | 106 case PPARAM: |
107 case PPARAMOUT: | 107 case PPARAMOUT: |
108 // if func param, need separate temporary | 108 // if func param, need separate temporary |
109 // to hold heap pointer. | 109 // to hold heap pointer. |
110 // the function type has already been checked | 110 // the function type has already been checked |
111 // (we're in the function body) | 111 // (we're in the function body) |
112 // so the param already has a valid xoffset. | 112 // so the param already has a valid xoffset. |
113 | 113 |
114 // expression to refer to stack copy | 114 // expression to refer to stack copy |
115 n->stackparam = nod(OPARAM, n, N); | 115 n->stackparam = nod(OPARAM, n, N); |
116 n->stackparam->type = n->type; | 116 n->stackparam->type = n->type; |
117 n->stackparam->addable = 1; | 117 n->stackparam->addable = 1; |
118 if(n->xoffset == BADWIDTH) | 118 if(n->xoffset == BADWIDTH) |
119 fatal("addrescapes before param assignment"); | 119 fatal("addrescapes before param assignment"); |
120 n->stackparam->xoffset = n->xoffset; | 120 n->stackparam->xoffset = n->xoffset; |
121 n->xoffset = 0; | |
122 // fallthrough | 121 // fallthrough |
123 case PAUTO: | 122 case PAUTO: |
124 | 123 |
125 n->class |= PHEAP; | 124 n->class |= PHEAP; |
126 n->addable = 0; | 125 n->addable = 0; |
127 n->ullman = 2; | 126 n->ullman = 2; |
128 n->xoffset = 0; | 127 n->xoffset = 0; |
129 | 128 |
130 // create stack variable to hold pointer to heap | 129 // create stack variable to hold pointer to heap |
131 n->heapaddr = nod(ONAME, N, N); | 130 n->heapaddr = nod(ONAME, N, N); |
132 n->heapaddr->type = ptrto(n->type); | 131 n->heapaddr->type = ptrto(n->type); |
133 snprint(buf, sizeof buf, "&%S", n->sym); | 132 snprint(buf, sizeof buf, "&%S", n->sym); |
134 n->heapaddr->sym = lookup(buf); | 133 n->heapaddr->sym = lookup(buf); |
135 n->heapaddr->class = PHEAP-1; // defer tempname to all
ocparams | 134 n->heapaddr->class = PHEAP-1; // defer tempname to all
ocparams |
136 n->heapaddr->ullman = 1; | 135 n->heapaddr->ullman = 1; |
137 n->curfn->dcl = list(n->curfn->dcl, n->heapaddr); | 136 n->curfn->dcl = list(n->curfn->dcl, n->heapaddr); |
138 | 137 |
139 » » » if (debug['m']) | 138 » » » if(debug['s']) |
140 » » » » print("%L: moved to heap: %N\n", n->lineno, n); | 139 » » » » n->esc = EscHeap; |
| 140 |
| 141 » » » if(debug['m']) |
| 142 » » » » print("%L: moved to heap: %hN\n", n->lineno, n); |
141 | 143 |
142 break; | 144 break; |
143 } | 145 } |
144 break; | 146 break; |
145 | 147 |
146 case OIND: | 148 case OIND: |
147 case ODOTPTR: | 149 case ODOTPTR: |
148 break; | 150 break; |
149 | 151 |
150 case ODOT: | 152 case ODOT: |
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 void | 836 void |
835 tempname(Node *nn, Type *t) | 837 tempname(Node *nn, Type *t) |
836 { | 838 { |
837 Node *n; | 839 Node *n; |
838 Sym *s; | 840 Sym *s; |
839 uint32 w; | 841 uint32 w; |
840 | 842 |
841 if(stksize < 0) | 843 if(stksize < 0) |
842 fatal("tempname not during code generation"); | 844 fatal("tempname not during code generation"); |
843 | 845 |
844 » if (curfn == N) | 846 » if(curfn == N) |
845 fatal("no curfn for tempname"); | 847 fatal("no curfn for tempname"); |
846 | 848 |
847 if(t == T) { | 849 if(t == T) { |
848 yyerror("tempname called with nil type"); | 850 yyerror("tempname called with nil type"); |
849 t = types[TINT32]; | 851 t = types[TINT32]; |
850 } | 852 } |
851 | 853 |
852 // give each tmp a different name so that there | 854 // give each tmp a different name so that there |
853 // a chance to registerizer them | 855 // a chance to registerizer them |
854 snprint(namebuf, sizeof(namebuf), "autotmp_%.4d", statuniqgen); | 856 snprint(namebuf, sizeof(namebuf), "autotmp_%.4d", statuniqgen); |
855 statuniqgen++; | 857 statuniqgen++; |
856 s = lookup(namebuf); | 858 s = lookup(namebuf); |
857 n = nod(ONAME, N, N); | 859 n = nod(ONAME, N, N); |
858 n->sym = s; | 860 n->sym = s; |
859 n->type = t; | 861 n->type = t; |
860 n->class = PAUTO; | 862 n->class = PAUTO; |
861 n->addable = 1; | 863 n->addable = 1; |
862 n->ullman = 1; | 864 n->ullman = 1; |
863 » n->noescape = 1; | 865 » n->esc = EscNever; |
864 n->curfn = curfn; | 866 n->curfn = curfn; |
865 curfn->dcl = list(curfn->dcl, n); | 867 curfn->dcl = list(curfn->dcl, n); |
866 | 868 |
867 dowidth(t); | 869 dowidth(t); |
868 w = t->width; | 870 w = t->width; |
869 stksize += w; | 871 stksize += w; |
870 stksize = rnd(stksize, t->align); | 872 stksize = rnd(stksize, t->align); |
871 if(thechar == '5') | 873 if(thechar == '5') |
872 stksize = rnd(stksize, widthptr); | 874 stksize = rnd(stksize, widthptr); |
873 n->xoffset = -stksize; | 875 n->xoffset = -stksize; |
874 | 876 |
875 // print("\ttmpname (%d): %N\n", stksize, n); | 877 // print("\ttmpname (%d): %N\n", stksize, n); |
876 | 878 |
877 *nn = *n; | 879 *nn = *n; |
878 } | 880 } |
LEFT | RIGHT |