Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
8bd8cede
Commit
8bd8cede
authored
Jan 14, 2014
by
Russ Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd/gc: add -live flag for debugging liveness maps
R=khr CC=golang-codereviews
https://golang.org/cl/51820043
parent
3ec60c25
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
63 additions
and
31 deletions
+63
-31
go.h
src/cmd/gc/go.h
+1
-0
lex.c
src/cmd/gc/lex.c
+1
-0
plive.c
src/cmd/gc/plive.c
+61
-31
No files found.
src/cmd/gc/go.h
View file @
8bd8cede
...
...
@@ -972,6 +972,7 @@ EXTERN char* flag_installsuffix;
EXTERN
int
flag_race
;
EXTERN
int
flag_largemodel
;
EXTERN
int
noescape
;
EXTERN
int
debuglive
;
EXTERN
Link
*
ctxt
;
EXTERN
int
nointerface
;
...
...
src/cmd/gc/lex.c
View file @
8bd8cede
...
...
@@ -264,6 +264,7 @@ main(int argc, char *argv[])
flagstr
(
"installsuffix"
,
"pkg directory suffix"
,
&
flag_installsuffix
);
flagcount
(
"j"
,
"debug runtime-initialized variables"
,
&
debug
[
'j'
]);
flagcount
(
"l"
,
"disable inlining"
,
&
debug
[
'l'
]);
flagcount
(
"live"
,
"debug liveness analysis"
,
&
debuglive
);
flagcount
(
"m"
,
"print optimization decisions"
,
&
debug
[
'm'
]);
flagstr
(
"o"
,
"obj: set output file"
,
&
outfile
);
flagstr
(
"p"
,
"path: set expected package import path"
,
&
myimportpath
);
...
...
src/cmd/gc/plive.c
View file @
8bd8cede
...
...
@@ -238,10 +238,9 @@ blockany(BasicBlock *bb, int (*callback)(Prog*))
}
// Collects and returns and array of Node*s for functions arguments and local
// variables. TODO(cshapiro): only return pointer containing nodes if we are
// not also generating a dead value map.
// variables.
static
Array
*
getvariables
(
Node
*
fn
)
getvariables
(
Node
*
fn
,
int
allvalues
)
{
Array
*
result
;
NodeList
*
ll
;
...
...
@@ -249,11 +248,13 @@ getvariables(Node *fn)
result
=
arraynew
(
0
,
sizeof
(
Node
*
));
for
(
ll
=
fn
->
dcl
;
ll
!=
nil
;
ll
=
ll
->
next
)
{
if
(
ll
->
n
->
op
==
ONAME
)
{
switch
(
ll
->
n
->
class
&
~
PHEAP
)
{
switch
(
ll
->
n
->
class
)
{
case
PAUTO
:
case
PPARAM
:
case
PPARAMOUT
:
arrayadd
(
result
,
&
ll
->
n
);
if
(
haspointers
(
ll
->
n
->
type
)
||
allvalues
)
arrayadd
(
result
,
&
ll
->
n
);
break
;
}
}
}
...
...
@@ -657,7 +658,7 @@ progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill)
case
PPARAMOUT
:
pos
=
arrayindexof
(
vars
,
from
->
node
);
if
(
pos
==
-
1
)
fatal
(
"progeffects: variable %N is unknown"
,
prog
->
from
.
node
)
;
goto
Next
;
if
(
info
.
flags
&
(
LeftRead
|
LeftAddr
))
bvset
(
uevar
,
pos
);
if
(
info
.
flags
&
LeftWrite
)
...
...
@@ -666,6 +667,7 @@ progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill)
}
}
}
Next:
if
(
info
.
flags
&
(
RightRead
|
RightWrite
|
RightAddr
))
{
to
=
&
prog
->
to
;
if
(
to
->
node
!=
nil
&&
to
->
sym
!=
nil
&&
!
isfunny
(
to
->
node
))
{
...
...
@@ -675,7 +677,7 @@ progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill)
case
PPARAMOUT
:
pos
=
arrayindexof
(
vars
,
to
->
node
);
if
(
pos
==
-
1
)
fatal
(
"progeffects: variable %N is unknown"
,
to
->
node
)
;
goto
Next1
;
if
(
info
.
flags
&
(
RightRead
|
RightAddr
))
bvset
(
uevar
,
pos
);
if
(
info
.
flags
&
RightWrite
)
...
...
@@ -684,6 +686,7 @@ progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill)
}
}
}
Next1:
;
}
// Constructs a new liveness structure used to hold the global state of the
...
...
@@ -1304,22 +1307,19 @@ static void
livenessepilogue
(
Liveness
*
lv
)
{
BasicBlock
*
bb
;
Bvec
*
livein
;
Bvec
*
liveout
;
Bvec
*
uevar
;
Bvec
*
varkill
;
Bvec
*
args
;
Bvec
*
locals
;
Bvec
*
livein
,
*
liveout
,
*
uevar
,
*
varkill
,
*
args
,
*
locals
;
Prog
*
p
,
*
next
;
int32
i
;
int32
nvars
;
int32
pos
;
int32
i
,
j
,
nmsg
,
nvars
,
pos
;
char
**
msg
;
Fmt
fmt
;
nvars
=
arraylength
(
lv
->
vars
);
livein
=
bvalloc
(
nvars
);
liveout
=
bvalloc
(
nvars
);
uevar
=
bvalloc
(
nvars
);
varkill
=
bvalloc
(
nvars
);
msg
=
nil
;
nmsg
=
0
;
for
(
i
=
0
;
i
<
arraylength
(
lv
->
cfg
);
i
++
)
{
bb
=
*
(
BasicBlock
**
)
arrayget
(
lv
->
cfg
,
i
);
...
...
@@ -1347,6 +1347,13 @@ livenessepilogue(Liveness *lv)
arrayadd
(
lv
->
deadvalues
,
&
locals
);
}
}
if
(
debuglive
)
{
nmsg
=
arraylength
(
lv
->
livepointers
);
msg
=
xmalloc
(
nmsg
*
sizeof
msg
[
0
]);
for
(
j
=
0
;
j
<
nmsg
;
j
++
)
msg
[
j
]
=
nil
;
}
// walk backward, emit pcdata and populate the maps
pos
=
arraylength
(
lv
->
livepointers
)
-
1
;
...
...
@@ -1372,8 +1379,35 @@ livenessepilogue(Liveness *lv)
}
if
(
issafepoint
(
p
))
{
// Found an interesting instruction, record the
// corresponding liveness information. Only
// CALL instructions need a PCDATA annotation.
// corresponding liveness information.
if
(
debuglive
)
{
fmtstrinit
(
&
fmt
);
fmtprint
(
&
fmt
,
"%L: live at "
,
p
->
lineno
);
if
(
p
->
as
==
ACALL
)
fmtprint
(
&
fmt
,
"CALL %lS:"
,
p
->
to
.
sym
);
else
fmtprint
(
&
fmt
,
"TEXT %lS:"
,
p
->
from
.
sym
);
for
(
j
=
0
;
j
<
arraylength
(
lv
->
vars
);
j
++
)
if
(
bvget
(
liveout
,
j
))
fmtprint
(
&
fmt
,
" %N"
,
*
(
Node
**
)
arrayget
(
lv
->
vars
,
j
));
fmtprint
(
&
fmt
,
"
\n
"
);
msg
[
pos
]
=
fmtstrflush
(
&
fmt
);
}
// Record live pointers.
args
=
*
(
Bvec
**
)
arrayget
(
lv
->
argslivepointers
,
pos
);
locals
=
*
(
Bvec
**
)
arrayget
(
lv
->
livepointers
,
pos
);
twobitlivepointermap
(
lv
,
liveout
,
lv
->
vars
,
args
,
locals
);
// Record dead values.
if
(
lv
->
deadvalues
!=
nil
)
{
args
=
*
(
Bvec
**
)
arrayget
(
lv
->
argsdeadvalues
,
pos
);
locals
=
*
(
Bvec
**
)
arrayget
(
lv
->
deadvalues
,
pos
);
twobitdeadvaluemap
(
lv
,
liveout
,
lv
->
vars
,
args
,
locals
);
}
// Only CALL instructions need a PCDATA annotation.
// The TEXT instruction annotation is implicit.
if
(
p
->
as
==
ACALL
)
{
if
(
isdeferreturn
(
p
))
{
...
...
@@ -1394,21 +1428,17 @@ livenessepilogue(Liveness *lv)
}
}
// Record live pointers.
args
=
*
(
Bvec
**
)
arrayget
(
lv
->
argslivepointers
,
pos
);
locals
=
*
(
Bvec
**
)
arrayget
(
lv
->
livepointers
,
pos
);
twobitlivepointermap
(
lv
,
liveout
,
lv
->
vars
,
args
,
locals
);
// Record dead values.
if
(
lv
->
deadvalues
!=
nil
)
{
args
=
*
(
Bvec
**
)
arrayget
(
lv
->
argsdeadvalues
,
pos
);
locals
=
*
(
Bvec
**
)
arrayget
(
lv
->
deadvalues
,
pos
);
twobitdeadvaluemap
(
lv
,
liveout
,
lv
->
vars
,
args
,
locals
);
}
pos
--
;
}
}
if
(
debuglive
)
{
for
(
j
=
0
;
j
<
nmsg
;
j
++
)
if
(
msg
[
j
]
!=
nil
)
print
(
"%s"
,
msg
[
j
]);
free
(
msg
);
msg
=
nil
;
nmsg
=
0
;
}
}
free
(
livein
);
...
...
@@ -1497,7 +1527,7 @@ liveness(Node *fn, Prog *firstp, Sym *argssym, Sym *livesym, Sym *deadsym)
// Construct the global liveness state.
cfg
=
newcfg
(
firstp
);
if
(
0
)
printcfg
(
cfg
);
vars
=
getvariables
(
fn
);
vars
=
getvariables
(
fn
,
deadsym
!=
nil
);
lv
=
newliveness
(
fn
,
firstp
,
cfg
,
vars
,
deadsym
!=
nil
);
// Run the dataflow framework.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment