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->noescape)»// this is nodfp (TODO lvd) | 91 » » if(n == nodfp) |
92 » » » break; | 92 » » » break; |
| 93 |
| 94 » » // if this is a tmpname (PAUTO), it was tagged by tmpname as not
escaping. |
| 95 » » // on PPARAM it means something different. |
| 96 » » if(n->class == PAUTO && n->esc == EscNever) |
| 97 » » » break; |
| 98 |
| 99 » » if(!debug['s'] && n->esc != EscUnknown) |
| 100 » » » fatal("without escape analysis, only PAUTO's should have
esc: %N", n); |
| 101 |
93 switch(n->class) { | 102 switch(n->class) { |
94 case PPARAMREF: | 103 case PPARAMREF: |
95 addrescapes(n->defn); | 104 addrescapes(n->defn); |
96 break; | 105 break; |
97 case PPARAM: | 106 case PPARAM: |
98 case PPARAMOUT: | 107 case PPARAMOUT: |
99 // if func param, need separate temporary | 108 // if func param, need separate temporary |
100 // to hold heap pointer. | 109 // to hold heap pointer. |
101 // the function type has already been checked | 110 // the function type has already been checked |
102 // (we're in the function body) | 111 // (we're in the function body) |
103 // so the param already has a valid xoffset. | 112 // so the param already has a valid xoffset. |
104 | 113 |
105 // expression to refer to stack copy | 114 // expression to refer to stack copy |
106 n->stackparam = nod(OPARAM, n, N); | 115 n->stackparam = nod(OPARAM, n, N); |
107 n->stackparam->type = n->type; | 116 n->stackparam->type = n->type; |
108 n->stackparam->addable = 1; | 117 n->stackparam->addable = 1; |
109 if(n->xoffset == BADWIDTH) | 118 if(n->xoffset == BADWIDTH) |
110 fatal("addrescapes before param assignment"); | 119 fatal("addrescapes before param assignment"); |
111 n->stackparam->xoffset = n->xoffset; | 120 n->stackparam->xoffset = n->xoffset; |
112 n->xoffset = 0; | |
113 // fallthrough | 121 // fallthrough |
114 case PAUTO: | 122 case PAUTO: |
115 | 123 |
116 n->class |= PHEAP; | 124 n->class |= PHEAP; |
117 n->addable = 0; | 125 n->addable = 0; |
118 n->ullman = 2; | 126 n->ullman = 2; |
119 n->xoffset = 0; | 127 n->xoffset = 0; |
120 | 128 |
121 // create stack variable to hold pointer to heap | 129 // create stack variable to hold pointer to heap |
122 n->heapaddr = nod(ONAME, N, N); | 130 n->heapaddr = nod(ONAME, N, N); |
123 n->heapaddr->type = ptrto(n->type); | 131 n->heapaddr->type = ptrto(n->type); |
124 snprint(buf, sizeof buf, "&%S", n->sym); | 132 snprint(buf, sizeof buf, "&%S", n->sym); |
125 n->heapaddr->sym = lookup(buf); | 133 n->heapaddr->sym = lookup(buf); |
126 n->heapaddr->class = PHEAP-1; // defer tempname to all
ocparams | 134 n->heapaddr->class = PHEAP-1; // defer tempname to all
ocparams |
127 n->heapaddr->ullman = 1; | 135 n->heapaddr->ullman = 1; |
128 n->curfn->dcl = list(n->curfn->dcl, n->heapaddr); | 136 n->curfn->dcl = list(n->curfn->dcl, n->heapaddr); |
129 | 137 |
130 » » » if (debug['m']) | 138 » » » if(debug['s']) |
131 » » » » 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); |
132 | 143 |
133 break; | 144 break; |
134 } | 145 } |
135 break; | 146 break; |
136 | 147 |
137 case OIND: | 148 case OIND: |
138 case ODOTPTR: | 149 case ODOTPTR: |
139 break; | 150 break; |
140 | 151 |
141 case ODOT: | 152 case ODOT: |
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 void | 836 void |
826 tempname(Node *nn, Type *t) | 837 tempname(Node *nn, Type *t) |
827 { | 838 { |
828 Node *n; | 839 Node *n; |
829 Sym *s; | 840 Sym *s; |
830 uint32 w; | 841 uint32 w; |
831 | 842 |
832 if(stksize < 0) | 843 if(stksize < 0) |
833 fatal("tempname not during code generation"); | 844 fatal("tempname not during code generation"); |
834 | 845 |
835 » if (curfn == N) | 846 » if(curfn == N) |
836 fatal("no curfn for tempname"); | 847 fatal("no curfn for tempname"); |
837 | 848 |
838 if(t == T) { | 849 if(t == T) { |
839 yyerror("tempname called with nil type"); | 850 yyerror("tempname called with nil type"); |
840 t = types[TINT32]; | 851 t = types[TINT32]; |
841 } | 852 } |
842 | 853 |
843 // give each tmp a different name so that there | 854 // give each tmp a different name so that there |
844 // a chance to registerizer them | 855 // a chance to registerizer them |
845 snprint(namebuf, sizeof(namebuf), "autotmp_%.4d", statuniqgen); | 856 snprint(namebuf, sizeof(namebuf), "autotmp_%.4d", statuniqgen); |
846 statuniqgen++; | 857 statuniqgen++; |
847 s = lookup(namebuf); | 858 s = lookup(namebuf); |
848 n = nod(ONAME, N, N); | 859 n = nod(ONAME, N, N); |
849 n->sym = s; | 860 n->sym = s; |
850 n->type = t; | 861 n->type = t; |
851 n->class = PAUTO; | 862 n->class = PAUTO; |
852 n->addable = 1; | 863 n->addable = 1; |
853 n->ullman = 1; | 864 n->ullman = 1; |
854 » n->noescape = 1; | 865 » n->esc = EscNever; |
855 n->curfn = curfn; | 866 n->curfn = curfn; |
856 curfn->dcl = list(curfn->dcl, n); | 867 curfn->dcl = list(curfn->dcl, n); |
857 | 868 |
858 dowidth(t); | 869 dowidth(t); |
859 w = t->width; | 870 w = t->width; |
860 stksize += w; | 871 stksize += w; |
861 stksize = rnd(stksize, t->align); | 872 stksize = rnd(stksize, t->align); |
862 if(thechar == '5') | 873 if(thechar == '5') |
863 stksize = rnd(stksize, widthptr); | 874 stksize = rnd(stksize, widthptr); |
864 n->xoffset = -stksize; | 875 n->xoffset = -stksize; |
865 | 876 |
866 // print("\ttmpname (%d): %N\n", stksize, n); | 877 // print("\ttmpname (%d): %N\n", stksize, n); |
867 | 878 |
868 *nn = *n; | 879 *nn = *n; |
869 } | 880 } |
LEFT | RIGHT |