// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Garbage collector liveness bitmap generation.

// The command line flag -live causes this code to print debug information.
// The levels are:
//
//	-live (aka -live=1): print liveness lists as code warnings at safe points
//	-live=2: print an assembly listing with liveness annotations
//	-live=3: print information during each computation phase (much chattier)
//
// Each level includes the earlier output as well.

#include <u.h>
#include <libc.h>
#include "gg.h"
#include "opt.h"
#include "../../pkg/runtime/funcdata.h"

enum { BitsPerPointer = 2 };

enum {
	UNVISITED = 0,
	VISITED = 1,
};

// An ordinary basic block.
//
// Instructions are threaded together in a doubly-linked list.  To iterate in
// program order follow the link pointer from the first node and stop after the
// last node has been visited
//
//   for(p = bb->first;; p = p->link) {
//     ...
//     if(p == bb->last)
//       break;
//   }
//
// To iterate in reverse program order by following the opt pointer from the
// last node
//
//   for(p = bb->last; p != nil; p = p->opt) {
//     ...
//   }
typedef struct BasicBlock BasicBlock;
struct BasicBlock {
	// An array of preceding blocks.  If the length of this array is 0 the
	// block is probably the start block of the CFG.
	Array *pred;

	// An array out succeeding blocks.  If the length of this array is zero,
	// the block probably ends in a return instruction.
	Array *succ;

	// First instruction in the block.  When part of a fully initialized
	// control flow graph, the opt member will be nil.
	Prog *first;

	// Last instruction in the basic block.
	Prog *last;

	// The reverse post order number.  This value is initialized to -1 and
	// will be replaced by a non-negative value when the CFG is constructed.
	// After CFG construction, if rpo is -1 this block is unreachable.
	int rpo;

	// State to denote whether the block has been visited during a
	// traversal.
	int mark;
	
	// For use during livenessepilogue.
	int lastbitmapindex;
};

// A collection of global state used by liveness analysis.
typedef struct Liveness Liveness;
struct Liveness {
	// A pointer to the node corresponding to the function being analyzed.
	Node *fn;

	// A linked list of instructions for this function.
	Prog *ptxt;

	// A list of arguments and local variables in this function.
	Array *vars;

	// A list of basic blocks that are overlayed on the instruction list.
	// The blocks are roughly in the same order as the instructions
	// in the function (first block has TEXT instruction, and so on).
	Array *cfg;

	// Summary sets of block effects.
	// The Bvec** is indexed by bb->rpo to yield a single Bvec*.
	// That bit vector is indexed by variable number (same as lv->vars).
	//
	// Computed during livenessprologue using only the content of
	// individual blocks:
	//
	//	uevar: upward exposed variables (used before set in block)
	//	varkill: killed variables (set in block)
	//	avarinit: addrtaken variables set or used (proof of initialization)
	//
	// Computed during livenesssolve using control flow information:
	//
	//	livein: variables live at block entry
	//	liveout: variables live at block exit
	//	avarinitany: addrtaken variables possibly initialized at block exit
	//		(initialized in block or at exit from any predecessor block)
	//	avarinitall: addrtaken variables certainly initialized at block exit
	//		(initialized in block or at exit from all predecessor blocks)
	Bvec **uevar;
	Bvec **varkill;
	Bvec **livein;
	Bvec **liveout;
	Bvec **avarinit;
	Bvec **avarinitany;
	Bvec **avarinitall;

	// An array with a bit vector for each safe point tracking live pointers
	// in the arguments and locals area, indexed by bb->rpo.
	Array *argslivepointers;
	Array *livepointers;
};

static void*
xmalloc(uintptr size)
{
	void *result;

	result = malloc(size);
	if(result == nil)
		fatal("malloc failed");
	return result;
}

// Constructs a new basic block containing a single instruction.
static BasicBlock*
newblock(Prog *prog)
{
	BasicBlock *result;

	if(prog == nil)
		fatal("newblock: prog cannot be nil");
	result = xmalloc(sizeof(*result));
	result->rpo = -1;
	result->mark = UNVISITED;
	result->first = prog;
	result->last = prog;
	result->pred = arraynew(2, sizeof(BasicBlock*));
	result->succ = arraynew(2, sizeof(BasicBlock*));
	return result;
}

// Frees a basic block and all of its leaf data structures.
static void
freeblock(BasicBlock *bb)
{
	if(bb == nil)
		fatal("freeblock: cannot free nil");
	arrayfree(bb->pred);
	arrayfree(bb->succ);
	free(bb);
}

// Adds an edge between two basic blocks by making from a predecessor of to and
// to a successor of from.
static void
addedge(BasicBlock *from, BasicBlock *to)
{
	if(from == nil)
		fatal("addedge: from is nil");
	if(to == nil)
		fatal("addedge: to is nil");
	arrayadd(from->succ, &to);
	arrayadd(to->pred, &from);
}

// Inserts prev before curr in the instruction
// stream.  Any control flow, such as branches or fall throughs, that target the
// existing instruction are adjusted to target the new instruction.
static void
splicebefore(Liveness *lv, BasicBlock *bb, Prog *prev, Prog *curr)
{
	Prog *next, tmp;

	USED(lv);

	// There may be other instructions pointing at curr,
	// and we want them to now point at prev. Instead of
	// trying to find all such instructions, swap the contents
	// so that the problem becomes inserting next after curr.
	// The "opt" field is the backward link in the linked list.

	// Overwrite curr's data with prev, but keep the list links.
	tmp = *curr;
	*curr = *prev;
	curr->opt = tmp.opt;
	curr->link = tmp.link;
	
	// Overwrite prev (now next) with curr's old data.
	next = prev;
	*next = tmp;
	next->opt = nil;
	next->link = nil;

	// Now insert next after curr.
	next->link = curr->link;
	next->opt = curr;
	curr->link = next;
	if(next->link && next->link->opt == curr)
		next->link->opt = next;

	if(bb->last == curr)
		bb->last = next;
}

// A pretty printer for basic blocks.
static void
printblock(BasicBlock *bb)
{
	BasicBlock *pred;
	BasicBlock *succ;
	Prog *prog;
	int i;

	print("basic block %d\n", bb->rpo);
	print("\tpred:");
	for(i = 0; i < arraylength(bb->pred); i++) {
		pred = *(BasicBlock**)arrayget(bb->pred, i);
		print(" %d", pred->rpo);
	}
	print("\n");
	print("\tsucc:");
	for(i = 0; i < arraylength(bb->succ); i++) {
		succ = *(BasicBlock**)arrayget(bb->succ, i);
		print(" %d", succ->rpo);
	}
	print("\n");
	print("\tprog:\n");
	for(prog = bb->first;; prog=prog->link) {
		print("\t\t%P\n", prog);
		if(prog == bb->last)
			break;
	}
}


// Iterates over a basic block applying a callback to each instruction.  There
// are two criteria for termination.  If the end of basic block is reached a
// value of zero is returned.  If the callback returns a non-zero value, the
// iteration is stopped and the value of the callback is returned.
static int
blockany(BasicBlock *bb, int (*callback)(Prog*))
{
	Prog *p;
	int result;

	for(p = bb->last; p != nil; p = p->opt) {
		result = (*callback)(p);
		if(result != 0)
			return result;
	}
	return 0;
}

// Collects and returns and array of Node*s for functions arguments and local
// variables.
static Array*
getvariables(Node *fn)
{
	Array *result;
	NodeList *ll;

	result = arraynew(0, sizeof(Node*));
	for(ll = fn->dcl; ll != nil; ll = ll->next) {
		if(ll->n->op == ONAME) {
			// In order for GODEBUG=gcdead=1 to work, each bitmap needs
			// to contain information about all variables covered by the bitmap.
			// For local variables, the bitmap only covers the stkptrsize
			// bytes in the frame where variables containing pointers live.
			// For arguments and results, the bitmap covers all variables,
			// so we must include all the variables, even the ones without
			// pointers.
			switch(ll->n->class) {
			case PAUTO:
				if(haspointers(ll->n->type))
					arrayadd(result, &ll->n);
				break;
			case PPARAM:
			case PPARAMOUT:
				arrayadd(result, &ll->n);
				break;
			}
		}
	}
	return result;
}

