From b3fb6b00ae6649631ce43a034f2d160045af3aee Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Fri, 14 Apr 2017 06:43:01 -0700 Subject: [PATCH] cmd/compile: relocate large comment to plive.go It was a bit weird to have it at the top of pgen.go. This does half of the TODO at the top of the comment. Change-Id: I65140fa05673b2dbb6feddb8c1877f6d624a7844 Reviewed-on: https://go-review.googlesource.com/40698 Run-TryBot: Josh Bleecher Snyder TryBot-Result: Gobot Gobot Reviewed-by: Matthew Dempsky --- src/cmd/compile/internal/gc/pgen.go | 58 ---------------------------- src/cmd/compile/internal/gc/plive.go | 57 +++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 58 deletions(-) diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go index c5519f6c3b..a8edfade10 100644 --- a/src/cmd/compile/internal/gc/pgen.go +++ b/src/cmd/compile/internal/gc/pgen.go @@ -17,64 +17,6 @@ import ( // "Portable" code generation. -// TODO(mdempsky): Update to reference OpVar{Def,Kill,Live} instead -// and move to plive.go. - -// VARDEF is an annotation for the liveness analysis, marking a place -// where a complete initialization (definition) of a variable begins. -// Since the liveness analysis can see initialization of single-word -// variables quite easy, gvardef is usually only called for multi-word -// or 'fat' variables, those satisfying isfat(n->type). -// However, gvardef is also called when a non-fat variable is initialized -// via a block move; the only time this happens is when you have -// return f() -// for a function with multiple return values exactly matching the return -// types of the current function. -// -// A 'VARDEF x' annotation in the instruction stream tells the liveness -// analysis to behave as though the variable x is being initialized at that -// point in the instruction stream. The VARDEF must appear before the -// actual (multi-instruction) initialization, and it must also appear after -// any uses of the previous value, if any. For example, if compiling: -// -// x = x[1:] -// -// it is important to generate code like: -// -// base, len, cap = pieces of x[1:] -// VARDEF x -// x = {base, len, cap} -// -// If instead the generated code looked like: -// -// VARDEF x -// base, len, cap = pieces of x[1:] -// x = {base, len, cap} -// -// then the liveness analysis would decide the previous value of x was -// unnecessary even though it is about to be used by the x[1:] computation. -// Similarly, if the generated code looked like: -// -// base, len, cap = pieces of x[1:] -// x = {base, len, cap} -// VARDEF x -// -// then the liveness analysis will not preserve the new value of x, because -// the VARDEF appears to have "overwritten" it. -// -// VARDEF is a bit of a kludge to work around the fact that the instruction -// stream is working on single-word values but the liveness analysis -// wants to work on individual variables, which might be multi-word -// aggregates. It might make sense at some point to look into letting -// the liveness analysis work on single-word values as well, although -// there are complications around interface values, slices, and strings, -// all of which cannot be treated as individual words. -// -// VARKILL is the opposite of VARDEF: it marks a value as no longer needed, -// even if its address has been taken. That is, a VARKILL annotation asserts -// that its argument is certainly dead, for use when the liveness analysis -// would not otherwise be able to deduce that fact. - func emitptrargsmap() { if Curfn.Func.Nname.Sym.Name == "_" { return diff --git a/src/cmd/compile/internal/gc/plive.go b/src/cmd/compile/internal/gc/plive.go index b667510b08..8e1c80a9ce 100644 --- a/src/cmd/compile/internal/gc/plive.go +++ b/src/cmd/compile/internal/gc/plive.go @@ -23,6 +23,63 @@ import ( "strings" ) +// TODO(mdempsky): Update to reference OpVar{Def,Kill,Live} instead. + +// VARDEF is an annotation for the liveness analysis, marking a place +// where a complete initialization (definition) of a variable begins. +// Since the liveness analysis can see initialization of single-word +// variables quite easy, gvardef is usually only called for multi-word +// or 'fat' variables, those satisfying isfat(n->type). +// However, gvardef is also called when a non-fat variable is initialized +// via a block move; the only time this happens is when you have +// return f() +// for a function with multiple return values exactly matching the return +// types of the current function. +// +// A 'VARDEF x' annotation in the instruction stream tells the liveness +// analysis to behave as though the variable x is being initialized at that +// point in the instruction stream. The VARDEF must appear before the +// actual (multi-instruction) initialization, and it must also appear after +// any uses of the previous value, if any. For example, if compiling: +// +// x = x[1:] +// +// it is important to generate code like: +// +// base, len, cap = pieces of x[1:] +// VARDEF x +// x = {base, len, cap} +// +// If instead the generated code looked like: +// +// VARDEF x +// base, len, cap = pieces of x[1:] +// x = {base, len, cap} +// +// then the liveness analysis would decide the previous value of x was +// unnecessary even though it is about to be used by the x[1:] computation. +// Similarly, if the generated code looked like: +// +// base, len, cap = pieces of x[1:] +// x = {base, len, cap} +// VARDEF x +// +// then the liveness analysis will not preserve the new value of x, because +// the VARDEF appears to have "overwritten" it. +// +// VARDEF is a bit of a kludge to work around the fact that the instruction +// stream is working on single-word values but the liveness analysis +// wants to work on individual variables, which might be multi-word +// aggregates. It might make sense at some point to look into letting +// the liveness analysis work on single-word values as well, although +// there are complications around interface values, slices, and strings, +// all of which cannot be treated as individual words. +// +// VARKILL is the opposite of VARDEF: it marks a value as no longer needed, +// even if its address has been taken. That is, a VARKILL annotation asserts +// that its argument is certainly dead, for use when the liveness analysis +// would not otherwise be able to deduce that fact. + // BlockEffects summarizes the liveness effects on an SSA block. type BlockEffects struct { lastbitmapindex int // for livenessepilogue -- 2.48.1