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

Delta Between Two Patch Sets: src/cmd/gc/plive.c

Issue 64170043: code review 64170043: cmd/gc: correct liveness for fat variables (Closed)
Left Patch Set: Created 11 years, 1 month ago
Right Patch Set: diff -r a2b715d74188 https://code.google.com/p/go/ Created 11 years, 1 month 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:
Right: Side by side diff | Download
« no previous file with change/comment | « src/cmd/gc/pgen.c ('k') | src/run.bash » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 // Copyright 2013 The Go Authors. All rights reserved. 1 // Copyright 2013 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 // Garbage collector liveness bitmap generation. 5 // Garbage collector liveness bitmap generation.
6 6
7 // The command line flag -live causes this code to print debug information. 7 // The command line flag -live causes this code to print debug information.
8 // The levels are: 8 // The levels are:
9 // 9 //
10 // -live (aka -live=1): print liveness lists as code warnings at safe point s 10 // -live (aka -live=1): print liveness lists as code warnings at safe point s
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 576
577 // Sort the basic blocks by their depth first number. The 577 // Sort the basic blocks by their depth first number. The
578 // array is now a depth-first spanning tree with the first 578 // array is now a depth-first spanning tree with the first
579 // node being the root. 579 // node being the root.
580 arraysort(cfg, blockrpocmp); 580 arraysort(cfg, blockrpocmp);
581 bb = *(BasicBlock**)arrayget(cfg, 0); 581 bb = *(BasicBlock**)arrayget(cfg, 0);
582 582
583 // Unreachable control flow nodes are indicated by a -1 in the rpo 583 // Unreachable control flow nodes are indicated by a -1 in the rpo
584 // field. If we see these nodes something must have gone wrong in an 584 // field. If we see these nodes something must have gone wrong in an
585 // upstream compilation phase. 585 // upstream compilation phase.
586 » if(bb->rpo == -1) 586 » if(bb->rpo == -1) {
587 » » fatal("newcfg: unreferenced basic blocks"); 587 » » print("newcfg: unreachable basic block for %P\n", bb->last);
588 » » printcfg(cfg);
589 » » fatal("newcfg: invalid control flow graph");
590 » }
588 591
589 return cfg; 592 return cfg;
590 } 593 }
591 594
592 // Frees a control flow graph (an array of BasicBlock*s) and all of its leaf 595 // Frees a control flow graph (an array of BasicBlock*s) and all of its leaf
593 // data structures. 596 // data structures.
594 static void 597 static void
595 freecfg(Array *cfg) 598 freecfg(Array *cfg)
596 { 599 {
597 BasicBlock *bb; 600 BasicBlock *bb;
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
949 BasicBlock *bb; 952 BasicBlock *bb;
950 int32 i; 953 int32 i;
951 954
952 for(i = 0; i < arraylength(lv->cfg); i++) { 955 for(i = 0; i < arraylength(lv->cfg); i++) {
953 bb = *(BasicBlock**)arrayget(lv->cfg, i); 956 bb = *(BasicBlock**)arrayget(lv->cfg, i);
954 livenessprintblock(lv, bb); 957 livenessprintblock(lv, bb);
955 } 958 }
956 } 959 }
957 960
958 static void 961 static void
959 checkauto(Node *fn, Prog *p, Node *n, char *where) 962 checkauto(Node *fn, Prog *p, Node *n)
960 { 963 {
961 » NodeList *ll; 964 » NodeList *l;
962 » int found; 965
963 » char *fnname; 966 » for(l = fn->dcl; l != nil; l = l->next)
964 » char *nname; 967 » » if(l->n->op == ONAME && l->n->class == PAUTO && l->n == n)
965 968 » » » return;
966 » found = 0; 969
967 » for(ll = fn->dcl; ll != nil; ll = ll->next) { 970 » print("checkauto %N: %N (%p; class=%d) not found in %P\n", curfn, n, n, n->class, p);
968 » » if(ll->n->op == ONAME && ll->n->class == PAUTO) { 971 » for(l = fn->dcl; l != nil; l = l->next)
969 » » » if(n == ll->n) { 972 » » print("\t%N (%p; class=%d)\n", l->n, l->n, l->n->class);
970 » » » » found = 1;
971 » » » » break;
972 » » » }
973 » » }
974 » }
975 » if(found)
976 » » return;
977 » fnname = fn->nname->sym->name ? fn->nname->sym->name : "<unknown>";
978 » nname = n->sym->name ? n->sym->name : "<unknown>";
979 » print("D_AUTO '%s' not found: name is '%s' function is '%s' class is %d\ n", where, nname, fnname, n->class);
980 » print("Here '%P'\nlooking for node %p\n", p, n);
981 » for(ll = fn->dcl; ll != nil; ll = ll->next)
982 » » print("node=%p, node->class=%d\n", (uintptr)ll->n, ll->n->class) ;
983 yyerror("checkauto: invariant lost"); 973 yyerror("checkauto: invariant lost");
984 } 974 }
985 975
986 static void 976 static void
987 checkparam(Node *fn, Prog *p, Node *n, char *where) 977 checkparam(Node *fn, Prog *p, Node *n)
988 { 978 {
989 » NodeList *ll; 979 » NodeList *l;
990 » int found; 980 » Node *a;
991 » char *fnname; 981 » int class;
992 » char *nname;
993 982
994 if(isfunny(n)) 983 if(isfunny(n))
995 return; 984 return;
996 » found = 0; 985 » for(l = fn->dcl; l != nil; l = l->next) {
997 » for(ll = fn->dcl; ll != nil; ll = ll->next) { 986 » » a = l->n;
998 » » if(ll->n->op == ONAME && ((ll->n->class & ~PHEAP) == PPARAM || 987 » » class = l->n->class & ~PHEAP;
999 » » » » » (ll->n->class & ~PHEAP) == PPARAMOUT)) { 988 » » if(a->op == ONAME && (class == PPARAM || class == PPARAMOUT) && a == n)
1000 » » » if(n == ll->n) { 989 » » » return;
1001 » » » » found = 1; 990 » }
1002 » » » » break; 991
1003 » » » } 992 » print("checkparam %N: %N (%p; class=%d) not found in %P\n", curfn, n, n, n->class, p);
1004 » » } 993 » for(l = fn->dcl; l != nil; l = l->next)
1005 » } 994 » » print("\t%N (%p; class=%d)\n", l->n, l->n, l->n->class);
1006 » if(found)
1007 » » return;
1008 » if(n->sym) {
1009 » » fnname = fn->nname->sym->name ? fn->nname->sym->name : "<unknown >";
1010 » » nname = n->sym->name ? n->sym->name : "<unknown>";
1011 » » print("D_PARAM '%s' not found: name='%s' function='%s' class is %d\n", where, nname, fnname, n->class);
1012 » » print("Here '%P'\nlooking for node %p\n", p, n);
1013 » » for(ll = fn->dcl; ll != nil; ll = ll->next)
1014 » » » print("node=%p, node->class=%d\n", ll->n, ll->n->class);
1015 » }
1016 yyerror("checkparam: invariant lost"); 995 yyerror("checkparam: invariant lost");
1017 } 996 }
1018 997
1019 static void 998 static void
1020 checkprog(Node *fn, Prog *p) 999 checkprog(Node *fn, Prog *p)
1021 { 1000 {
1022 if(p->from.type == D_AUTO) 1001 if(p->from.type == D_AUTO)
1023 » » checkauto(fn, p, p->from.node, "from"); 1002 » » checkauto(fn, p, p->from.node);
1024 if(p->from.type == D_PARAM) 1003 if(p->from.type == D_PARAM)
1025 » » checkparam(fn, p, p->from.node, "from"); 1004 » » checkparam(fn, p, p->from.node);
1026 if(p->to.type == D_AUTO) 1005 if(p->to.type == D_AUTO)
1027 » » checkauto(fn, p, p->to.node, "to"); 1006 » » checkauto(fn, p, p->to.node);
1028 if(p->to.type == D_PARAM) 1007 if(p->to.type == D_PARAM)
1029 » » checkparam(fn, p, p->to.node, "to"); 1008 » » checkparam(fn, p, p->to.node);
1030 } 1009 }
1031 1010
1032 // Check instruction invariants. We assume that the nodes corresponding to the 1011 // Check instruction invariants. We assume that the nodes corresponding to the
1033 // sources and destinations of memory operations will be declared in the 1012 // sources and destinations of memory operations will be declared in the
1034 // function. This is not strictly true, as is the case for the so-called funny 1013 // function. This is not strictly true, as is the case for the so-called funny
1035 // nodes and there are special cases to skip over that stuff. The analysis will 1014 // nodes and there are special cases to skip over that stuff. The analysis will
1036 // fail if this invariant blindly changes. 1015 // fail if this invariant blindly changes.
1037 static void 1016 static void
1038 checkptxt(Node *fn, Prog *firstp) 1017 checkptxt(Node *fn, Prog *firstp)
1039 { 1018 {
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after
1602 printvars("livein", livein, lv->vars); 1581 printvars("livein", livein, lv->vars);
1603 printvars("liveout", liveout, lv->vars); 1582 printvars("liveout", liveout, lv->vars);
1604 } 1583 }
1605 if(issafepoint(p)) { 1584 if(issafepoint(p)) {
1606 // Found an interesting instruction, record the 1585 // Found an interesting instruction, record the
1607 // corresponding liveness information.·· 1586 // corresponding liveness information.··
1608 ································ 1587 ································
1609 // Useful sanity check: on entry to the function , 1588 // Useful sanity check: on entry to the function ,
1610 // the only things that can possibly be live are the 1589 // the only things that can possibly be live are the
1611 // input parameters. 1590 // input parameters.
1612 » » » » if(0 && p->as == ATEXT) { 1591 » » » » if(p->as == ATEXT) {
1613 for(j = 0; j < liveout->n; j++) { 1592 for(j = 0; j < liveout->n; j++) {
1614 if(!bvget(liveout, j)) 1593 if(!bvget(liveout, j))
1615 continue; 1594 continue;
1616 n = *(Node**)arrayget(lv->vars, j); 1595 n = *(Node**)arrayget(lv->vars, j);
1617 if(n->class != PPARAM) 1596 if(n->class != PPARAM)
1618 » » » » » » » yyerrorl(p->lineno, "int ernal error: %N %N recorded as live on entry", curfn->nname, n); 1597 » » » » » » » yyerrorl(p->lineno, "int ernal error: %N %lN recorded as live on entry", curfn->nname, n);
1619 } 1598 }
1620 } 1599 }
1621 1600
1622 // Record live pointers. 1601 // Record live pointers.
1623 args = *(Bvec**)arrayget(lv->argslivepointers, p os); 1602 args = *(Bvec**)arrayget(lv->argslivepointers, p os);
1624 locals = *(Bvec**)arrayget(lv->livepointers, pos ); 1603 locals = *(Bvec**)arrayget(lv->livepointers, pos );
1625 twobitlivepointermap(lv, liveout, lv->vars, args , locals); 1604 twobitlivepointermap(lv, liveout, lv->vars, args , locals);
1626 1605
1627 // Show live pointer bitmaps. 1606 // Show live pointer bitmaps.
1628 // We're interpreting the args and locals bitmap instead of liveout so that we 1607 // We're interpreting the args and locals bitmap instead of liveout so that we
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
1923 if(deadsym != nil) 1902 if(deadsym != nil)
1924 twobitwritesymbol(lv->deadvalues, deadsym, nil); 1903 twobitwritesymbol(lv->deadvalues, deadsym, nil);
1925 1904
1926 // Free everything. 1905 // Free everything.
1927 freeliveness(lv); 1906 freeliveness(lv);
1928 arrayfree(vars); 1907 arrayfree(vars);
1929 freecfg(cfg); 1908 freecfg(cfg);
1930 ········ 1909 ········
1931 debuglive -= debugdelta; 1910 debuglive -= debugdelta;
1932 } 1911 }
LEFTRIGHT

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