// A pretty printer for control flow graphs.  Takes an array of BasicBlock*s.
static void
printcfg(Array *cfg)
{
	BasicBlock *bb;
	int32 i;

	for(i = 0; i < arraylength(cfg); i++) {
		bb = *(BasicBlock**)arrayget(cfg, i);
		printblock(bb);
	}
}

// Assigns a reverse post order number to each connected basic block using the
// standard algorithm.  Unconnected blocks will not be affected.
static void
reversepostorder(BasicBlock *root, int32 *rpo)
{
	BasicBlock *bb;
	int i;

	root->mark = VISITED;
	for(i = 0; i < arraylength(root->succ); i++) {
		bb = *(BasicBlock**)arrayget(root->succ, i);
		if(bb->mark == UNVISITED)
			reversepostorder(bb, rpo);
	}
	*rpo -= 1;
	root->rpo = *rpo;
}

// Comparison predicate used for sorting basic blocks by their rpo in ascending
// order.
static int
blockrpocmp(const void *p1, const void *p2)
{
	BasicBlock *bb1;
	BasicBlock *bb2;

	bb1 = *(BasicBlock**)p1;
	bb2 = *(BasicBlock**)p2;
	if(bb1->rpo < bb2->rpo)
		return -1;
	if(bb1->rpo > bb2->rpo)
		return 1;
	return 0;
}

// A pattern matcher for call instructions.  Returns true when the instruction
// is a call to a specific package qualified function name.
static int
iscall(Prog *prog, LSym *name)
{
	if(prog == nil)
		fatal("iscall: prog is nil");
	if(name == nil)
		fatal("iscall: function name is nil");
	if(prog->as != ACALL)
		return 0;
	return name == prog->to.sym;
}

// Returns true for instructions that call a runtime function implementing a
// select communication clause.
static int
isselectcommcasecall(Prog *prog)
{
	static LSym* names[5];
	int32 i;

	if(names[0] == nil) {
		names[0] = linksym(pkglookup("selectsend", runtimepkg));
		names[1] = linksym(pkglookup("selectrecv", runtimepkg));
		names[2] = linksym(pkglookup("selectrecv2", runtimepkg));
		names[3] = linksym(pkglookup("selectdefault", runtimepkg));
	}
	for(i = 0; names[i] != nil; i++)
		if(iscall(prog, names[i]))
			return 1;
	return 0;
}

// Returns true for call instructions that target runtime·newselect.
static int
isnewselect(Prog *prog)
{
	static LSym *sym;

	if(sym == nil)
		sym = linksym(pkglookup("newselect", runtimepkg));
	return iscall(prog, sym);
}

// Returns true for call instructions that target runtime·selectgo.
static int
isselectgocall(Prog *prog)
{
	static LSym *sym;

	if(sym == nil)
		sym = linksym(pkglookup("selectgo", runtimepkg));
	return iscall(prog, sym);
}

static int
isdeferreturn(Prog *prog)
{
	static LSym *sym;

	if(sym == nil)
		sym = linksym(pkglookup("deferreturn", runtimepkg));
	return iscall(prog, sym);
}

// Walk backwards from a runtime·selectgo call up to its immediately dominating
// runtime·newselect call.  Any successor nodes of communication clause nodes
// are implicit successors of the runtime·selectgo call node.  The goal of this
// analysis is to add these missing edges to complete the control flow graph.
static void
addselectgosucc(BasicBlock *selectgo)
{
	BasicBlock *pred;
	BasicBlock *succ;

	pred = selectgo;
	for(;;) {
		if(arraylength(pred->pred) == 0)
			fatal("selectgo does not have a newselect");
		pred = *(BasicBlock**)arrayget(pred->pred, 0);
		if(blockany(pred, isselectcommcasecall)) {
			// A select comm case block should have exactly one
			// successor.
			if(arraylength(pred->succ) != 1)
				fatal("select comm case has too many successors");
			succ = *(BasicBlock**)arrayget(pred->succ, 0);
			// Its successor should have exactly two successors.
			// The drop through should flow to the selectgo block
			// and the branch should lead to the select case
			// statements block.
			if(arraylength(succ->succ) != 2)
				fatal("select comm case successor has too many successors");
			// Add the block as a successor of the selectgo block.
			addedge(selectgo, succ);
		}
		if(blockany(pred, isnewselect)) {
			// Reached the matching newselect.
			break;
		}
	}
}

// The entry point for the missing selectgo control flow algorithm.  Takes an
// array of BasicBlock*s containing selectgo calls.
static void
fixselectgo(Array *selectgo)
{
	BasicBlock *bb;
	int32 i;

	for(i = 0; i < arraylength(selectgo); i++) {
		bb = *(BasicBlock**)arrayget(selectgo, i);
		addselectgosucc(bb);
	}
}

// Constructs a control flow graph from a sequence of instructions.  This
// procedure is complicated by various sources of implicit control flow that are
// not accounted for using the standard cfg construction algorithm.  Returns an
// array of BasicBlock*s in control flow graph form (basic blocks ordered by
// their RPO number).
static Array*
newcfg(Prog *firstp)
{
	Prog *p;
	Prog *prev;
	BasicBlock *bb;
	Array *cfg;
	Array *selectgo;
	int32 i;
	int32 rpo;

	// Reset the opt field of each prog to nil.  In the first and second
	// passes, instructions that are labels temporarily use the opt field to
	// point to their basic block.  In the third pass, the opt field reset
	// to point to the predecessor of an instruction in its basic block.
	for(p = firstp; p != P; p = p->link)
		p->opt = nil;

	// Allocate an array to remember where we have seen selectgo calls.
	// These blocks will be revisited to add successor control flow edges.
	selectgo = arraynew(0, sizeof(BasicBlock*));

	// Loop through all instructions identifying branch targets
	// and fall-throughs and allocate basic blocks.
	cfg = arraynew(0, sizeof(BasicBlock*));
	bb = newblock(firstp);
	arrayadd(cfg, &bb);
	for(p = firstp; p != P; p = p->link) {
		if(p->to.type == D_BRANCH) {
			if(p->to.u.branch == nil)
				fatal("prog branch to nil");
			if(p->to.u.branch->opt == nil) {
				p->to.u.branch->opt = newblock(p->to.u.branch);
				arrayadd(cfg, &p->to.u.branch->opt);
			}
			if(p->as != AJMP && p->link != nil && p->link->opt == nil) {
				p->link->opt = newblock(p->link);
				arrayadd(cfg, &p->link->opt);
			}
		} else if(isselectcommcasecall(p) || isselectgocall(p)) {
			// Accommodate implicit selectgo control flow.
			if(p->link->opt == nil) {
				p->link->opt = newblock(p->link);
				arrayadd(cfg, &p->link->opt);
			}
		}
	}

	// Loop through all basic blocks maximally growing the list of
	// contained instructions until a label is reached.  Add edges
	// for branches and fall-through instructions.
	for(i = 0; i < arraylength(cfg); i++) {
		bb = *(BasicBlock**)arrayget(cfg, i);
		for(p = bb->last; p != nil; p = p->link) {
			if(p->opt != nil && p != bb->last)
				break;
			bb->last = p;

			// Stop before an unreachable RET, to avoid creating
			// unreachable control flow nodes.
			if(p->link != nil && p->link->as == ARET && p->link->mode == 1)
				break;

			// Collect basic blocks with selectgo calls.
			if(isselectgocall(p))
				arrayadd(selectgo, &bb);
		}
		if(bb->last->to.type == D_BRANCH)
			addedge(bb, bb->last->to.u.branch->opt);
		if(bb->last->link != nil) {
			// Add a fall-through when the instruction is
			// not an unconditional control transfer.
			switch(bb->last->as) {
			case AJMP:
			case ARET:
			case AUNDEF:
				break;
			default:
				addedge(bb, bb->last->link->opt);
			}
		}
	}

	// Add back links so the instructions in a basic block can be traversed
	// backward.  This is the final state of the instruction opt field.
	for(i = 0; i < arraylength(cfg); i++) {
		bb = *(BasicBlock**)arrayget(cfg, i);
		p = bb->first;
		prev = nil;
		for(;;) {
			p->opt = prev;
			if(p == bb->last)
				break;
			prev = p;
			p = p->link;
		}
	}

	// Add missing successor edges to the selectgo blocks.
	if(arraylength(selectgo))
		fixselectgo(selectgo);
	arrayfree(selectgo);

	// Find a depth-first order and assign a depth-first number to
	// all basic blocks.
	for(i = 0; i < arraylength(cfg); i++) {
		bb = *(BasicBlock**)arrayget(cfg, i);
		bb->mark = UNVISITED;
	}
	bb = *(BasicBlock**)arrayget(cfg, 0);
	rpo = arraylength(cfg);
	reversepostorder(bb, &rpo);

	// Sort the basic blocks by their depth first number.  The
	// array is now a depth-first spanning tree with the first
	// node being the root.
	arraysort(cfg, blockrpocmp);
	bb = *(BasicBlock**)arrayget(cfg, 0);

	// Unreachable control flow nodes are indicated by a -1 in the rpo
	// field.  If we see these nodes something must have gone wrong in an
	// upstream compilation phase.
	if(bb->rpo == -1) {
		print("newcfg: unreachable basic block for %P\n", bb->last);
		printcfg(cfg);
		fatal("newcfg: invalid control flow graph");
	}

	return cfg;
}

