/**********************************************************************
 * Copyright (c) 2007 IBM Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.ptp.pldt.mpi.analysis.analysis;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

import org.eclipse.cdt.core.dom.ast.*;
import org.eclipse.cdt.core.dom.ast.c.ICASTDesignatedInitializer;
import org.eclipse.cdt.core.dom.ast.c.ICASTTypeIdInitializerExpression;
import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression;
import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.IBlock;
import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.ICallGraph;
import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.ICallGraphNode;
import org.eclipse.ptp.pldt.mpi.analysis.cdt.graphs.IControlFlowGraph;


/** 
 * Calculate the (inter-procedural) use set and def set of each block.
 * @author Yuan Zhang
 *
 */
public class UseDefBuilder extends ASTVisitor{
	protected ICallGraph cg_;
	protected IControlFlowGraph cfg_ = null;
	
	protected List<String> use_ = null;
	protected List<String> def_ = null;
	protected List<String> guse_ = null;
	protected List<String> gdef_ = null;
	protected List<String> padef_ = null;

	protected final int lhs = 0;
	protected final int rhs = 1;
	
	protected MPICallGraphNode currentFunc_;
	protected Hashtable<String,List<IBlock>> defTable_ = null;
	
	public UseDefBuilder(ICallGraph cg){
		cg_ = cg;
	}
	
	public void run(){
		this.shouldVisitDeclarations = true;
		this.shouldVisitExpressions = true;
		this.shouldVisitStatements = true;
		
		/* Fix point to deal with the recursion */
		boolean change = true;
		while(change){
			change = false;
			for(ICallGraphNode n = cg_.botEntry(); n != null; n = n.botNext()){
				MPICallGraphNode node = (MPICallGraphNode)n;
				//if(node.getFuncName().equals("yytnamerr"))
					//System.out.println(node.getFuncName());
				if(!node.marked) continue;
				List<String> oldguse_ = node.getGlobalUse();
				List<String> oldgdef_ = node.getGlobalDef();
				List<String> oldpadef_ = node.getParamDef();
				guse_ = new ArrayList<String>();
				gdef_ = new ArrayList<String>();
				padef_ = new ArrayList<String>();
				cfg_ = node.getCFG();
				currentFunc_ = node;
				for(IBlock b = cfg_.getEntry().topNext(); b != null; b = b.topNext()){
					MPIBlock block = (MPIBlock)b;
					IASTNode content = block.getContent();
					if(content == null || content instanceof IASTName) continue;
					List<String> olduse_ = block.getUse();
					List<String> olddef_ = block.getDef();
					use_ = new ArrayList<String>();
					def_ = new ArrayList<String>();
					if(content instanceof IASTExpression){
						IASTExpression expr = (IASTExpression)content;
						expr.accept(this);
					} else { //statement
						IASTStatement stmt = (IASTStatement)content;
						stmt.accept(this);
					}
					if(!Util.equals(use_, olduse_)){
						block.setUse(use_);
						change = true;
					}
					if(!Util.equals(def_, olddef_)){
						block.setDef(def_);
						change = true;
					}
				}
				if(!Util.equals(guse_, oldguse_)){
					node.setGlobalUse(guse_);
					change = true;
				}
				if(!Util.equals(gdef_, oldgdef_)){
					node.setGlobalDef(gdef_);
					change = true;
				}
				if(!Util.equals(padef_, oldpadef_)){
					node.setParamDef(padef_);
					change = true;
				}
			}
		}
		
		for(ICallGraphNode n = cg_.botEntry(); n != null; n = n.botNext()){
			MPICallGraphNode node = (MPICallGraphNode)n;
			if(!node.marked) continue;
			currentFunc_ = node;
			cfg_ = node.getCFG();
			setEntryBlock((MPIBlock)node.getCFG().getEntry());
			setExitBlock((MPIBlock)node.getCFG().getExit());
			defTable_ = new Hashtable<String,List<IBlock>>();
			for(IBlock b = cfg_.getEntry(); b != null; b = b.topNext()){
				MPIBlock block = (MPIBlock)b;
				List<String> def = block.getDef();
				if(def.isEmpty()) continue;
				for(Iterator<String> i = def.iterator(); i.hasNext();){
					String var = i.next();
					List<IBlock> defblocks = defTable_.get(var);
					if(defblocks == null){
						defblocks = new ArrayList<IBlock>();
						defblocks.add(block);
						defTable_.put(var, defblocks);
					} else {
						defblocks.add(block);
						defTable_.put(var, defblocks);
					}
				}
			}
			node.setDefTable(defTable_);
		}
	}
	
