From 21a3e9dea32f676dc3b505aa1d2fa618ee9a97f1 Mon Sep 17 00:00:00 2001
From: Daniel Knorreck <daniel.knorreck@telecom-paristech.fr>
Date: Thu, 15 Jul 2010 09:52:02 +0000
Subject: [PATCH]

---
 .../tomappingsystemc2/LiveVariableNode.java   | 490 ++++++++++++++++++
 1 file changed, 490 insertions(+)
 create mode 100755 src/tmltranslator/tomappingsystemc2/LiveVariableNode.java

diff --git a/src/tmltranslator/tomappingsystemc2/LiveVariableNode.java b/src/tmltranslator/tomappingsystemc2/LiveVariableNode.java
new file mode 100755
index 0000000000..d0370881ef
--- /dev/null
+++ b/src/tmltranslator/tomappingsystemc2/LiveVariableNode.java
@@ -0,0 +1,490 @@
+package tmltranslator.tomappingsystemc2;
+
+import java.util.*;
+import tmltranslator.*;
+import javax.script.*;
+
+public class LiveVariableNode{
+	private LinkedList<LiveVariableNode> _succList, _predList;
+	private boolean _valid=false;
+	private static int _nextDefID=0;
+	private static int[][] _varToStatements=null;
+	private static int _bytesForStatements;
+	private static LiveVariableNode[] _defLookup;
+	private int[] _useVars;
+	private int[] _defVars;
+	private int[] _defNegVars;
+	private int[] _inVars;
+	private int[] _outVars;
+	private int[] _killDefs;
+	private int[] _generateDefs;
+	private int[] _killCandidates;
+	private int[] _inDefs;
+	private int[] _outDefs;
+	private int _myDefID;
+	private boolean _isConstant=false;
+	private boolean _constantStuckToFalse=false;
+	private boolean _infected=false;
+	private TMLActivityElement _linkedElem;
+	private LiveVariableNode _superiorBranchNode=null;
+	private int _exprValue=0;
+	private String _lhs="";
+	private String _rhs="";
+	private String _unrolledExpr="";
+	
+
+	LiveVariableNode(int[] iUseVars, int[] iDefVars, TMLActivityElement iLinkedElem, LiveVariableNode iSuperiorNode, boolean iConstantStuckToFalse, String iLhs, String iRhs){
+		this(iUseVars, iDefVars, iLinkedElem, iSuperiorNode, iConstantStuckToFalse);
+		_lhs=iLhs;
+		_rhs= iRhs;
+		//System.out.println("lhs in init:*" + _lhs + "* rhs in init:*" + _rhs);
+	}
+	
+	LiveVariableNode(int[] iUseVars, int[] iDefVars, TMLActivityElement iLinkedElem, LiveVariableNode iSuperiorNode, boolean iConstantStuckToFalse){
+		this(iUseVars, iDefVars, iLinkedElem, iSuperiorNode);
+		_constantStuckToFalse=iConstantStuckToFalse;
+		
+	}
+
+	LiveVariableNode(int[] iUseVars, int[] iDefVars, TMLActivityElement iLinkedElem, LiveVariableNode iSuperiorNode){
+		boolean isADefinition=false;
+		_useVars=iUseVars;
+		_defVars=iDefVars;
+		_superiorBranchNode = iSuperiorNode;
+		_defNegVars = new int[_defVars.length];
+		_inVars = new int[_defVars.length];
+		_outVars = new int[_defVars.length];
+		if (_varToStatements==null) _varToStatements = new int [_defVars.length << 5][];
+		_linkedElem = iLinkedElem;
+		for (int i=0; i<_defVars.length;i++){
+			_defNegVars[i] =  ~_defVars[i];
+			_inVars[i] = _useVars[i] & _defNegVars[i];
+			isADefinition |= (_defVars[i]!=0);
+		}
+		if (isADefinition)
+			_myDefID=_nextDefID++;
+		else
+			_myDefID=-1;
+		 _succList = new LinkedList<LiveVariableNode>();
+		 _predList = new LinkedList<LiveVariableNode>();
+	}
+
+	public static int evaluate(String string) throws IllegalArgumentException{
+		ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
+		try{
+			//Object object = engine.eval("eval("+string+")");
+			engine.eval(string);
+			Object object = engine.get("xx_xx");
+			if ((object != null) && (object instanceof Number)){
+                		return ((Number)(object)).intValue();
+			}else{
+				throw new IllegalArgumentException("Invalid input: '"+string+"'");
+			}
+		}catch (ScriptException e){
+			throw new IllegalArgumentException("Invalid input: '"+string+"'", e);
+		}
+	}
+
+	public static void reset(){
+		_varToStatements=null;
+		_nextDefID=0;
+	}
+	
+	public void prepareReachingDefinitions(){
+		invalidate();
+		if(_varToStatements[0]==null){
+			//System.out.println("Initialization done");
+			_bytesForStatements = _nextDefID >>> 5;
+			if ((_nextDefID & 0x1F)!=0 || _nextDefID==0) _bytesForStatements++;
+			//System.out.println("Initialization Set _bytesForStatements = " + _bytesForStatements + "  _nextDefID:" + _nextDefID);
+			for (int i=0; i<(_defVars.length << 5);i++){
+				_varToStatements[i]=new int[_bytesForStatements];
+			}
+			_defLookup = new LiveVariableNode[_bytesForStatements << 5];
+		}//else
+			//System.out.println("Bytes for statements without init: " + _bytesForStatements);
+		_generateDefs = new int[_bytesForStatements];
+		_killDefs= new int[_bytesForStatements];
+		_killCandidates = new int[_bytesForStatements];
+		_inDefs = new int[_bytesForStatements];
+		_outDefs = new int[_bytesForStatements];
+		//System.out.println("<> varToStatements asso: " + getStatementDescr());
+		if (_myDefID!=-1){
+			for (int bytes=0; bytes<_defVars.length;bytes++){
+				for (int bits=0; bits<32;bits++){
+					if ((_defVars[bytes] & (1 << bits))!=0){
+						 _varToStatements[(bytes << 5)|bits][_myDefID >>> 5] |= 1 << (_myDefID & 0x1F);
+						//System.out.println("var found:" + ((bytes << 5)|bits));
+					}
+				}
+			}
+		 	_generateDefs[_myDefID >>> 5] =  1 << (_myDefID & 0x1F);
+			_defLookup[_myDefID]=this;
+		}
+		//System.out.println("<> END varToStatements asso: " + getStatementDescr());
+	}
+
+	public void printKillEntries(){
+		//System.out.println("++++++++++ Kill definitions list ++++++++++");
+		System.out.print(getStatementDescr() + "  kills definitions: ");
+		printDefList(_killDefs);
+		System.out.println();
+	}
+
+	public void printReachingEntries(){
+		//System.out.println("++++++++++ Reaching definitions list ++++++++++");
+		System.out.print(getStatementDescr() + "  reached by definitions: ");
+		printDefList(_inDefs);
+		System.out.println();
+	}
+
+	private void printDefList(int[] iList){
+		for (int bytes=0; bytes<iList.length; bytes++){
+			for (int bits=0; bits<32;bits++){
+				if ((iList[bytes]& (1 << bits))!=0) System.out.print(((bytes << 5)|bits) + ", "); 
+			}
+		}
+	}
+	
+
+	private boolean allDefsConstantAndEqual(int[] iDefinitions){
+		boolean aIsConst=true, aFirstTime=true, aDefFound=false;
+		int aLastExprVal=0; 
+		//System.out.println("******* allDefsConstantAndEqual");
+		for (int bytes=0; bytes<iDefinitions.length && aIsConst; bytes++){
+			for (int bits=0; bits<32 && aIsConst; bits++){
+				int anIndex = (bytes << 5)|bits;
+				if ((iDefinitions[bytes] & (1<< bits))!=0){ //what if there are no definitions????
+					aDefFound=true;
+					//aIsConst &= _defLookup[(bytes << 5)|bits].isConstant();	
+					if (_defLookup[anIndex].isConstant()){
+						//System.out.println(_defLookup[anIndex].getStatementDescr() + " said to be constant");
+						if (aFirstTime || _defLookup[anIndex].getExpressionValue() == aLastExprVal){
+							aLastExprVal = _defLookup[anIndex].getExpressionValue();
+							_unrolledExpr+= _defLookup[anIndex].getExpressionString() + ";";
+							aFirstTime=false;
+						}else
+							aIsConst=false;
+					}else{
+						//System.out.println(_defLookup[anIndex].getStatementDescr() + " said to be NOT constant");
+						aIsConst=false;
+					}
+				}//else
+					//if (_defLookup[anIndex]!=null) System.out.println(_defLookup[anIndex].getStatementDescr() + " not concerned"); 
+			}
+		}
+		//if (aIsConst)
+		//System.out.println(aIsConst + " lhs:" + _lhs + " rhs:" + _rhs);
+		return (aIsConst && aDefFound);
+	}
+
+	public boolean determineIfConstant(){
+		//not constant: random, notified event, receive event, select event
+		//if (_linkedElem!=null && (_linkedElem instanceof TMLRandom || _linkedElem instanceof TMLWaitEvent || _linkedElem instanceof TMLNotifiedEvent || _linkedElem instanceof TMLSelectEvt)) return false;
+		if (_isConstant) return false;
+		_valid=false;
+		int[] aReachingDefForVar= new int[_bytesForStatements];
+		boolean aIsConst=true;
+		//System.out.println("!!!!Checking if  " + getStatementDescr() + " is constant");
+		for (int bytes=0; bytes<_useVars.length; bytes++){
+			for (int bits=0; bits<32;bits++){
+				if ((_useVars[bytes] & (1<< bits))!=0){
+					//System.out.println("var " + ((bytes << 5)|bits) + " is used  usevars:" + _useVars[bytes]);
+					//System.out.println("Reached by definitions: ");
+					printDefList(_inDefs);
+					for (int i=0; i<_bytesForStatements;i++){
+						aReachingDefForVar[i] = _varToStatements[(bytes << 5)|bits][i] & _inDefs[i];
+					}
+					//aIsConst &= allDefsConstant(aReachingDefForVar);
+					if(allDefsConstantAndEqual(aReachingDefForVar)){
+						//toggle bit no [bits] = set it to zero as it is one
+						_useVars[bytes]^= (1<< bits);
+						//System.out.println("*** " + getStatementDescr() + "toggle bit " + ((bytes << 5)|bits) + "***");
+						_inVars[bytes] = _useVars[bytes] & _defNegVars[bytes];
+					}else{
+						//System.out.println("not all defs constant for variable " + ((bytes << 5)|bits));
+						aIsConst=false;
+					}
+				}
+			}
+		}
+		if (aIsConst && !(_lhs==null ||_lhs.isEmpty())){
+			_unrolledExpr+= "xx_xx=" + _rhs + ";";
+			//try{
+				_exprValue = evaluate(_unrolledExpr);
+				//System.out.println("Expr: *" + _unrolledExpr + "* evaluated to: " + _exprValue);
+			//}catch(IllegalArgumentException e){
+				//System.out.println("At lest one variable of the expression remains undefined: " + _rhs);
+			//}
+		}
+		//boolean aChangeInResult = (aIsConst!= _isConstant);
+		boolean aChangeInResult = (_constantStuckToFalse)? false : aIsConst!= _isConstant;
+		_isConstant = aIsConst;
+		return aChangeInResult;
+		//}
+	}
+
+	public boolean isConstant(){
+		return (_constantStuckToFalse)? false: _isConstant;
+	}
+	
+	public boolean isInfected(){
+		return _infected;
+	}
+	
+	public String getExpressionString(){
+		return _lhs + "=" + _exprValue;
+	}
+	
+	public int getExpressionValue(){
+		return _exprValue;
+	}
+
+	public int[] getKillCandidates(){
+		return _killCandidates;
+	}
+	
+	public void setInfected(boolean iInfected){
+		_infected = iInfected;
+	}
+
+	public boolean determineKilledSets(){
+		boolean aChange=false;
+		//if (iYouCouldKill==null) iYouCouldKill=new int[_bytesForStatements];
+		int [] aKillOut = new int[_bytesForStatements];
+		int [] aKillIn = new int[_bytesForStatements];
+		if (!_valid){
+			_valid=true;
+			//System.out.println("determineKilledSets for " + getStatementDescr() ); 
+			for(LiveVariableNode aPred: _predList) {
+				int[] aKillCandidatesPred = aPred.getKillCandidates();
+				for (int i=0; i<_bytesForStatements;i++){
+					aKillOut[i] |= aKillCandidatesPred[i];
+					aKillIn[i] |= aKillCandidatesPred[i];
+				}
+			}
+			//System.out.println( "aLocalKillCandidates[0] " + aLocalKillCandidates[0]); 
+			//System.out.println( "killDefs[0] before" + _killDefs[0]); 
+			if (_myDefID!=-1){
+				//System.out.println("Statement " + _myDefID + " (" + getStatementDescr() + ") defines: " + _generateDefs[0] + " could kill input: " + aLocalKillCandidates[0]);
+				for (int bytes=0; bytes<_defVars.length; bytes++){
+					for (int bits=0; bits<32;bits++){
+						if ((_defVars[bytes] & (1<< bits))!=0){   //for all variables which are defined in this statement
+							for (int i=0; i<_bytesForStatements;i++){
+								//killDefs = definitions representing kill candidates in program flow & all statements affecting the current variable targeted in this definition
+								//all kill candidates -> for a specific variable -> variable determined by defVars  
+								//_killDefs[i] |= (aLocalKillCandidates[i] & _varToStatements[(bytes << 5)|bits][i]);
+								_killDefs[i] |= (aKillIn[i] & _varToStatements[(bytes << 5)|bits][i]);
+								//System.out.println( "killDefs[i] " + _killDefs[i] + " i" + i); 
+								//int oldCandidates = aLocalKillCandidates[i];
+								//delete all kill candidates for the variable yielded by that definition
+								//aLocalKillCandidates[i] &= ~ _varToStatements[(bytes << 5)|bits][i];
+								aKillOut[i] &= ~ _varToStatements[(bytes << 5)|bits][i];
+								//add this definition as killer for the variable
+								//aLocalKillCandidates[i] |= _generateDefs[i];
+								aKillOut[i] |= _generateDefs[i];
+								//aChange |= (oldCandidates!=aLocalKillCandidates[i]);
+							}
+						}
+					}
+				}
+			}
+			//System.out.println( "killDefs[0] " + _killDefs[0]); 
+			for (int i=0; i<_bytesForStatements;i++){
+				//aChange |= (_killCandidates[i]!=aLocalKillCandidates[i]);
+				aChange |= (_killCandidates[i]!=aKillOut[i]);
+				//_killCandidates[i]=aLocalKillCandidates[i];
+				_killCandidates[i]=aKillOut[i];
+			}
+			if (aChange){
+				for(LiveVariableNode aSucc: _succList) aSucc.invalidate();
+			}
+		}
+		return aChange;
+	}
+
+	public String getStatementDescr(){
+		String aName = "| Live ID: " + _myDefID + " | ";
+		if (_linkedElem==null)
+				aName += "cmd type: unknown | cmd ID: unknown";
+		else
+			aName += "cmd type: " + _linkedElem.getName() + " | cmd ID: " + _linkedElem.getID();
+		aName+= " | infected: " + _infected;
+		if (!(_lhs==null || _rhs==null || _lhs.isEmpty() || _rhs.isEmpty()))
+			aName += " | action: " + _lhs + "=" + _rhs;
+		aName += " | const: ";
+		if (_isConstant){
+			if (_lhs==null || _lhs.isEmpty())
+				aName+= "true";
+			else
+				aName+= _exprValue;
+		}else 
+			aName += "false"; 
+		aName += " | to be removed: " + canBeRemoved() + " |";
+		return aName; 
+	}
+
+	public void invalidate(){
+		_valid=false;
+	}
+
+	public void reachingDefinitionsInit(){
+		invalidate();
+		for (int i=0; i<_bytesForStatements;i++)
+			_outDefs[i] = _generateDefs[i] & (~_killDefs[i]);
+		//System.out.println("out Defs " + getStatementDescr() + " " + _outDefs[0] + " generate Defs: " + _generateDefs[0] + " kill Defs: " + _killDefs[0]);
+	}
+
+	public boolean reachingDefinitionAnalysis(){
+		boolean aSuccInvalidated=false;
+		if (!_valid){
+			_valid=true;
+			for(LiveVariableNode aPred: _predList) {
+				int[] aPredOutDefs = aPred.getOutDefs();
+				for (int i=0; i<_bytesForStatements;i++){
+					_inDefs[i] |= aPredOutDefs[i];
+					int aOutDefsOld=_outDefs[i];
+					_outDefs[i] = _generateDefs[i] | _inDefs[i] & (~_killDefs[i]);
+					if (aOutDefsOld!=_outDefs[i]) aSuccInvalidated=true; 
+				} 
+			}
+			if(aSuccInvalidated){
+				for(LiveVariableNode aSucc: _succList)
+					aSucc.invalidate();
+			}
+		}
+		return aSuccInvalidated;
+	}
+
+	public boolean liveVariableAnalysis(){
+		boolean aPredInvalidated=false;
+		if (!_valid){
+			_valid=true;
+			/*if (_linkedElem==null)
+				System.out.print("recalculate waitRequest invalidate: ");
+			else 
+				System.out.print("recalculate " + _linkedElem.getName() + " " + _linkedElem.getID() + "invalidate: ");*/
+			for(LiveVariableNode aSucc: _succList) {
+				int[] aSuccInVars = aSucc.getInVars();
+				for (int i=0; i<aSuccInVars.length;i++){
+					_outVars[i] |= aSuccInVars[i];
+					int aInVarsOld=_inVars[i];
+					_inVars[i] = _useVars[i] | _outVars[i] & _defNegVars[i];
+					if (aInVarsOld!=_inVars[i]) aPredInvalidated=true; 
+				} 
+			}
+			if(aPredInvalidated){
+				for(LiveVariableNode aPred: _predList){
+					aPred.invalidate();
+					/*if (aPred.getLinkedElement()==null)
+						System.out.print("waitRequest, ");
+					else
+						System.out.print(aPred.getLinkedElement().getID() + ", ");*/
+				}
+			}
+			//System.out.println();
+		}
+		return aPredInvalidated;
+	}
+	
+	public boolean infectionAnalysis(){
+		if (_infected)
+			return false;
+		else{
+			if (_superiorBranchNode!=null && _superiorBranchNode.isInfected()){
+				_infected=true;
+			}else{
+				int[] aRelevantDefs = new int[_bytesForStatements];
+				for (int bytes=0; bytes<_useVars.length; bytes++){
+					for (int bits=0; bits<32;bits++){
+						if ((_useVars[bytes] & (1<< bits))!=0){   //for all variables which are defined in this statement
+							for (int i=0; i<_bytesForStatements;i++){
+								 aRelevantDefs[i] |=_inDefs[i] & _varToStatements[(bytes << 5)|bits][i];
+							}						
+						}
+					}
+				}
+				_infected |= defsInfected(aRelevantDefs);
+			}
+		}
+		return _infected;
+	}
+	
+	private boolean defsInfected(int[] iDefs){
+		boolean aInfected=false;
+		for (int bytes=0; bytes<iDefs.length && !aInfected; bytes++){
+			for (int bits=0; bits<32 && !aInfected;bits++){
+				if ((iDefs[bytes] & (1<< bits))!=0){ 
+					aInfected |= _defLookup[(bytes << 5)|bits].isInfected();
+				}
+			}
+		}
+		return aInfected;
+	}
+
+	public TMLActivityElement getLinkedElement(){
+		return _linkedElem;
+	}
+
+	public boolean isEmptyNode(){
+		if (_succList.size()>1) return false;
+		for (int i=0; i<_defVars.length;i++)
+			if (_defVars[i]!=0) return false;
+		for (int i=0; i<_useVars.length;i++)
+			if (_useVars[i]!=0) return false;
+		return true;
+	}
+
+	public void setSuccessor(LiveVariableNode iSucc){
+		if(iSucc!=null){
+			_succList.add(iSucc);
+			iSucc.setPredecessor(this);
+		}
+	}
+
+	private void setPredecessor(LiveVariableNode iPred){
+		_predList.add(iPred);
+	}
+
+	public int[] getInVars(){
+		return _inVars;
+	}
+
+	public int[] getOutVars(){
+		return _outVars;
+	}
+	
+	public int[] getInDefs(){
+		return _inDefs;
+	}
+
+	public int[] getOutDefs(){
+		return _outDefs;
+	}
+
+	public boolean canBeRemoved(){
+		if ((_lhs==null || _lhs.isEmpty()) && (_rhs==null || _rhs.isEmpty()) && !(_linkedElem==null || _linkedElem instanceof TMLNotifiedEvent || _linkedElem instanceof TMLRandom)) return false;
+		for (int i=0; i<_defVars.length;i++){
+			if ((_defVars[i] & _outVars[i]) !=0) return false;
+		}
+		return true;
+	}
+
+	public String getLiveVariableString(){
+		return intArrayToHexString(_outVars);
+	}
+
+	public String getStateModificationString(){
+		return intArrayToHexString(_defVars);
+	}
+
+	private String intArrayToHexString(int[] iArray){
+		String aResult = "array(" + iArray.length; 	
+		for (int bytes=0; bytes<iArray.length; bytes++){
+			//for (int bits=0; bits<32; bits+=8)
+				aResult+= ", 0x" + Integer.toHexString(iArray[bytes]);
+		}
+		aResult+=")";
+		return aResult;
+	}
+}
-- 
GitLab