// Frees a control flow graph (an array of BasicBlock*s) and all of its leaf
// data structures.
static void
freecfg(Array *cfg)
{
	BasicBlock *bb;
	BasicBlock *bb0;
	Prog *p;
	int32 i;
	int32 len;

	len = arraylength(cfg);
	if(len > 0) {
		bb0 = *(BasicBlock**)arrayget(cfg, 0);
		for(p = bb0->first; p != P; p = p->link) {
			p->opt = nil;
		}
		for(i = 0; i < len; i++) {
			bb = *(BasicBlock**)arrayget(cfg, i);
			freeblock(bb);
		}
	}
	arrayfree(cfg);
}

// Returns true if the node names a variable that is otherwise uninteresting to
// the liveness computation.
static int
isfunny(Node *node)
{
	char *names[] = { ".fp", ".args", nil };
	int i;

	if(node->sym != nil && node->sym->name != nil)
		for(i = 0; names[i] != nil; i++)
			if(strcmp(node->sym->name, names[i]) == 0)
				return 1;
	return 0;
}

// Computes the effects of an instruction on a set of
// variables.  The vars argument is an array of Node*s.
//
// The output vectors give bits for variables:
//	uevar - used by this instruction
//	varkill - killed by this instruction
//		for variables without address taken, means variable was set
//		for variables with address taken, means variable was marked dead
//	avarinit - initialized or referred to by this instruction,
//		only for variables with address taken but not escaping to heap
//
// The avarinit output serves as a signal that the data has been
// initialized, because any use of a variable must come after its
// initialization.
static void
progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill, Bvec *avarinit)
{
	ProgInfo info;
	Adr *from;
	Adr *to;
	Node *node;
	int32 i;
	int32 pos;

	bvresetall(uevar);
	bvresetall(varkill);
	bvresetall(avarinit);

	proginfo(&info, prog);
	if(prog->as == ARET) {
		// Return instructions implicitly read all the arguments.  For
		// the sake of correctness, out arguments must be read.  For the
		// sake of backtrace quality, we read in arguments as well.
		//
		// A return instruction with a p->to is a tail return, which brings
		// the stack pointer back up (if it ever went down) and then jumps
		// to a new function entirely. That form of instruction must read
		// all the parameters for correctness, and similarly it must not
		// read the out arguments - they won't be set until the new
		// function runs.
		for(i = 0; i < arraylength(vars); i++) {
			node = *(Node**)arrayget(vars, i);
			switch(node->class & ~PHEAP) {
			case PPARAM:
				bvset(uevar, i);
				break;
			case PPARAMOUT:
				// If the result had its address taken, it is being tracked
				// by the avarinit code, which does not use uevar.
				// If we added it to uevar too, we'd not see any kill
				// and decide that the varible was live entry, which it is not.
				// So only use uevar in the non-addrtaken case.
				// The p->to.type == D_NONE limits the bvset to
				// non-tail-call return instructions; see note above
				// the for loop for details.
				if(!node->addrtaken && prog->to.type == D_NONE)
					bvset(uevar, i);
				break;
			}
		}
		return;
	}
	if(prog->as == ATEXT) {
		// A text instruction marks the entry point to a function and
		// the definition point of all in arguments.
		for(i = 0; i < arraylength(vars); i++) {
			node = *(Node**)arrayget(vars, i);
			switch(node->class & ~PHEAP) {
			case PPARAM:
				if(node->addrtaken)
					bvset(avarinit, i);
				bvset(varkill, i);
				break;
			}
		}
		return;
	}
	if(info.flags & (LeftRead | LeftWrite | LeftAddr)) {
		from = &prog->from;
		if (from->node != nil && from->sym != nil) {
			switch(from->node->class & ~PHEAP) {
			case PAUTO:
			case PPARAM:
			case PPARAMOUT:
				pos = arrayindexof(vars, from->node);
				if(pos == -1)
					goto Next;
				if(from->node->addrtaken) {
					bvset(avarinit, pos);
				} else {
					if(info.flags & (LeftRead | LeftAddr))
						bvset(uevar, pos);
					if(info.flags & LeftWrite)
						if(from->node != nil && !isfat(from->node->type))
							bvset(varkill, pos);
				}
			}
		}
	}
Next:
	if(info.flags & (RightRead | RightWrite | RightAddr)) {
		to = &prog->to;
		if (to->node != nil && to->sym != nil) {
			switch(to->node->class & ~PHEAP) {
			case PAUTO:
			case PPARAM:
			case PPARAMOUT:
				pos = arrayindexof(vars, to->node);
				if(pos == -1)
					goto Next1;
				if(to->node->addrtaken) {
					if(prog->as != AVARKILL)
						bvset(avarinit, pos);
					if(prog->as == AVARDEF || prog->as == AVARKILL)
						bvset(varkill, pos);
				} else {
					// RightRead is a read, obviously.
					// RightAddr by itself is also implicitly a read.
					//
					// RightAddr|RightWrite means that the address is being taken
					// but only so that the instruction can write to the value.
					// It is not a read. It is equivalent to RightWrite except that
					// having the RightAddr bit set keeps the registerizer from
					// trying to substitute a register for the memory location.
					if((info.flags & RightRead) || (info.flags & (RightAddr|RightWrite)) == RightAddr)
						bvset(uevar, pos);
					if(info.flags & RightWrite)
						if(to->node != nil && (!isfat(to->node->type) || prog->as == AVARDEF))
							bvset(varkill, pos);
				}
			}
		}
	}
Next1:;
}

// Constructs a new liveness structure used to hold the global state of the
// liveness computation.  The cfg argument is an array of BasicBlock*s and the
// vars argument is an array of Node*s.
static Liveness*
newliveness(Node *fn, Prog *ptxt, Array *cfg, Array *vars)
{
	Liveness *result;
	int32 i;
	int32 nblocks;
	int32 nvars;

	result = xmalloc(sizeof(*result));
	result->fn = fn;
	result->ptxt = ptxt;
	result->cfg = cfg;
	result->vars = vars;

	nblocks = arraylength(cfg);
	result->uevar = xmalloc(sizeof(Bvec*) * nblocks);
	result->varkill = xmalloc(sizeof(Bvec*) * nblocks);
	result->livein = xmalloc(sizeof(Bvec*) * nblocks);
	result->liveout = xmalloc(sizeof(Bvec*) * nblocks);
	result->avarinit = xmalloc(sizeof(Bvec*) * nblocks);
	result->avarinitany = xmalloc(sizeof(Bvec*) * nblocks);
	result->avarinitall = xmalloc(sizeof(Bvec*) * nblocks);

	nvars = arraylength(vars);
	for(i = 0; i < nblocks; i++) {
		result->uevar[i] = bvalloc(nvars);
		result->varkill[i] = bvalloc(nvars);
		result->livein[i] = bvalloc(nvars);
		result->liveout[i] = bvalloc(nvars);
		result->avarinit[i] = bvalloc(nvars);
		result->avarinitany[i] = bvalloc(nvars);
		result->avarinitall[i] = bvalloc(nvars);
	}

	result->livepointers = arraynew(0, sizeof(Bvec*));
	result->argslivepointers = arraynew(0, sizeof(Bvec*));
	return result;
}