	public int visit(IASTStatement stmt){
		if(stmt instanceof IASTDeclarationStatement){
			IASTDeclarationStatement declStmt = (IASTDeclarationStatement)stmt;
			IASTDeclaration decl = declStmt.getDeclaration();
			if(decl instanceof IASTSimpleDeclaration){
				IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration)decl;
				IASTDeclarator[] declarators = simpleDecl.getDeclarators();
				for(int i=0; i<declarators.length; i++){
					IASTName name = declarators[i].getName();
					IASTInitializer init = declarators[i].getInitializer();
					if(init != null)
						def_.add(name.toString());
					processInitializer(init);
				}
			}
			return PROCESS_SKIP;
		}
		return PROCESS_CONTINUE;
	}
	
	private void processInitializer(IASTInitializer init){
		if(init != null){
			if(init instanceof IASTInitializerExpression){
				IASTInitializerExpression initE = (IASTInitializerExpression)init;
				IASTExpression e = initE.getExpression();
				useDefSet(e, rhs, null, -1);
			}
			else if(init instanceof IASTInitializerList){
				IASTInitializerList list = (IASTInitializerList)init;
				IASTInitializer[] inits = list.getInitializers();
				for(int j = 0; j<inits.length; j++){
					processInitializer(inits[j]);
				}
			}
			else if(init instanceof ICASTDesignatedInitializer){
				System.out.println("ICASTDesignatedInitializer found !"); //$NON-NLS-1$
			}
		}
	}
	
	/** 
	 * The traverse is stopped (by PROCESS_SKIP) when the expression of 
	 * the statement is visited. This method is used to find the expression.
	 */
	public int visit(IASTExpression expr){
		useDefSet(expr, rhs, null, -1);
		return PROCESS_SKIP;
	}



	/**
	 * 
	 * @param expr The expression being analyzed
	 * @param side lhs if it is defined, rhs otherwise (rhs)
	 * @param funcall the function call expression
	 * @param index  the index of the current parameter in funcall
	 */
	public void useDefSet(IASTExpression expr, int side, 
			IASTFunctionCallExpression funcall, int index){
		// Null expression for empty function parameter 
		if(expr == null) return; 
		if(expr instanceof IASTAmbiguousExpression){
		}
		else if(expr instanceof IASTArraySubscriptExpression){
			IASTArraySubscriptExpression asE = (IASTArraySubscriptExpression)expr;
			if(side == rhs){
				// = a[index_expr]
				useDefSet(asE.getArrayExpression(), rhs, funcall, index); 
				useDefSet(asE.getSubscriptExpression(), rhs, funcall, index);
			} else { //lhs
				// a[b[i]] = ... , a is defined, b and i are used
				useDefSet(asE.getSubscriptExpression(), rhs, funcall, index);
				useDefSet(asE.getArrayExpression(), lhs, funcall, index);
			}
		}
		else if(expr instanceof IASTBinaryExpression){
			IASTBinaryExpression biE = (IASTBinaryExpression)expr;
			int op = biE.getOperator();
			if(op == IASTBinaryExpression.op_assign){
				// x = y = z is right associative --> x = (y = z)
				// So the "side" will be always rhs
				useDefSet(biE.getOperand1(), lhs, funcall, index);
				useDefSet(biE.getOperand2(), rhs, funcall, index);
			}
			else if( op == IASTBinaryExpression.op_multiplyAssign ||
					 op == IASTBinaryExpression.op_divideAssign ||
					 op == IASTBinaryExpression.op_moduloAssign ||
					 op == IASTBinaryExpression.op_plusAssign ||
					 op == IASTBinaryExpression.op_minusAssign ||
					 op == IASTBinaryExpression.op_shiftLeftAssign ||
					 op == IASTBinaryExpression.op_shiftRightAssign ||
					 op == IASTBinaryExpression.op_binaryAndAssign ||
					 op == IASTBinaryExpression.op_binaryXorAssign ||
					 op == IASTBinaryExpression.op_binaryOrAssign){
				useDefSet(biE.getOperand1(), rhs, funcall, index);
				useDefSet(biE.getOperand2(), rhs, funcall, index);
				useDefSet(biE.getOperand1(), lhs, funcall, index);
			} 
			else {
				useDefSet(biE.getOperand1(), rhs, funcall, index);
				useDefSet(biE.getOperand2(), rhs, funcall, index);
			}
		}
		else if(expr instanceof IASTCastExpression){
			IASTCastExpression castE = (IASTCastExpression)expr;
			useDefSet(castE.getOperand(), side, funcall, index);
		}
		else if(expr instanceof IASTConditionalExpression){
			IASTConditionalExpression condE = (IASTConditionalExpression)expr;
			if(side == rhs){
				useDefSet(condE.getLogicalConditionExpression(), rhs, funcall, index); 
				useDefSet(condE.getPositiveResultExpression(), rhs, funcall, index); 
				useDefSet(condE.getNegativeResultExpression(), rhs, funcall, index);
			} else {
				// eg. x > y ? x : y = 1
				useDefSet(condE.getLogicalConditionExpression(), rhs, funcall, index); 
				useDefSet(condE.getPositiveResultExpression(), lhs, funcall, index); 
				useDefSet(condE.getNegativeResultExpression(), lhs, funcall, index);
			}
		}
		else if(expr instanceof IASTExpressionList){
			IASTExpressionList exprList = (IASTExpressionList)expr;
			IASTExpression[] exprs = exprList.getExpressions();
			for(int i = 0; i<exprs.length; i++){
				if(funcall != null)
					useDefSet(exprs[i], side, funcall, i);
				else
					useDefSet(exprs[i], side, funcall, index);
			}
		}
		else if(expr instanceof IASTFieldReference){
			IASTFieldReference frE = (IASTFieldReference)expr;
			useDefSet(frE.getFieldOwner(), side, funcall, index);
		}
		else if(expr instanceof IASTFunctionCallExpression){
			IASTFunctionCallExpression funcE = (IASTFunctionCallExpression)expr;
			IASTExpression funcname = funcE.getFunctionNameExpression();
			String signature = funcname.getRawSignature();
			MPICallGraphNode n = (MPICallGraphNode)cg_.getNode(currentFunc_.getFileName(), signature);
			if(n != null){
				gdef_ = Util.Union(gdef_, n.getGlobalDef());
				guse_ = Util.Union(guse_, n.getGlobalUse());
				def_ = Util.Union(def_, n.getGlobalDef());
				use_ = Util.Union(use_, n.getGlobalUse());
			}
			IASTExpression paramE = funcE.getParameterExpression();
			if(paramE == null) return;
			if(paramE instanceof IASTExpressionList)
				useDefSet(funcE.getParameterExpression(), side, funcE, -1);
			else
				useDefSet(funcE.getParameterExpression(), side, funcE, 0);
		}
		else if(expr instanceof IASTIdExpression){
			IASTIdExpression id = (IASTIdExpression)expr;
			IASTName name = id.getName();
			String var = name.toString();
			if(var.startsWith("MPI_")) return; //$NON-NLS-1$
			if(side == rhs){
				if(!use_.contains(var)) 
					use_.add(var);
				if(cg_.getEnv().contains(var) && !guse_.contains(var)) 
					guse_.add(var);
				if(funcall != null){
					if(isDefinedParam(funcall, index)){
						if(!def_.contains(var))
							def_.add(var);
						if(cg_.getEnv().contains(var) && !gdef_.contains(var))
							gdef_.add(var);
						if(isPassableParam(var) && !padef_.contains(var))
							padef_.add(var);
					}
				}
			} else { //lhs
				if(!def_.contains(var)) 
					def_.add(var);
				if(cg_.getEnv().contains(var) && !gdef_.contains(var)) 
					gdef_.add(var);
				if(isPassableParam(var) && !padef_.contains(var)) 
					padef_.add(var);
			}
		}
		else if(expr instanceof IASTLiteralExpression){
		}
		else if(expr instanceof IASTProblemExpression){
		}
		else if(expr instanceof IASTTypeIdExpression){
		}
		else if(expr instanceof IASTUnaryExpression){
			IASTUnaryExpression uE = (IASTUnaryExpression)expr;
			int op = uE.getOperator();
			if(op == IASTUnaryExpression.op_prefixIncr ||
				  op == IASTUnaryExpression.op_prefixDecr ||
				  op == IASTUnaryExpression.op_postFixIncr ||
				  op == IASTUnaryExpression.op_postFixDecr) {
				useDefSet(uE.getOperand(), rhs, funcall, index);
				useDefSet(uE.getOperand(), lhs, funcall, index);
			} else {
				useDefSet(uE.getOperand(), side, funcall, index);
			}
		}
		else if(expr instanceof ICASTTypeIdInitializerExpression){
		}
		else{
		}
	}
	
	private boolean isPassableParam(String name){
		IASTFunctionDefinition fdef = currentFunc_.getFuncDef();
		IASTFunctionDeclarator fdecl = fdef.getDeclarator();
		if(fdecl instanceof IASTStandardFunctionDeclarator){
			IASTStandardFunctionDeclarator sfunc = (IASTStandardFunctionDeclarator)fdecl;
			IASTParameterDeclaration[] params = sfunc.getParameters();
			for(int i = 0; i < params.length; i++){
				IASTName param = params[i].getDeclarator().getName();
				IASTPointerOperator[] pops = params[i].getDeclarator().getPointerOperators();
				if(name.equals(param.toString()) && pops != IASTPointerOperator.EMPTY_ARRAY){
					return true;
				}
			}
		} else {
			ICASTKnRFunctionDeclarator krfunc = (ICASTKnRFunctionDeclarator)fdecl;
			IASTName[] params = krfunc.getParameterNames();
			for(int i=0; i<params.length; i++){
				if(name.equals(params[i].toString())){
					IASTDeclarator decl = krfunc.getDeclaratorForParameterName(params[i]);
					if(decl.getPointerOperators() != IASTPointerOperator.EMPTY_ARRAY)
						return true;
				}
			}
		}
		return false;
	}
	
	private boolean isDefinedParam(IASTFunctionCallExpression fE, int index){
		if(index == -1) return false;
		IASTExpression funcname = fE.getFunctionNameExpression();
		String signature = funcname.getRawSignature();
		MPICallGraphNode node = (MPICallGraphNode)cg_.getNode(currentFunc_.getFileName(), signature);
		if(node != null){
			List<String> padef = node.getParamDef();
			IASTFunctionDefinition fdef = node.getFuncDef();
			IASTFunctionDeclarator fdecl = fdef.getDeclarator();
			if(fdecl instanceof IASTStandardFunctionDeclarator){
				IASTStandardFunctionDeclarator sfunc = (IASTStandardFunctionDeclarator)fdecl;
				IASTParameterDeclaration[] params = sfunc.getParameters();
				if(params.length <= index) return false;
				IASTName param = params[index].getDeclarator().getName();
				if(padef.contains(param.toString())) return true;
			} else {
				ICASTKnRFunctionDeclarator krfunc = (ICASTKnRFunctionDeclarator)fdecl;
				IASTName[] params = krfunc.getParameterNames();
				if(params.length <= index) return false;
				IASTName param = params[index];
				if(padef.contains(param.toString())) return true;
			}
		} else {
			/* Library function calls. Any parameter whose address
			 * is taken (pointer or array) is both defined and used.
			 */
			IASTExpression parameterE = fE.getParameterExpression();
			if(parameterE instanceof IASTExpressionList){
				IASTExpressionList paramEList = (IASTExpressionList)parameterE;
				IASTExpression param = (paramEList.getExpressions())[index];
				IType type = param.getExpressionType();
				if(type instanceof IArrayType || 
						type instanceof IPointerType) return true;
			}
			else{
				IType type = parameterE.getExpressionType();
				if(type instanceof IArrayType || 
						type instanceof IPointerType) return true;
			}
		}
		return false;
	}
	
	/**
	 * All parameters of a function and used globals are assumed to be 
	 * defined at the entry block.
	 */
	private void setEntryBlock(MPIBlock entry){
		List<String> def = new ArrayList<String>();
		IASTFunctionDefinition fdef = currentFunc_.getFuncDef();
		IASTFunctionDeclarator fdecl = fdef.getDeclarator();
		if(fdecl instanceof IASTStandardFunctionDeclarator){
			IASTStandardFunctionDeclarator sfunc = (IASTStandardFunctionDeclarator)fdecl;
			IASTParameterDeclaration[] params = sfunc.getParameters();
			for(int i=0; i<params.length; i++){
				IASTName param = params[i].getDeclarator().getName();
				def.add(param.toString());
			}
		} else {
			ICASTKnRFunctionDeclarator krfunc = (ICASTKnRFunctionDeclarator)fdecl;
			IASTName[] params = krfunc.getParameterNames();
			for(int i=0; i<params.length; i++){
				IASTName param = params[i];
				def.add(param.toString());
			}
		}
		for(Iterator<String> i = currentFunc_.getGlobalUse().iterator(); i.hasNext();){
			def.add(i.next());
		}
		entry.setDef(def);
		entry.setUse(new ArrayList<String>());
	}	
	
	/**
	 *  All defined global variables and defined passable parameters are assumed 
	 * to be used in the exit block
	 */
	private void setExitBlock(MPIBlock exit){
		List<String> use = new ArrayList<String>();
		for(Iterator<String> i = currentFunc_.getGlobalDef().iterator(); i.hasNext();){
			use.add(i.next());
		}
		for(Iterator<String> i = currentFunc_.getParamDef().iterator(); i.hasNext();){
			use.add(i.next());
		}
		
		exit.setUse(use);
		exit.setDef(new ArrayList<String>());
	}
}
