/* Copyright © International Business Machines Corp., 2006
 *              Adelard LLP, 2007
 *
 * Author: Josh Triplett <josh@freedesktop.org>
 *         Dan Sheridan <djs@adelard.com>
 *
 * Licensed under the Open Software License version 1.1
 */
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>

#include "lib.h"
#include "allocate.h"
#include "token.h"
#include "parse.h"
#include "symbol.h"
#include "expression.h"
#include "linearize.h"


/* Draw the subgraph for a given entrypoint. Includes details of loads
 * and stores for globals, and marks return bbs */
static void graph_ep(struct entrypoint *ep)
{
	struct basic_block *bb;
	struct instruction *insn;

	const char *fname, *sname;

	fname = show_ident(ep->name->ident);
	sname = stream_name(ep->entry->bb->pos.stream);

	printf("subgraph cluster%p {\n"
	       "    color=blue;\n"
	       "    label=<<TABLE BORDER=\"0\" CELLBORDER=\"0\">\n"
	       "             <TR><TD>%s</TD></TR>\n"
	       "             <TR><TD><FONT POINT-SIZE=\"21\">%s()</FONT></TD></TR>\n"
	       "           </TABLE>>;\n"
	       "    file=\"%s\";\n"
	       "    fun=\"%s\";\n"
	       "    ep=bb%p;\n",
	       ep, sname, fname, sname, fname, ep->entry->bb);

	FOR_EACH_PTR(ep->bbs, bb) {
		struct basic_block *child;
		int ret = 0;
		const char * s = ", ls=\"[";

		/* Node for the bb */
		printf("    bb%p [shape=ellipse,label=%d,line=%d,col=%d",
		       bb, bb->pos.line, bb->pos.line, bb->pos.pos);


		/* List loads and stores */
		FOR_EACH_PTR(bb->insns, insn) {
			switch(insn->opcode) {
			case OP_STORE:
				if (insn->symbol->type == PSEUDO_SYM) {
				  printf("%s store(%s)", s, show_ident(insn->symbol->sym->ident));
				  s = ",";
				}
				break;

			case OP_LOAD:
				if (insn->symbol->type == PSEUDO_SYM) {
				  printf("%s load(%s)", s, show_ident(insn->symbol->sym->ident));
				  s = ",";
				}
				break;

			case OP_RET:
				ret = 1;
				break;

			}
		} END_FOR_EACH_PTR(insn);
		if (s[1] == 0)
			printf("]\"");
		if (ret)
			printf(",op=ret");
		printf("];\n");

		/* Edges between bbs; lower weight for upward edges */
		FOR_EACH_PTR(bb->children, child) {
			printf("    bb%p -> bb%p [op=br, %s];\n", bb, child,
			       (bb->pos.line > child->pos.line) ? "weight=5" : "weight=10");
		} END_FOR_EACH_PTR(child);
	} END_FOR_EACH_PTR(bb);

	printf("}\n");
}


/* Insert edges for intra- or inter-file calls, depending on the value
 * of internal. Bold edges are used for calls with destinations;
 * dashed for calls to external functions */
static void graph_calls(struct entrypoint *ep, int internal)
{
	struct basic_block *bb;
	struct instruction *insn;

	const char *fname, *sname;

	fname = show_ident(ep->name->ident);
	sname = stream_name(ep->entry->bb->pos.stream);

	FOR_EACH_PTR(ep->bbs, bb) {
		if (!bb)
			continue;
		if (!bb->parents && !bb->children && !bb->insns && verbose < 2)
			continue;

		FOR_EACH_PTR(bb->insns, insn) {
			if (insn->opcode == OP_CALL &&
			    internal == !(insn->func->sym->ctype.modifiers & MOD_EXTERN)) {

				/* Find the symbol for the callee's definition */
				struct symbol * sym;
				if (insn->func->type == PSEUDO_SYM) {
					for (sym = insn->func->sym->ident->symbols;
					     sym; sym = sym->next_id) {
						if (sym->namespace & NS_SYMBOL && sym->ep)
							break;
					}

					if (sym)
						printf("bb%p -> bb%p"
						       "[label=%d,line=%d,col=%d,op=call,style=bold,weight=30];\n",
						       bb, sym->ep->entry->bb,
						       insn->pos.line, insn->pos.line, insn->pos.pos);
					else
						printf("bb%p -> \"%s\" "
						       "[label=%d,line=%d,col=%d,op=extern,style=dashed];\n",
						       bb, show_pseudo(insn->func),
						       insn->pos.line, insn->pos.line, insn->pos.pos);
				}
			}
		} END_FOR_EACH_PTR(insn);
	} END_FOR_EACH_PTR(bb);
}

int main(int argc, char **argv)
{
	struct string_list *filelist = NULL;
	char *file;
	struct symbol *sym;

	struct symbol_list *fsyms, *all_syms=NULL;

	printf("digraph call_graph {\n");
	fsyms = sparse_initialize(argc, argv, &filelist);
	concat_symbol_list(fsyms, &all_syms);

	/* Linearize all symbols, graph internal basic block
	 * structures and intra-file calls */
	FOR_EACH_PTR_NOTAG(filelist, file) {

		fsyms = sparse(file);
		concat_symbol_list(fsyms, &all_syms);

		FOR_EACH_PTR(fsyms, sym) {
			expand_symbol(sym);
			linearize_symbol(sym);
		} END_FOR_EACH_PTR(sym);

		FOR_EACH_PTR(fsyms, sym) {
			if (sym->ep) {
				graph_ep(sym->ep);
				graph_calls(sym->ep, 1);
			}
		} END_FOR_EACH_PTR_NOTAG(sym);

	} END_FOR_EACH_PTR_NOTAG(file);

	/* Graph inter-file calls */
	FOR_EACH_PTR(all_syms, sym) {
		if (sym->ep)
			graph_calls(sym->ep, 0);
	} END_FOR_EACH_PTR_NOTAG(sym);

	printf("}\n");
	return 0;
}