// Frees the liveness structure and all of its leaf data structures.
static void
freeliveness(Liveness *lv)
{
	int32 i;

	if(lv == nil)
		fatal("freeliveness: cannot free nil");

	for(i = 0; i < arraylength(lv->livepointers); i++)
		free(*(Bvec**)arrayget(lv->livepointers, i));
	arrayfree(lv->livepointers);

	for(i = 0; i < arraylength(lv->argslivepointers); i++)
		free(*(Bvec**)arrayget(lv->argslivepointers, i));
	arrayfree(lv->argslivepointers);

	for(i = 0; i < arraylength(lv->cfg); i++) {
		free(lv->uevar[i]);
		free(lv->varkill[i]);
		free(lv->livein[i]);
		free(lv->liveout[i]);
		free(lv->avarinit[i]);
		free(lv->avarinitany[i]);
		free(lv->avarinitall[i]);
	}

	free(lv->uevar);
	free(lv->varkill);
	free(lv->livein);
	free(lv->liveout);
	free(lv->avarinit);
	free(lv->avarinitany);
	free(lv->avarinitall);

	free(lv);
}

static void
printeffects(Prog *p, Bvec *uevar, Bvec *varkill, Bvec *avarinit)
{
	print("effects of %P", p);
	print("\nuevar: ");
	bvprint(uevar);
	print("\nvarkill: ");
	bvprint(varkill);
	print("\navarinit: ");
	bvprint(avarinit);
	print("\n");
}

// Pretty print a variable node.  Uses Pascal like conventions for pointers and
// addresses to avoid confusing the C like conventions used in the node variable
// names.
static void
printnode(Node *node)
{
	char *p;
	char *a;

	p = haspointers(node->type) ? "^" : "";
	a = node->addrtaken ? "@" : "";
	print(" %N%s%s", node, p, a);
}

// Pretty print a list of variables.  The vars argument is an array of Node*s.
static void
printvars(char *name, Bvec *bv, Array *vars)
{
	int32 i;

	print("%s:", name);
	for(i = 0; i < arraylength(vars); i++)
		if(bvget(bv, i))
			printnode(*(Node**)arrayget(vars, i));
	print("\n");
}

// Prints a basic block annotated with the information computed by liveness
// analysis.
static void
livenessprintblock(Liveness *lv, BasicBlock *bb)
{
	BasicBlock *pred;
	BasicBlock *succ;
	Prog *prog;
	Bvec *live;
	int i;
	int32 pos;

	print("basic block %d\n", bb->rpo);

	print("\tpred:");
	for(i = 0; i < arraylength(bb->pred); i++) {
		pred = *(BasicBlock**)arrayget(bb->pred, i);
		print(" %d", pred->rpo);
	}
	print("\n");

	print("\tsucc:");
	for(i = 0; i < arraylength(bb->succ); i++) {
		succ = *(BasicBlock**)arrayget(bb->succ, i);
		print(" %d", succ->rpo);
	}
	print("\n");

	printvars("\tuevar", lv->uevar[bb->rpo], lv->vars);
	printvars("\tvarkill", lv->varkill[bb->rpo], lv->vars);
	printvars("\tlivein", lv->livein[bb->rpo], lv->vars);
	printvars("\tliveout", lv->liveout[bb->rpo], lv->vars);
	printvars("\tavarinit", lv->avarinit[bb->rpo], lv->vars);
	printvars("\tavarinitany", lv->avarinitany[bb->rpo], lv->vars);
	printvars("\tavarinitall", lv->avarinitall[bb->rpo], lv->vars);

	print("\tprog:\n");
	for(prog = bb->first;; prog = prog->link) {
		print("\t\t%P", prog);
		if(prog->as == APCDATA && prog->from.offset == PCDATA_StackMapIndex) {
			pos = prog->to.offset;
			live = *(Bvec**)arrayget(lv->livepointers, pos);
			print(" ");
			bvprint(live);
		}
		print("\n");
		if(prog == bb->last)
			break;
	}
}

// Prints a control flow graph annotated with any information computed by
// liveness analysis.
static void
livenessprintcfg(Liveness *lv)
{
	BasicBlock *bb;
	int32 i;

	for(i = 0; i < arraylength(lv->cfg); i++) {
		bb = *(BasicBlock**)arrayget(lv->cfg, i);
		livenessprintblock(lv, bb);
	}
}

static void
checkauto(Node *fn, Prog *p, Node *n)
{
	NodeList *l;

	for(l = fn->dcl; l != nil; l = l->next)
		if(l->n->op == ONAME && l->n->class == PAUTO && l->n == n)
			return;

	print("checkauto %N: %N (%p; class=%d) not found in %P\n", curfn, n, n, n->class, p);
	for(l = fn->dcl; l != nil; l = l->next)
		print("\t%N (%p; class=%d)\n", l->n, l->n, l->n->class);
	yyerror("checkauto: invariant lost");
}

static void
checkparam(Node *fn, Prog *p, Node *n)
{
	NodeList *l;
	Node *a;
	int class;

	if(isfunny(n))
		return;
	for(l = fn->dcl; l != nil; l = l->next) {
		a = l->n;
		class = a->class & ~PHEAP;
		if(a->op == ONAME && (class == PPARAM || class == PPARAMOUT) && a == n)
			return;
	}

	print("checkparam %N: %N (%p; class=%d) not found in %P\n", curfn, n, n, n->class, p);
	for(l = fn->dcl; l != nil; l = l->next)
		print("\t%N (%p; class=%d)\n", l->n, l->n, l->n->class);
	yyerror("checkparam: invariant lost");
}

static void
checkprog(Node *fn, Prog *p)
{
	if(p->from.type == D_AUTO)
		checkauto(fn, p, p->from.node);
	if(p->from.type == D_PARAM)
		checkparam(fn, p, p->from.node);
	if(p->to.type == D_AUTO)
		checkauto(fn, p, p->to.node);
	if(p->to.type == D_PARAM)
		checkparam(fn, p, p->to.node);
}

// Check instruction invariants.  We assume that the nodes corresponding to the
// sources and destinations of memory operations will be declared in the
// function.  This is not strictly true, as is the case for the so-called funny
// nodes and there are special cases to skip over that stuff.  The analysis will
// fail if this invariant blindly changes.
static void
checkptxt(Node *fn, Prog *firstp)
{
	Prog *p;

	for(p = firstp; p != P; p = p->link) {
		if(0)
			print("analyzing '%P'\n", p);
		switch(p->as) {
		case ADATA:
		case AGLOBL:
		case ANAME:
		case ASIGNAME:
		case ATYPE:
			continue;
		}
		checkprog(fn, p);
	}
}

