--- gcc-3.4.1/gcc/cgraphunit.c	2006-05-03 22:27:52.703183630 +0530
+++ codeviz-1.0.9/compilers/gcc-graph/gcc-3.4.1/gcc/cgraphunit.c	2006-05-03 22:30:24.180169427 +0530
@@ -52,6 +52,12 @@
 static bool cgraph_default_inline_p (struct cgraph_node *n);
 static void cgraph_analyze_function (struct cgraph_node *node);
 static void cgraph_decide_inlining_incrementally (struct cgraph_node *);
+/*AccessViz */
+void read_access (tree body,FILE * fnref_f, tree thisTree);
+void dump_access_info (tree body,FILE * fnref_f, tree thisTree);
+void print_structures (tree field, FILE *fnref_f); 
+void print_arg_structures ( tree args, FILE *fnref_f);
+void find_record (tree arg, FILE *fnref_f);
 
 /* Statistics we collect about inlining algorithm.  */
 static int ncalls_inlined;
@@ -315,18 +321,371 @@
   visited_nodes = NULL;
 }
 
+
+/* AccessViz: Print the fields of a structure */ 
+void print_structures (tree field, FILE *fnref_f) 
+{
+      while(field && (TREE_CODE (field) == FIELD_DECL)) {
+			fprintf(fnref_f, "S {%s} \n", lang_hooks.decl_printable_name (field, 2));
+            if (TREE_CODE (TREE_TYPE (field)) == UNION_TYPE) 
+                print_structures (TYPE_FIELDS (TREE_TYPE (field)),fnref_f); 
+/*            fprintf(fnref_f, "S {%s} \n", lang_hooks.decl_printable_name (DECL_CONTEXT (field),2));*/
+            field = TREE_CHAIN (field);
+      }      
+      return;
+}
+
+/* AccessViz: If a given argument is of type structure, print the fields */
+void find_record (tree arg, FILE *fnref_f)
+{
+    if(arg) {
+    switch (TREE_CODE(arg)) 
+    {
+        case POINTER_TYPE:
+        case REFERENCE_TYPE:          
+            arg= TREE_TYPE(arg);
+	        find_record (arg, fnref_f);
+            return;
+            break;
+
+        case RECORD_TYPE:
+	  //            fprintf(stderr, "record\n");           
+            print_structures (TYPE_FIELDS(arg), fnref_f);
+            return;
+            break;
+
+        default:
+            return;
+            break;
+    }
+       
+    }
+    else
+        return;
+}
+
+/* AccessViz: Traverse the list of arguments of a function */
+void print_arg_structures ( tree args, FILE *fnref_f)
+{
+    while(args && DECL_ARG_TYPE (args))
+    {
+      //        fprintf(stderr, "args\n");
+        find_record(DECL_ARG_TYPE (args),fnref_f);
+        args = TREE_CHAIN (args);
+    }
+            
+}
+
+/* AccessViz : Function to find the globals, arguments being read */
+void read_access (tree body,FILE * fnref_f, tree thisTree)
+ {
+      tree expr,cont;	
+      while (body) {		
+      switch (TREE_CODE (body))
+	{
+	  case COMPOUND_STMT:			
+		if (COMPOUND_BODY (body))
+			body = COMPOUND_BODY (body);
+		else
+			return;
+		break;
+
+	  case TREE_LIST:
+		read_access (TREE_VALUE (body), fnref_f, thisTree);
+		if (TREE_CHAIN (body))
+                        body = TREE_CHAIN (body) ;
+                else
+                        return;
+        break;
+
+	  case DECL_STMT:
+	  case SCOPE_STMT:
+		if(TREE_CHAIN (body))
+			body = TREE_CHAIN (body) ;
+		else
+			return;
+		break;
+	  
+	  case EXPR_STMT: 	
+		expr = EXPR_STMT_EXPR (body); 
+		read_access (expr, fnref_f, thisTree);
+		if(TREE_CHAIN (body))
+			body = TREE_CHAIN (body) ; 
+		else
+			return;
+		break;
+	 
+	  case CONVERT_EXPR:
+	  case NOP_EXPR:
+		body = TREE_OPERAND (body, 0);
+		break;
+
+      case FUNCTION_DECL:
+         cont=DECL_ARGUMENTS(body);
+         while (cont) {
+             read_access(cont, fnref_f, thisTree);
+             cont = TREE_CHAIN(cont);
+         };
+
+        return;
+        break;
+        
+	  case PARM_DECL:
+	    	fprintf(fnref_f, "A {%s} {%s:%d} {param:%s:%s}\n",
+		      lang_hooks.decl_printable_name (thisTree, 2),
+		      DECL_SOURCE_FILE (thisTree),1,"R",
+		      lang_hooks.decl_printable_name (body, -1));		 
+		return;
+		break;
+
+	  case VAR_DECL:
+     	       cont = DECL_CONTEXT (body);
+  	       if (!cont)
+			fprintf(stderr,"global var read \n");
+	       if(((DECL_CONTEXT (body) == NULL) || (TREE_CODE (DECL_CONTEXT (body)) == NULL_TREE ) ||
+		           (TREE_CODE (DECL_CONTEXT (body))==TRANSLATION_UNIT_DECL) ) )
+		{
+	           fprintf(fnref_f, "A {%s} {%s:%d} {global:%s:%s}\n",
+		           lang_hooks.decl_printable_name (thisTree, 2),
+			       DECL_SOURCE_FILE (thisTree),1,"R",
+			       lang_hooks.decl_printable_name (body, -1));		
+               find_record(TREE_TYPE (body),fnref_f);
+               /*if (TREE_TYPE (body) && TREE_CODE (TREE_TYPE (body))==RECORD_TYPE ) 		
+               {
+	  	          fprintf(fnref_f, "TSR {%s}\n", lang_hooks.decl_printable_name (TREE_TYPE (body), 2));  
+		          print_structures (TYPE_FIELDS(TREE_TYPE (body)), fnref_f);	
+               } */  
+		}
+		return; 		
+		break;
+
+      case FOR_STMT:
+        dump_access_info (FOR_INIT_STMT(body),fnref_f, thisTree);
+        read_access(FOR_COND(body),fnref_f, thisTree);
+        dump_access_info(FOR_EXPR(body),fnref_f, thisTree);
+        dump_access_info(FOR_BODY(body),fnref_f, thisTree);
+        body = TREE_CHAIN(body);
+        break;
+        
+     case WHILE_STMT:
+        dump_access_info (WHILE_BODY(body),fnref_f, thisTree);
+        read_access (WHILE_COND(body),fnref_f, thisTree);
+        body = TREE_CHAIN(body);
+        break;
+        
+     case DO_STMT:
+        dump_access_info (DO_BODY(body),fnref_f, thisTree);
+        read_access (DO_COND(body),fnref_f, thisTree);
+        body = TREE_CHAIN(body);
+        break;   
+        
+	case INDIRECT_REF:
+		body = TREE_OPERAND (body, 0);
+		break;
+
+	case COMPONENT_REF:
+    case ADDR_EXPR:
+		body = TREE_OPERAND (body,0);
+		break;
+
+/*    case LT_EXPR:
+    case LE_EXPR:
+    case GE_EXPR:
+    case NE_EXPR:
+    case TRUTH_ANDIF_EXPR:
+    case TRUTH_ORIF_EXPR:
+    case GT_EXPR:    */
+    case ARRAY_REF:    
+/*    case TRUNC_MOD_EXPR:    
+    case EQ_EXPR:
+	case MULT_EXPR:
+	case PLUS_EXPR:      */
+	    expr = TREE_OPERAND (body,0);
+		read_access(expr,fnref_f, thisTree);
+		expr = TREE_OPERAND (body, 1);
+		read_access(expr,fnref_f, thisTree);
+		return;
+		break;
+
+	case CALL_EXPR:
+		if(TREE_OPERAND(body,1))
+			body = TREE_OPERAND(body, 1);
+		else
+			return;	
+		break;
+	
+	default:
+        if(IS_EXPR_CODE_CLASS(TREE_CODE_CLASS(TREE_CODE(body))) ){
+	    expr = TREE_OPERAND (body,0);
+		read_access(expr,fnref_f, thisTree);
+		expr = TREE_OPERAND (body, 1);
+		read_access(expr,fnref_f, thisTree);           
+        }
+        return;
+	}	
+      } 	
+      return;
+
+  } 
+
+/* AccessViz : Function to find the globals, arguments being read and written*/
+/* To find what function to use to reference a child of a given node, can take help 
+   from c-dump.c or tree-dump.c or tree.def */
+void dump_access_info (tree body,FILE * fnref_f, tree thisTree)
+ {
+      tree expr,cont;	
+      while (body) {		
+      switch (TREE_CODE (body))
+	{
+	  case COMPOUND_STMT:			
+		if (COMPOUND_BODY (body))
+			body = COMPOUND_BODY (body);
+		else
+			return;
+		break;
+
+	  case DECL_STMT:
+	  case SCOPE_STMT:
+      case BREAK_STMT:
+      case CONTINUE_STMT:
+      case CASE_LABEL:
+		if(TREE_CHAIN (body))
+			body = TREE_CHAIN (body) ;
+		else
+			return;
+		break;
+	 
+      case IF_STMT:
+        read_access(IF_COND (body), fnref_f, thisTree);
+        cont = THEN_CLAUSE(body);
+        dump_access_info (cont, fnref_f, thisTree);
+        if(ELSE_CLAUSE(body)) {
+            cont = ELSE_CLAUSE(body);
+            dump_access_info(cont,fnref_f, thisTree);
+        }
+        if(TREE_CHAIN(body))
+            body = TREE_CHAIN(body);
+        else
+            return;
+        break;
+              
+      case FOR_STMT:
+        dump_access_info (FOR_INIT_STMT(body),fnref_f, thisTree);
+        read_access(FOR_COND(body),fnref_f, thisTree);
+        dump_access_info(FOR_EXPR(body),fnref_f, thisTree);
+        dump_access_info(FOR_BODY(body),fnref_f, thisTree);
+        body = TREE_CHAIN (body);
+        break;
+    
+     case WHILE_STMT:
+        read_access (WHILE_COND(body),fnref_f, thisTree);
+        dump_access_info (WHILE_BODY(body),fnref_f, thisTree);
+        body = TREE_CHAIN(body);
+        break;
+
+        
+      case DO_STMT:
+        dump_access_info (DO_BODY(body),fnref_f, thisTree);
+        read_access (DO_COND(body),fnref_f, thisTree);
+        body = TREE_CHAIN(body);
+        break;
+        
+      case SWITCH_STMT:
+        dump_access_info (SWITCH_BODY(body),fnref_f, thisTree);
+        read_access (SWITCH_COND(body),fnref_f, thisTree);
+        body = TREE_CHAIN(body);
+        break;  
+
+      
+	  case EXPR_STMT: 	
+		expr = EXPR_STMT_EXPR (body); 
+		dump_access_info (expr, fnref_f, thisTree);
+		if(TREE_CHAIN (body))
+			body = TREE_CHAIN (body) ; 
+		else
+			return;
+		break;
+	 
+      case CALL_EXPR:
+/*        cont = TREE_OPERAND(body,0);
+        read_access(cont,fnref_f, thisTree);*/
+        if(TREE_OPERAND(body,1))
+            read_access(TREE_OPERAND(body,1),fnref_f,thisTree);
+        return;
+        break;
+       
+      case INIT_EXPR:  
+	  case CONVERT_EXPR:
+		body = TREE_OPERAND (body, 0);
+		break;
+
+      case ARRAY_REF:  
+	  case MODIFY_EXPR:
+		/*AccessViz, get the read access, by looking at the operands*/
+		read_access(TREE_OPERAND (body, 1),fnref_f,thisTree);
+		/*AccessViz, get the write access, by looking at the operand 0*/
+		body = TREE_OPERAND (body, 0);
+		break;
+
+	  case PARM_DECL:
+	    	fprintf(fnref_f, "A {%s} {%s:%d} {param:%s:%s}\n",
+		      lang_hooks.decl_printable_name (thisTree, 2),
+		      DECL_SOURCE_FILE (thisTree),1,"W",
+		      lang_hooks.decl_printable_name (body,-1));		 
+		return;
+		break;
+
+	  case VAR_DECL:
+     	       cont = DECL_CONTEXT (body);
+  	       if (!cont)
+			fprintf(stderr,"global var write \n");
+	       if((DECL_CONTEXT (body) == NULL) || (TREE_CODE (DECL_CONTEXT (body)) == NULL_TREE ) ||
+		           (TREE_CODE (DECL_CONTEXT (body))==TRANSLATION_UNIT_DECL)  )
+  		   {
+		     fprintf(fnref_f, "A {%s} {%s:%d} {global:%s:%s}\n",
+		           lang_hooks.decl_printable_name (thisTree, 2),
+			    DECL_SOURCE_FILE (thisTree) ,1,"W",
+			      lang_hooks.decl_printable_name (body, -1));	
+		     find_record (TREE_TYPE (body),fnref_f);
+
+		  }
+		return; 		
+		break;
+	  
+	case INDIRECT_REF:
+	case PREDECREMENT_EXPR:
+	case PREINCREMENT_EXPR:
+	case POSTDECREMENT_EXPR:
+	case POSTINCREMENT_EXPR:
+		body = TREE_OPERAND (body, 0);
+		break;
+
+	case COMPONENT_REF:
+		body = TREE_OPERAND (body,0);
+		break;
+	
+	default:
+	       return;
+	}	
+      } 
+      return;
+
+  } 
+
 /* Analyze the function scheduled to be output.  */
 static void
 cgraph_analyze_function (struct cgraph_node *node)
 {
-  tree decl = node->decl;
+  tree decl = node->decl,body;
+  /* AccessViz */
   tree thisTree, calleeTree;
   FILE *fnref_f;
+
   struct cgraph_edge *e;
   struct cgraph_edge *calleeEdge;
 
   current_function_decl = decl;
-
+ 
   /* First kill forward declaration so reverse inlining works properly.  */
   cgraph_create_edges (decl, DECL_SAVED_TREE (decl));
 
@@ -361,7 +720,6 @@
   node->analyzed = true;
   current_function_decl = NULL;
 
-  /* CodeViz: Output information on this node */
   thisTree = node->decl;
   if ((fnref_f = cdepn_open(NULL)))
     {
@@ -371,6 +729,20 @@
 
     }
 
+/*#ifndef HEADER_INFO
+  if ((DECL_SOURCE_FILE (thisTree))[strlen(DECL_SOURCE_FILE (thisTree))-1]!='h') 
+#endif      */
+        
+  /* AccessViz: Also o/p if the function paramaters are being read or written  */
+  body = DECL_SAVED_TREE(thisTree);
+  dump_access_info(body,fnref_f, thisTree); 
+  /*For printing the out the parameter in detail, if non-basic */
+  print_arg_structures (DECL_ARGUMENTS (thisTree), fnref_f);
+  /*For printing the return type, if non-basic */
+//  fprintf(fnref_f,"return type:");
+  find_record ( TREE_TYPE (TREE_TYPE(thisTree)), fnref_f);
+  
+
   /* CodeViz: Output information on all functions this node calls */
   for (calleeEdge = node->callees; calleeEdge; calleeEdge = calleeEdge->next_callee)
     {
@@ -379,7 +751,13 @@
 	  calleeTree != NULL &&
 	  (fnref_f = cdepn_open(NULL)) != NULL)
 	{
-	  fprintf(fnref_f, "C {%s} {%s:%d} {%s}\n",
+  /* Do not output function call and declaration info got from header files. Only the source file information
+	is outputted */
+#ifndef HEADER_INFO
+	if(calleeEdge->call_location.file[strlen(calleeEdge->call_location.file)-1]=='h')
+		continue;
+#endif
+	  fprintf(fnref_f, "C {%s} {%s:%d} {call:%s}\n",
 	      lang_hooks.decl_printable_name (thisTree, 2),
 	      calleeEdge->call_location.file, calleeEdge->call_location.line,
 	      lang_hooks.decl_printable_name (calleeTree, 2));
