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" |
11 | 11 |
12 static void cgen_dcl(Node *n); | 12 static void cgen_dcl(Node *n); |
13 static void cgen_proc(Node *n, int proc); | 13 static void cgen_proc(Node *n, int proc); |
14 static void checkgoto(Node*, Node*); | 14 static void» checkgoto(Node*, Node*); |
15 | 15 |
16 static Label *labellist; | 16 static Label *labellist; |
17 static Label *lastlabel; | 17 static Label *lastlabel; |
18 | 18 |
19 Node* | 19 Node* |
20 sysfunc(char *name) | 20 sysfunc(char *name) |
21 { | 21 { |
22 Node *n; | 22 Node *n; |
23 | 23 |
24 n = newname(pkglookup(name, runtimepkg)); | 24 n = newname(pkglookup(name, runtimepkg)); |
(...skipping 23 matching lines...) Expand all 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) | 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 //» » » print("moved to heap: %N\n", n); | 138 » » » if(debug['s']) |
| 139 » » » » n->esc = EscHeap; |
| 140 |
| 141 » » » if(debug['m']) |
| 142 » » » » print("%L: moved to heap: %hN\n", n->lineno, n); |
131 | 143 |
132 break; | 144 break; |
133 } | 145 } |
134 break; | 146 break; |
135 | 147 |
136 case OIND: | 148 case OIND: |
137 case ODOTPTR: | 149 case ODOTPTR: |
138 break; | 150 break; |
139 | 151 |
140 case ODOT: | 152 case ODOT: |
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
824 void | 836 void |
825 tempname(Node *nn, Type *t) | 837 tempname(Node *nn, Type *t) |
826 { | 838 { |
827 Node *n; | 839 Node *n; |
828 Sym *s; | 840 Sym *s; |
829 uint32 w; | 841 uint32 w; |
830 | 842 |
831 if(stksize < 0) | 843 if(stksize < 0) |
832 fatal("tempname not during code generation"); | 844 fatal("tempname not during code generation"); |
833 | 845 |
834 » if (curfn == N) | 846 » if(curfn == N) |
835 fatal("no curfn for tempname"); | 847 fatal("no curfn for tempname"); |
836 | 848 |
837 if(t == T) { | 849 if(t == T) { |
838 yyerror("tempname called with nil type"); | 850 yyerror("tempname called with nil type"); |
839 t = types[TINT32]; | 851 t = types[TINT32]; |
840 } | 852 } |
841 | 853 |
842 // give each tmp a different name so that there | 854 // give each tmp a different name so that there |
843 // a chance to registerizer them | 855 // a chance to registerizer them |
844 snprint(namebuf, sizeof(namebuf), "autotmp_%.4d", statuniqgen); | 856 snprint(namebuf, sizeof(namebuf), "autotmp_%.4d", statuniqgen); |
845 statuniqgen++; | 857 statuniqgen++; |
846 s = lookup(namebuf); | 858 s = lookup(namebuf); |
847 n = nod(ONAME, N, N); | 859 n = nod(ONAME, N, N); |
848 n->sym = s; | 860 n->sym = s; |
849 n->type = t; | 861 n->type = t; |
850 n->class = PAUTO; | 862 n->class = PAUTO; |
851 n->addable = 1; | 863 n->addable = 1; |
852 n->ullman = 1; | 864 n->ullman = 1; |
853 » n->noescape = 1; | 865 » n->esc = EscNever; |
854 n->curfn = curfn; | 866 n->curfn = curfn; |
855 curfn->dcl = list(curfn->dcl, n); | 867 curfn->dcl = list(curfn->dcl, n); |
856 | 868 |
857 dowidth(t); | 869 dowidth(t); |
858 w = t->width; | 870 w = t->width; |
859 stksize += w; | 871 stksize += w; |
860 stksize = rnd(stksize, t->align); | 872 stksize = rnd(stksize, t->align); |
861 if(thechar == '5') | 873 if(thechar == '5') |
862 stksize = rnd(stksize, widthptr); | 874 stksize = rnd(stksize, widthptr); |
863 n->xoffset = -stksize; | 875 n->xoffset = -stksize; |
864 | 876 |
865 // print("\ttmpname (%d): %N\n", stksize, n); | 877 // print("\ttmpname (%d): %N\n", stksize, n); |
866 | 878 |
867 *nn = *n; | 879 *nn = *n; |
868 } | 880 } |
LEFT | RIGHT |