// NOTE: The bitmap for a specific type t should be cached in t after the first run
// and then simply copied into bv at the correct offset on future calls with
// the same type t. On https://rsc.googlecode.com/hg/testdata/slow.go, twobitwalktype1
// accounts for 40% of the 6g execution time.
static void
twobitwalktype1(Type *t, vlong *xoffset, Bvec *bv)
{
	vlong fieldoffset;
	vlong i;
	vlong o;
	Type *t1;

	if(t->align > 0 && (*xoffset & (t->align - 1)) != 0)
		fatal("twobitwalktype1: invalid initial alignment, %T", t);

	switch(t->etype) {
	case TINT8:
	case TUINT8:
	case TINT16:
	case TUINT16:
	case TINT32:
	case TUINT32:
	case TINT64:
	case TUINT64:
	case TINT:
	case TUINT:
	case TUINTPTR:
	case TBOOL:
	case TFLOAT32:
	case TFLOAT64:
	case TCOMPLEX64:
	case TCOMPLEX128:
		for(i = 0; i < t->width; i++) {
			bvset(bv, ((*xoffset + i) / widthptr) * BitsPerPointer); // 1 = live scalar
		}
		*xoffset += t->width;
		break;

	case TPTR32:
	case TPTR64:
	case TUNSAFEPTR:
	case TFUNC:
	case TCHAN:
	case TMAP:
		if((*xoffset & (widthptr-1)) != 0)
			fatal("twobitwalktype1: invalid alignment, %T", t);
		bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 1); // 2 = live ptr
		*xoffset += t->width;
		break;

	case TSTRING:
		// struct { byte *str; intgo len; }
		if((*xoffset & (widthptr-1)) != 0)
			fatal("twobitwalktype1: invalid alignment, %T", t);
		bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 0);
		bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 1); // 3:0 = multiword:string
		*xoffset += t->width;
		break;

	case TINTER:
		// struct { Itab *tab;	union { void *ptr, uintptr val } data; }
		// or, when isnilinter(t)==true:
		// struct { Type *type; union { void *ptr, uintptr val } data; }
		if((*xoffset & (widthptr-1)) != 0)
			fatal("twobitwalktype1: invalid alignment, %T", t);
		bvset(bv, ((*xoffset / widthptr) * BitsPerPointer) + 0);
		bvset(bv, ((*xoffset / widthptr) * BitsPerPointer) + 1); // 3 = multiword
		// next word contains 2 = Iface, 3 = Eface
		if(isnilinter(t)) {
			bvset(bv, ((*xoffset / widthptr) * BitsPerPointer) + 2);
			bvset(bv, ((*xoffset / widthptr) * BitsPerPointer) + 3);
		} else {
			bvset(bv, ((*xoffset / widthptr) * BitsPerPointer) + 3);
		}
		*xoffset += t->width;
		break;

	case TARRAY:
		// The value of t->bound is -1 for slices types and >0 for
		// for fixed array types.  All other values are invalid.
		if(t->bound < -1)
			fatal("twobitwalktype1: invalid bound, %T", t);
		if(isslice(t)) {
			// struct { byte *array; uintgo len; uintgo cap; }
			if((*xoffset & (widthptr-1)) != 0)
				fatal("twobitwalktype1: invalid TARRAY alignment, %T", t);
			bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 0);
			bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 1);
			bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 2); // 3:1 = multiword/slice
			*xoffset += t->width;
		} else
			for(i = 0; i < t->bound; i++)
				twobitwalktype1(t->type, xoffset, bv);
		break;

	case TSTRUCT:
		o = 0;
		for(t1 = t->type; t1 != T; t1 = t1->down) {
			fieldoffset = t1->width;
			*xoffset += fieldoffset - o;
			twobitwalktype1(t1->type, xoffset, bv);
			o = fieldoffset + t1->type->width;
		}
		*xoffset += t->width - o;
		break;

	default:
		fatal("twobitwalktype1: unexpected type, %T", t);
	}
}

// Returns the number of words of local variables.
static int32
localswords(void)
{
	return stkptrsize / widthptr;
}

// Returns the number of words of in and out arguments.
static int32
argswords(void)
{
	return curfn->type->argwid / widthptr;
}

// Generates live pointer value maps for arguments and local variables.  The
// this argument and the in arguments are always assumed live.  The vars
// argument is an array of Node*s.
static void
twobitlivepointermap(Liveness *lv, Bvec *liveout, Array *vars, Bvec *args, Bvec *locals)
{
	Node *node;
	Type *thisargtype;
	Type *inargtype;
	vlong xoffset;
	int32 i;

	for(i = 0; i < arraylength(vars); i++) {
		node = *(Node**)arrayget(vars, i);
		switch(node->class) {
		case PAUTO:
			if(bvget(liveout, i)) {
				xoffset = node->xoffset + stkptrsize;
				twobitwalktype1(node->type, &xoffset, locals);
			}
			break;
		case PPARAM:
		case PPARAMOUT:
			if(bvget(liveout, i)) {
				xoffset = node->xoffset;
				twobitwalktype1(node->type, &xoffset, args);
			}
			break;
		}
	}
	
	// The node list only contains declared names.
	// If the receiver or arguments are unnamed, they will be omitted
	// from the list above. Preserve those values - even though they are unused -
	// in order to keep their addresses live for use in stack traces.
	thisargtype = getthisx(lv->fn->type);
	if(thisargtype != nil) {
		xoffset = 0;
		twobitwalktype1(thisargtype, &xoffset, args);
	}
	inargtype = getinargx(lv->fn->type);
	if(inargtype != nil) {
		xoffset = 0;
		twobitwalktype1(inargtype, &xoffset, args);
	}
}

// Construct a disembodied instruction.
static Prog*
unlinkedprog(int as)
{
	Prog *p;

	p = mal(sizeof(*p));
	clearp(p);
	p->as = as;
	return p;
}

// Construct a new PCDATA instruction associated with and for the purposes of
// covering an existing instruction.
static Prog*
newpcdataprog(Prog *prog, int32 index)
{
	Node from, to;
	Prog *pcdata;

	nodconst(&from, types[TINT32], PCDATA_StackMapIndex);
	nodconst(&to, types[TINT32], index);
	pcdata = unlinkedprog(APCDATA);
	pcdata->lineno = prog->lineno;
	naddr(&from, &pcdata->from, 0);
	naddr(&to, &pcdata->to, 0);
	return pcdata;
}

// Returns true for instructions that are safe points that must be annotated
// with liveness information.
static int
issafepoint(Prog *prog)
{
	return prog->as == ATEXT || prog->as == ACALL;
}

// Initializes the sets for solving the live variables.  Visits all the
// instructions in each basic block to summarizes the information at each basic
// block
static void
livenessprologue(Liveness *lv)
{
	BasicBlock *bb;
	Bvec *uevar, *varkill, *avarinit;
	Prog *p;
	int32 i;
	int32 nvars;

	nvars = arraylength(lv->vars);
	uevar = bvalloc(nvars);
	varkill = bvalloc(nvars);
	avarinit = bvalloc(nvars);
	for(i = 0; i < arraylength(lv->cfg); i++) {
		bb = *(BasicBlock**)arrayget(lv->cfg, i);
		// Walk the block instructions backward and update the block
		// effects with the each prog effects.
		for(p = bb->last; p != nil; p = p->opt) {
			progeffects(p, lv->vars, uevar, varkill, avarinit);
			if(debuglive >= 3)
				printeffects(p, uevar, varkill, avarinit);
			bvor(lv->varkill[i], lv->varkill[i], varkill);
			bvandnot(lv->uevar[i], lv->uevar[i], varkill);
			bvor(lv->uevar[i], lv->uevar[i], uevar);			
		}
		// Walk the block instructions forward to update avarinit bits.
		// avarinit describes the effect at the end of the block, not the beginning.
		bvresetall(varkill);
		for(p = bb->first;; p = p->link) {
			progeffects(p, lv->vars, uevar, varkill, avarinit);
			if(debuglive >= 3)
				printeffects(p, uevar, varkill, avarinit);
			bvandnot(lv->avarinit[i], lv->avarinit[i], varkill);
			bvor(lv->avarinit[i], lv->avarinit[i], avarinit);
			if(p == bb->last)
				break;
		}
	}
	free(uevar);
	free(varkill);
	free(avarinit);
}

// Solve the liveness dataflow equations.
static void
livenesssolve(Liveness *lv)
{
	BasicBlock *bb, *succ, *pred;
	Bvec *newlivein, *newliveout, *any, *all;
	int32 rpo, i, j, change;

	// These temporary bitvectors exist to avoid successive allocations and
	// frees within the loop.
	newlivein = bvalloc(arraylength(lv->vars));
	newliveout = bvalloc(arraylength(lv->vars));
	any = bvalloc(arraylength(lv->vars));
	all = bvalloc(arraylength(lv->vars));

	// Push avarinitall, avarinitany forward.
	// avarinitall says the addressed var is initialized along all paths reaching the block exit.
	// avarinitany says the addressed var is initialized along some path reaching the block exit.
	for(i = 0; i < arraylength(lv->cfg); i++) {
		bb = *(BasicBlock**)arrayget(lv->cfg, i);
		rpo = bb->rpo;
		if(i == 0)
			bvcopy(lv->avarinitall[rpo], lv->avarinit[rpo]);
		else {
			bvresetall(lv->avarinitall[rpo]);
			bvnot(lv->avarinitall[rpo]);
		}
		bvcopy(lv->avarinitany[rpo], lv->avarinit[rpo]);
	}

	change = 1;
	while(change != 0) {
		change = 0;
		for(i = 0; i < arraylength(lv->cfg); i++) {
			bb = *(BasicBlock**)arrayget(lv->cfg, i);
			rpo = bb->rpo;
			bvresetall(any);
			bvresetall(all);
			for(j = 0; j < arraylength(bb->pred); j++) {
				pred = *(BasicBlock**)arrayget(bb->pred, j);
				if(j == 0) {
					bvcopy(any, lv->avarinitany[pred->rpo]);
					bvcopy(all, lv->avarinitall[pred->rpo]);
				} else {
					bvor(any, any, lv->avarinitany[pred->rpo]);
					bvand(all, all, lv->avarinitall[pred->rpo]);
				}
			}
			bvandnot(any, any, lv->varkill[rpo]);
			bvandnot(all, all, lv->varkill[rpo]);
			bvor(any, any, lv->avarinit[rpo]);
			bvor(all, all, lv->avarinit[rpo]);
			if(bvcmp(any, lv->avarinitany[rpo])) {
				change = 1;
				bvcopy(lv->avarinitany[rpo], any);
			}
			if(bvcmp(all, lv->avarinitall[rpo])) {
				change = 1;
				bvcopy(lv->avarinitall[rpo], all);
			}
		}
	}

	// Iterate through the blocks in reverse round-robin fashion.  A work
	// queue might be slightly faster.  As is, the number of iterations is
	// so low that it hardly seems to be worth the complexity.
	change = 1;
	while(change != 0) {
		change = 0;
		// Walk blocks in the general direction of propagation.  This
		// improves convergence.
		for(i = arraylength(lv->cfg) - 1; i >= 0; i--) {
			// A variable is live on output from this block
			// if it is live on input to some successor.
			//
			// out[b] = \bigcup_{s \in succ[b]} in[s]
			bb = *(BasicBlock**)arrayget(lv->cfg, i);
			rpo = bb->rpo;
			bvresetall(newliveout);
			for(j = 0; j < arraylength(bb->succ); j++) {
				succ = *(BasicBlock**)arrayget(bb->succ, j);
				bvor(newliveout, newliveout, lv->livein[succ->rpo]);
			}
			if(bvcmp(lv->liveout[rpo], newliveout)) {
				change = 1;
				bvcopy(lv->liveout[rpo], newliveout);
			}

			// A variable is live on input to this block
			// if it is live on output from this block and
			// not set by the code in this block.
			//
			// in[b] = uevar[b] \cup (out[b] \setminus varkill[b])
			bvandnot(newlivein, lv->liveout[rpo], lv->varkill[rpo]);
			bvor(lv->livein[rpo], newlivein, lv->uevar[rpo]);
		}
	}

	free(newlivein);
	free(newliveout);
	free(any);
	free(all);
}

// This function is slow but it is only used for generating debug prints.
// Check whether n is marked live in args/locals.
static int
islive(Node *n, Bvec *args, Bvec *locals)
{
	int i;

	switch(n->class) {
	case PPARAM:
	case PPARAMOUT:
		for(i = 0; i < n->type->width/widthptr*BitsPerPointer; i++)
			if(bvget(args, n->xoffset/widthptr*BitsPerPointer + i))
				return 1;
		break;
	case PAUTO:
		for(i = 0; i < n->type->width/widthptr*BitsPerPointer; i++)
			if(bvget(locals, (n->xoffset + stkptrsize)/widthptr*BitsPerPointer + i))
				return 1;
		break;
	}
	return 0;
}

// Visits all instructions in a basic block and computes a bit vector of live
// variables at each safe point locations.
static void
livenessepilogue(Liveness *lv)
{
	BasicBlock *bb, *pred;
	Bvec *ambig, *livein, *liveout, *uevar, *varkill, *args, *locals, *avarinit, *any, *all;
	Node *n;
	Prog *p, *next;
	int32 i, j, numlive, startmsg, nmsg, nvars, pos;
	vlong xoffset;
	char **msg;
	Fmt fmt;

	nvars = arraylength(lv->vars);
	livein = bvalloc(nvars);
	liveout = bvalloc(nvars);
	uevar = bvalloc(nvars);
	varkill = bvalloc(nvars);
	avarinit = bvalloc(nvars);
	any = bvalloc(nvars);
	all = bvalloc(nvars);
	ambig = bvalloc(localswords() * BitsPerPointer);
	msg = nil;
	nmsg = 0;
	startmsg = 0;

	for(i = 0; i < arraylength(lv->cfg); i++) {
		bb = *(BasicBlock**)arrayget(lv->cfg, i);
		
		// Compute avarinitany and avarinitall for entry to block.
		// This duplicates information known during livenesssolve
		// but avoids storing two more vectors for each block.
		bvresetall(any);
		bvresetall(all);
		for(j = 0; j < arraylength(bb->pred); j++) {
			pred = *(BasicBlock**)arrayget(bb->pred, j);
			if(j == 0) {
				bvcopy(any, lv->avarinitany[pred->rpo]);
				bvcopy(all, lv->avarinitall[pred->rpo]);
			} else {
				bvor(any, any, lv->avarinitany[pred->rpo]);
				bvand(all, all, lv->avarinitall[pred->rpo]);
			}
		}

		// Walk forward through the basic block instructions and
		// allocate liveness maps for those instructions that need them.
		// Seed the maps with information about the addrtaken variables.
		for(p = bb->first;; p = p->link) {
			progeffects(p, lv->vars, uevar, varkill, avarinit);
			bvandnot(any, any, varkill);
			bvandnot(all, all, varkill);
			bvor(any, any, avarinit);
			bvor(all, all, avarinit);

			if(issafepoint(p)) {
				// Annotate ambiguously live variables so that they can
				// be zeroed at function entry.
				// livein and liveout are dead here and used as temporaries.
				// For now, only enabled when using GOEXPERIMENT=precisestack
				// during make.bash / all.bash.
				if(precisestack_enabled) {
					bvresetall(livein);
					bvandnot(liveout, any, all);
					if(!bvisempty(liveout)) {
						for(pos = 0; pos < liveout->n; pos++) {
							if(!bvget(liveout, pos))
								continue;
							bvset(all, pos); // silence future warnings in this block
							n = *(Node**)arrayget(lv->vars, pos);
							if(!n->needzero) {
								n->needzero = 1;
								if(debuglive >= 1)
									warnl(p->lineno, "%N: %lN is ambiguously live", curfn->nname, n);
								// Record in 'ambiguous' bitmap.
								xoffset = n->xoffset + stkptrsize;
								twobitwalktype1(n->type, &xoffset, ambig);
							}
						}
					}
				}
	
				// Allocate a bit vector for each class and facet of
				// value we are tracking.
	
				// Live stuff first.
				args = bvalloc(argswords() * BitsPerPointer);
				arrayadd(lv->argslivepointers, &args);
				locals = bvalloc(localswords() * BitsPerPointer);
				arrayadd(lv->livepointers, &locals);

				if(debuglive >= 3) {
					print("%P\n", p);
					printvars("avarinitany", any, lv->vars);
				}

				// Record any values with an "address taken" reaching
				// this code position as live. Must do now instead of below
				// because the any/all calculation requires walking forward
				// over the block (as this loop does), while the liveout
				// requires walking backward (as the next loop does).
				twobitlivepointermap(lv, any, lv->vars, args, locals);
			}
			
			if(p == bb->last)
				break;
		}
		bb->lastbitmapindex = arraylength(lv->livepointers) - 1;
	}
	
	for(i = 0; i < arraylength(lv->cfg); i++) {
		bb = *(BasicBlock**)arrayget(lv->cfg, i);
		
		if(debuglive >= 1 && strcmp(curfn->nname->sym->name, "init") != 0 && curfn->nname->sym->name[0] != '.') {
			nmsg = arraylength(lv->livepointers);
			startmsg = nmsg;
			msg = xmalloc(nmsg*sizeof msg[0]);
			for(j=0; j<nmsg; j++)
				msg[j] = nil;
		}

		// walk backward, emit pcdata and populate the maps
		pos = bb->lastbitmapindex;
		if(pos < 0) {
			// the first block we encounter should have the ATEXT so
			// at no point should pos ever be less than zero.
			fatal("livenessepilogue");
		}

		bvcopy(livein, lv->liveout[bb->rpo]);
		for(p = bb->last; p != nil; p = next) {
			next = p->opt; // splicebefore modifies p->opt
			// Propagate liveness information
			progeffects(p, lv->vars, uevar, varkill, avarinit);
			bvcopy(liveout, livein);
			bvandnot(livein, liveout, varkill);
			bvor(livein, livein, uevar);
			if(debuglive >= 3 && issafepoint(p)){
				print("%P\n", p);
				printvars("uevar", uevar, lv->vars);
				printvars("varkill", varkill, lv->vars);
				printvars("livein", livein, lv->vars);
				printvars("liveout", liveout, lv->vars);
			}
			if(issafepoint(p)) {
				// Found an interesting instruction, record the
				// corresponding liveness information.  
				
				// Useful sanity check: on entry to the function,
				// the only things that can possibly be live are the
				// input parameters.
				if(p->as == ATEXT) {
					for(j = 0; j < liveout->n; j++) {
						if(!bvget(liveout, j))
							continue;
						n = *(Node**)arrayget(lv->vars, j);
						if(n->class != PPARAM)
							yyerrorl(p->lineno, "internal error: %N %lN recorded as live on entry", curfn->nname, n);
					}
				}

				// Record live pointers.
				args = *(Bvec**)arrayget(lv->argslivepointers, pos);
				locals = *(Bvec**)arrayget(lv->livepointers, pos);
				twobitlivepointermap(lv, liveout, lv->vars, args, locals);
				
				// Ambiguously live variables are zeroed immediately after
				// function entry. Mark them live for all the non-entry bitmaps
				// so that GODEBUG=gcdead=1 mode does not poison them.
				if(p->as == ACALL)
					bvor(locals, locals, ambig);

				// Show live pointer bitmaps.
				// We're interpreting the args and locals bitmap instead of liveout so that we
				// include the bits added by the avarinit logic in the
				// previous loop.
				if(msg != nil) {
					fmtstrinit(&fmt);
					fmtprint(&fmt, "%L: live at ", p->lineno);
					if(p->as == ACALL && p->to.node)
						fmtprint(&fmt, "call to %s:", p->to.node->sym->name);
					else if(p->as == ACALL)
						fmtprint(&fmt, "indirect call:");
					else
						fmtprint(&fmt, "entry to %s:", p->from.node->sym->name);
					numlive = 0;
					for(j = 0; j < arraylength(lv->vars); j++) {
						n = *(Node**)arrayget(lv->vars, j);
						if(islive(n, args, locals)) {
							fmtprint(&fmt, " %N", n);
							numlive++;
						}
					}
					fmtprint(&fmt, "\n");
					if(numlive == 0) // squelch message
						free(fmtstrflush(&fmt));
					else
						msg[--startmsg] = fmtstrflush(&fmt);
				}

				// Only CALL instructions need a PCDATA annotation.
				// The TEXT instruction annotation is implicit.
				if(p->as == ACALL) {
					if(isdeferreturn(p)) {
						// runtime.deferreturn modifies its return address to return
						// back to the CALL, not to the subsequent instruction.
						// Because the return comes back one instruction early,
						// the PCDATA must begin one instruction early too.
						// The instruction before a call to deferreturn is always a
						// no-op, to keep PC-specific data unambiguous.
						splicebefore(lv, bb, newpcdataprog(p->opt, pos), p->opt);
					} else {
						splicebefore(lv, bb, newpcdataprog(p, pos), p);
					}
				}

				pos--;
			}
		}
		if(msg != nil) {
			for(j=startmsg; j<nmsg; j++) 
				if(msg[j] != nil)
					print("%s", msg[j]);
			free(msg);
			msg = nil;
			nmsg = 0;
			startmsg = 0;
		}
	}

	free(livein);
	free(liveout);
	free(uevar);
	free(varkill);
	free(avarinit);
	free(any);
	free(all);
	free(ambig);
	
	flusherrors();
}

// FNV-1 hash function constants.
#define H0 2166136261UL
#define Hp 16777619UL

static uint32
hashbitmap(uint32 h, Bvec *bv)
{
	uchar *p, *ep;
	
	p = (uchar*)bv->b;
	ep = p + 4*((bv->n+31)/32);
	while(p < ep)
		h = (h*Hp) ^ *p++;
	return h;
}

// Compact liveness information by coalescing identical per-call-site bitmaps.
// The merging only happens for a single function, not across the entire binary.
//
// There are actually two lists of bitmaps, one list for the local variables and one
// list for the function arguments. Both lists are indexed by the same PCDATA
// index, so the corresponding pairs must be considered together when
// merging duplicates. The argument bitmaps change much less often during
// function execution than the local variable bitmaps, so it is possible that
// we could introduce a separate PCDATA index for arguments vs locals and
// then compact the set of argument bitmaps separately from the set of
// local variable bitmaps. As of 2014-04-02, doing this to the godoc binary
// is actually a net loss: we save about 50k of argument bitmaps but the new
// PCDATA tables cost about 100k. So for now we keep using a single index for
// both bitmap lists.
static void
livenesscompact(Liveness *lv)
{
	int *table, *remap, i, j, n, tablesize, uniq;
	uint32 h;
	Bvec *local, *arg, *jlocal, *jarg;
	Prog *p;

	// Linear probing hash table of bitmaps seen so far.
	// The hash table has 4n entries to keep the linear
	// scan short. An entry of -1 indicates an empty slot.
	n = arraylength(lv->livepointers);
	tablesize = 4*n;
	table = xmalloc(tablesize*sizeof table[0]);
	memset(table, 0xff, tablesize*sizeof table[0]);
	
	// remap[i] = the new index of the old bit vector #i.
	remap = xmalloc(n*sizeof remap[0]);
	memset(remap, 0xff, n*sizeof remap[0]);
	uniq = 0; // unique tables found so far

	// Consider bit vectors in turn.
	// If new, assign next number using uniq,
	// record in remap, record in lv->livepointers and lv->argslivepointers
	// under the new index, and add entry to hash table.
	// If already seen, record earlier index in remap and free bitmaps.
	for(i=0; i<n; i++) {
		local = *(Bvec**)arrayget(lv->livepointers, i);
		arg = *(Bvec**)arrayget(lv->argslivepointers, i);
		h = hashbitmap(hashbitmap(H0, local), arg) % tablesize;

		for(;;) {
			j = table[h];
			if(j < 0)
				break;
			jlocal = *(Bvec**)arrayget(lv->livepointers, j);
			jarg = *(Bvec**)arrayget(lv->argslivepointers, j);
			if(bvcmp(local, jlocal) == 0 && bvcmp(arg, jarg) == 0) {
				free(local);
				free(arg);
				remap[i] = j;
				goto Next;
			}
			if(++h == tablesize)
				h = 0;
		}
		table[h] = uniq;
		remap[i] = uniq;
		*(Bvec**)arrayget(lv->livepointers, uniq) = local;
		*(Bvec**)arrayget(lv->argslivepointers, uniq) = arg;
		uniq++;
	Next:;
	}

	// We've already reordered lv->livepointers[0:uniq]
	// and lv->argslivepointers[0:uniq] and freed the bitmaps
	// we don't need anymore. Clear the pointers later in the
	// array so that we can tell where the coalesced bitmaps stop
	// and so that we don't double-free when cleaning up.
	for(j=uniq; j<n; j++) {
		*(Bvec**)arrayget(lv->livepointers, j) = nil;
		*(Bvec**)arrayget(lv->argslivepointers, j) = nil;
	}
	
	// Rewrite PCDATA instructions to use new numbering.
	for(p=lv->ptxt; p != P; p=p->link) {
		if(p->as == APCDATA && p->from.offset == PCDATA_StackMapIndex) {
			i = p->to.offset;
			if(i >= 0)
				p->to.offset = remap[i];
		}
	}

	free(table);
	free(remap);
}

static int
printbitset(int printed, char *name, Array *vars, Bvec *bits)
{
	int i, started;
	Node *n;

	started = 0;	
	for(i=0; i<arraylength(vars); i++) {
		if(!bvget(bits, i))
			continue;
		if(!started) {
			if(!printed)
				print("\t");
			else
				print(" ");
			started = 1;
			printed = 1;
			print("%s=", name);
		} else {
			print(",");
		}
		n = *(Node**)arrayget(vars, i);
		print("%s", n->sym->name);
	}
	return printed;
}

// Prints the computed liveness information and inputs, for debugging.
// This format synthesizes the information used during the multiple passes
// into a single presentation.
static void
livenessprintdebug(Liveness *lv)
{
	int i, j, pcdata, printed;
	BasicBlock *bb;
	Prog *p;
	Bvec *uevar, *varkill, *avarinit, *args, *locals;
	Node *n;

	print("liveness: %s\n", curfn->nname->sym->name);

	uevar = bvalloc(arraylength(lv->vars));
	varkill = bvalloc(arraylength(lv->vars));
	avarinit = bvalloc(arraylength(lv->vars));

	pcdata = 0;
	for(i = 0; i < arraylength(lv->cfg); i++) {
		if(i > 0)
			print("\n");
		bb = *(BasicBlock**)arrayget(lv->cfg, i);

		// bb#0 pred=1,2 succ=3,4
		print("bb#%d pred=", i);
		for(j = 0; j < arraylength(bb->pred); j++) {
			if(j > 0)
				print(",");
			print("%d", (*(BasicBlock**)arrayget(bb->pred, j))->rpo);
		}
		print(" succ=");
		for(j = 0; j < arraylength(bb->succ); j++) {
			if(j > 0)
				print(",");
			print("%d", (*(BasicBlock**)arrayget(bb->succ, j))->rpo);
		}
		print("\n");
		
		// initial settings
		printed = 0;
		printed = printbitset(printed, "uevar", lv->vars, lv->uevar[bb->rpo]);
		printed = printbitset(printed, "livein", lv->vars, lv->livein[bb->rpo]);
		if(printed)
			print("\n");
		
		// program listing, with individual effects listed
		for(p = bb->first;; p = p->link) {
			print("%P\n", p);
			if(p->as == APCDATA && p->from.offset == PCDATA_StackMapIndex)
				pcdata = p->to.offset;
			progeffects(p, lv->vars, uevar, varkill, avarinit);
			printed = 0;
			printed = printbitset(printed, "uevar", lv->vars, uevar);
			printed = printbitset(printed, "varkill", lv->vars, varkill);
			printed = printbitset(printed, "avarinit", lv->vars, avarinit);
			if(printed)
				print("\n");
			if(issafepoint(p)) {
				args = *(Bvec**)arrayget(lv->argslivepointers, pcdata);
				locals = *(Bvec**)arrayget(lv->livepointers, pcdata);
				print("\tlive=");
				printed = 0;
				for(j = 0; j < arraylength(lv->vars); j++) {
					n = *(Node**)arrayget(lv->vars, j);
					if(islive(n, args, locals)) {
						if(printed++)
							print(",");
						print("%N", n);
					}
				}
				print("\n");
			}
			if(p == bb->last)
				break;
		}
		
		// bb bitsets
		print("end\n");
		printed = printbitset(printed, "varkill", lv->vars, lv->varkill[bb->rpo]);
		printed = printbitset(printed, "liveout", lv->vars, lv->liveout[bb->rpo]);
		printed = printbitset(printed, "avarinit", lv->vars, lv->avarinit[bb->rpo]);
		printed = printbitset(printed, "avarinitany", lv->vars, lv->avarinitany[bb->rpo]);
		printed = printbitset(printed, "avarinitall", lv->vars, lv->avarinitall[bb->rpo]);
		if(printed)
			print("\n");
	}
	print("\n");

	free(uevar);
	free(varkill);
	free(avarinit);
}

// Dumps an array of bitmaps to a symbol as a sequence of uint32 values.  The
// first word dumped is the total number of bitmaps.  The second word is the
// length of the bitmaps.  All bitmaps are assumed to be of equal length.  The
// words that are followed are the raw bitmap words.  The arr argument is an
// array of Node*s.
static void
twobitwritesymbol(Array *arr, Sym *sym)
{
	Bvec *bv;
	int off, i, j, len;
	uint32 word;

	len = arraylength(arr);
	off = 0;
	off += 4; // number of bitmaps, to fill in later
	bv = *(Bvec**)arrayget(arr, 0);
	off = duint32(sym, off, bv->n); // number of bits in each bitmap
	for(i = 0; i < len; i++) {
		// bitmap words
		bv = *(Bvec**)arrayget(arr, i);
		if(bv == nil)
			break;
		for(j = 0; j < bv->n; j += 32) {
			word = bv->b[j/32];
			off = duint32(sym, off, word);
		}
	}
	duint32(sym, 0, i); // number of bitmaps
	ggloblsym(sym, off, 0, 1);
}

static void
printprog(Prog *p)
{
	while(p != nil) {
		print("%P\n", p);
		p = p->link;
	}
}

// Entry pointer for liveness analysis.  Constructs a complete CFG, solves for
// the liveness of pointer variables in the function, and emits a runtime data
// structure read by the garbage collector.
void
liveness(Node *fn, Prog *firstp, Sym *argssym, Sym *livesym)
{
	Array *cfg, *vars;
	Liveness *lv;
	int debugdelta;

	// Change name to dump debugging information only for a specific function.
	debugdelta = 0;
	if(strcmp(curfn->nname->sym->name, "!") == 0)
		debugdelta = 2;
	
	debuglive += debugdelta;
	if(debuglive >= 3) {
		print("liveness: %s\n", curfn->nname->sym->name);
		printprog(firstp);
	}
	checkptxt(fn, firstp);

	// Construct the global liveness state.
	cfg = newcfg(firstp);
	if(debuglive >= 3)
		printcfg(cfg);
	vars = getvariables(fn);
	lv = newliveness(fn, firstp, cfg, vars);

	// Run the dataflow framework.
	livenessprologue(lv);
	if(debuglive >= 3)
		livenessprintcfg(lv);
	livenesssolve(lv);
	if(debuglive >= 3)
		livenessprintcfg(lv);
	livenessepilogue(lv);
	if(debuglive >= 3)
		livenessprintcfg(lv);
	livenesscompact(lv);

	if(debuglive >= 2)
		livenessprintdebug(lv);

	// Emit the live pointer map data structures
	twobitwritesymbol(lv->livepointers, livesym);
	twobitwritesymbol(lv->argslivepointers, argssym);

	// Free everything.
	freeliveness(lv);
	arrayfree(vars);
	freecfg(cfg);
	
	debuglive -= debugdelta;
}
