diff --git a/src/main/rascal/lang/jimple/toolkit/ssa/Helpers.rsc b/src/main/rascal/lang/jimple/toolkit/ssa/Helpers.rsc new file mode 100644 index 00000000..1c7ac2a2 --- /dev/null +++ b/src/main/rascal/lang/jimple/toolkit/ssa/Helpers.rsc @@ -0,0 +1,103 @@ +module lang::jimple::toolkit::ssa::Helpers + +import Node; +import Type; +import List; + +import lang::jimple::toolkit::FlowGraph; +import lang::jimple::core::Syntax; + +public Variable returnStmtVariable(Node graphNode) { + stmtNode(assignStatement) = graphNode; + variableArg = assignStatement[0]; + + switch(variableArg) { + case Variable variable: return variable; + } +} + +public Statement returnStmtNodeBody(Node stmtNode) { + switch(stmtNode) { + case stmtNode(stmtBody): return stmtBody; + } +} + +public Variable returnLeftHandSideVariable(Node stmtNode) { + switch(stmtNode) { + case stmtNode(assign(leftHandSide, _)): return leftHandSide; + } +} + +public Expression returnRightHandSideExpression(Node stmtNode) { + switch(stmtNode) { + case stmtNode(assign(_, rightHandSide)): return rightHandSide; + } +} + +public String returnVariableImmediateName(Immediate immediate) { + switch(immediate) { + case local(String localName): return localName; + default: return ""; + } +} + +public String returnImmediateName(Immediate immediate) { + switch(immediate[0]) { + case String immediateName: return immediateName; + } +} + +public list[Immediate] returnRightHandSideImmediates(Node variableNode) { + rightHandSide = returnRightHandSideExpression(variableNode); + typeOfVariableArg = typeOf(rightHandSide); + + if(typeOfVariableArg.name != "Expression") return []; + + list[Immediate] immediates = returnExpressionImmediates(rightHandSide); + list[Immediate] localVariableImmediates = [ immediate | immediate <- immediates, returnVariableImmediateName(immediate) != ""]; + int variablesCount = size(localVariableImmediates); + + if(variablesCount != 0) return localVariableImmediates; + + return []; +} + +public list[Immediate] returnExpressionImmediates(Expression expression) { + switch(expression) { + case newInstance(Type instanceType): return []; + case newArray(Type baseType, list[ArrayDescriptor] dims): return []; + case cast(Type toType, local(name)): return []; + case instanceOf(Type baseType, local(name)): return [local(name)]; + case invokeExp(_): return []; + case arraySubscript(Name arrayName, _): return [local(arrayName)]; + case stringSubscript(String stringName, local(name)): return [local(stringName)]; + case localFieldRef(Name local, Name className, Type fieldType, Name fieldName): return []; + case fieldRef(Name className, Type fieldType, Name fieldName): return []; + case and(lhs, rhs): return [lhs, rhs]; + case or(lhs, rhs): return [lhs, rhs]; + case xor(lhs, rhs): return [lhs, rhs]; + case reminder(lhs, rhs): return [lhs, rhs]; + case isNull(variable): return [variable]; + case isNotNull(variable): return [variable]; + case cmp(lhs, rhs): return [lhs, rhs]; + case cmpg(lhs, rhs): return [lhs, rhs]; + case cmpl(lhs, rhs): return [lhs, rhs]; + case cmpeq(lhs, rhs): return [lhs, rhs]; + case cmpne(lhs, rhs): return [lhs, rhs]; + case cmpgt(lhs, rhs): return [lhs, rhs]; + case cmpge(lhs, rhs): return [lhs, rhs]; + case cmplt(lhs, rhs): return [lhs, rhs]; + case cmple(lhs, rhs): return [lhs, rhs]; + case shl(lhs, rhs): return [lhs, rhs]; + case shr(lhs, rhs): return [lhs, rhs]; + case ushr(lhs, rhs): return [lhs, rhs]; + case plus(lhs, rhs): return [lhs, rhs]; + case minus(lhs, rhs): return [lhs, rhs]; + case mult(lhs, rhs): return [lhs, rhs]; + case div(lhs, rhs): return [lhs, rhs]; + case lengthOf(local(name)): return [local(name)]; + case neg(local(name)): return [local(name)]; + case immediate(local(name)): return [local(name)]; + default: return []; + } +} diff --git a/src/main/rascal/lang/jimple/toolkit/ssa/VariableRenaming.rsc b/src/main/rascal/lang/jimple/toolkit/ssa/VariableRenaming.rsc index 4f6fb054..cb8851c4 100644 --- a/src/main/rascal/lang/jimple/toolkit/ssa/VariableRenaming.rsc +++ b/src/main/rascal/lang/jimple/toolkit/ssa/VariableRenaming.rsc @@ -15,6 +15,7 @@ import lang::jimple::util::Stack; import lang::jimple::toolkit::FlowGraph; import lang::jimple::core::Syntax; import lang::jimple::toolkit::ssa::DominanceTree; +import lang::jimple::toolkit::ssa::Helpers; map[str, Stack[int]] VARIABLE_VERSION_STACK = (); map[str, int] VARIABLE_ASSIGNMENT_COUNT = (); @@ -50,8 +51,8 @@ public map[Node, list[Node]] replace(Node X) { // Deal with all nodes that aren't assigments bug uses a variable in some way if(isNonAssignmentStatementToRename(X)) { - stmtNode(statement) = X; - Node renamedStatement = stmtNode(replaceImmediateUse(statement)); + statementBody = returnStmtNodeBody(X); + Node renamedStatement = stmtNode(replaceImmediateUse(statementBody)); renameNodeOcurrecies(X, renamedStatement); X = renamedStatement; }; @@ -60,7 +61,7 @@ public map[Node, list[Node]] replace(Node X) { if(isOrdinaryAssignment(X) && !isRenamed(X)) { // Replace right hand side variables - list[Immediate] rightHandNodeImmediates = getRightHandSideImmediates(X); + list[Immediate] rightHandNodeImmediates = returnRightHandSideImmediates(X); for(rightHandSideImmediate <- rightHandNodeImmediates) { newAssignStmt = replaceRightVariableVersion(ADJACENCIES_MATRIX, rightHandSideImmediate, X); @@ -71,7 +72,7 @@ public map[Node, list[Node]] replace(Node X) { // Replace left hand side variables if(isLeftHandSideVariable(X)) { - Variable V = getStmtVariable(X); + Variable V = returnStmtVariable(X); Immediate localVariableImmediate = local(V[0]); int assingmentQuantity = returnAssignmentQuantity(localVariableImmediate); @@ -101,7 +102,7 @@ public map[Node, list[Node]] replace(Node X) { } public void findAndAddPhiFunctionArgs(Node oldNode, Node newNode) { - Variable variable = getStmtVariable(oldNode); + Variable variable = returnStmtVariable(oldNode); variableName = variable[0]; dfsPhiFunctionLookupAndRename(newNode, newNode, variableName); } @@ -157,7 +158,7 @@ public map[Node, list[Node]] replaceNodeOcurrenciesInTrees(map[Node, list[Node]] } public Statement replaceImmediateUse(Statement statement) { - return return addEnclosingStmt(statement, replaceImmediateUse(statement[0])); + return addEnclosingStmt(statement, replaceImmediateUse(statement[0])); } public Statement addEnclosingStmt(Statement statement, Expression expression) { @@ -192,7 +193,7 @@ public Expression replaceImmediateUse(Expression expression) { public Name returnLastVariableVersion(str name) { Immediate immediate = local(name); - variableName = getVariableImmediateName(immediate); + variableName = returnVariableImmediateName(immediate); int versionIndex = getVariableVersionStacked(immediate); str newVariableName = buildVersionName(variableName, versionIndex); @@ -216,7 +217,7 @@ public bool isSkipableStatement(stmtArgument) { } public Node replacePhiFunctionVersion(map[Node, list[Node]] blockTree, Node variableNode) { - stmtNode(assignStatement) = variableNode; + assignStatement = returnStmtNodeBody(variableNode); assign(assignVariable, assignPhiFunction) = assignStatement; phiFunction(phiFunctionVariable, variableVersionList) = assignPhiFunction; variableName = phiFunctionVariable[0]; @@ -257,7 +258,7 @@ public Expression renameExpressionVariables(Expression expression, Immediate imm return arraySubscript(newVersionName, local(returnCurrentVersionName(local(localName)))); }; - list[Immediate] immediates = getExpressionImmediates(expression); + list[Immediate] immediates = returnExpressionImmediates(expression); int index = indexOf(immediates, immediateToRename); expression[index] = local(newVersionName); @@ -266,7 +267,7 @@ public Expression renameExpressionVariables(Expression expression, Immediate imm public String returnCurrentVersionName(Immediate immediate) { int variableVersion = getVariableVersionStacked(immediate); - String variableOriginalName = getImmediateName(immediate); + String variableOriginalName = returnImmediateName(immediate); return buildVersionName(variableOriginalName, variableVersion); } @@ -285,18 +286,6 @@ public str buildVersionName(str variableOriginalName, int versionIndex) { return variableOriginalName + "_version-" + toString(versionIndex); } -public String getVariableName(Variable variable) { - switch(variable[0]) { - case String variableName: return variableName; - } -} - -public String getImmediateName(Immediate immediate) { - switch(immediate[0]) { - case String immediateName: return immediateName; - } -} - public bool isLeftHandSideVariable(Node variableNode) { switch(variableNode) { case stmtNode(assign(localVariable(_), _)): return true; @@ -305,21 +294,6 @@ public bool isLeftHandSideVariable(Node variableNode) { } } -public list[Immediate] getRightHandSideImmediates(Node variableNode) { - rightHandSide = returnRightHandSideExpression(variableNode); - typeOfVariableArg = typeOf(rightHandSide); - - if(typeOfVariableArg.name != "Expression") return []; - - list[Immediate] immediates = getExpressionImmediates(rightHandSide); - list[Immediate] localVariableImmediates = [ immediate | immediate <- immediates, getVariableImmediateName(immediate) != ""]; - int variablesCount = size(localVariableImmediates); - - if(variablesCount != 0) return localVariableImmediates; - - return []; -} - public bool ignoreNode(Node variableNode) { switch(variableNode) { case entryNode(): return true; @@ -357,15 +331,6 @@ public bool isPhiFunctionAssigment(Node variableNode) { } } -public Variable getStmtVariable(Node graphNode) { - stmtNode(assignStatement) = graphNode; - variableArg = assignStatement[0]; - - switch(variableArg) { - case Variable variable: return variable; - } -} - public bool isVariable(Node graphNode) { if (size(graphNode[..]) == 0) return false; @@ -390,71 +355,12 @@ public bool isSameVariable(Node graphNode, Variable variable) { return variableArg == variable; } -public list[Immediate] getExpressionImmediates(Expression expression) { - switch(expression) { - case newInstance(Type instanceType): return []; - case newArray(Type baseType, list[ArrayDescriptor] dims): return []; - case cast(Type toType, local(name)): return []; - case instanceOf(Type baseType, local(name)): return [local(name)]; - case invokeExp(_): return []; - case arraySubscript(Name arrayName, _): return [local(arrayName)]; - case stringSubscript(String stringName, local(name)): return [local(stringName)]; - case localFieldRef(Name local, Name className, Type fieldType, Name fieldName): return []; - case fieldRef(Name className, Type fieldType, Name fieldName): return []; - case and(lhs, rhs): return [lhs, rhs]; - case or(lhs, rhs): return [lhs, rhs]; - case xor(lhs, rhs): return [lhs, rhs]; - case reminder(lhs, rhs): return [lhs, rhs]; - case isNull(variable): return [variable]; - case isNotNull(variable): return [variable]; - case cmp(lhs, rhs): return [lhs, rhs]; - case cmpg(lhs, rhs): return [lhs, rhs]; - case cmpl(lhs, rhs): return [lhs, rhs]; - case cmpeq(lhs, rhs): return [lhs, rhs]; - case cmpne(lhs, rhs): return [lhs, rhs]; - case cmpgt(lhs, rhs): return [lhs, rhs]; - case cmpge(lhs, rhs): return [lhs, rhs]; - case cmplt(lhs, rhs): return [lhs, rhs]; - case cmple(lhs, rhs): return [lhs, rhs]; - case shl(lhs, rhs): return [lhs, rhs]; - case shr(lhs, rhs): return [lhs, rhs]; - case ushr(lhs, rhs): return [lhs, rhs]; - case plus(lhs, rhs): return [lhs, rhs]; - case minus(lhs, rhs): return [lhs, rhs]; - case mult(lhs, rhs): return [lhs, rhs]; - case div(lhs, rhs): return [lhs, rhs]; - case lengthOf(local(name)): return [local(name)]; - case neg(local(name)): return [local(name)]; - case immediate(local(name)): return [local(name)]; - default: return []; - } -} - -public Variable returnLeftHandSideVariable(Node stmtNode) { - switch(stmtNode) { - case stmtNode(assign(leftHandSide, _)): return leftHandSide; - } -} - -public Expression returnRightHandSideExpression(Node stmtNode) { - switch(stmtNode) { - case stmtNode(assign(_, rightHandSide)): return rightHandSide; - } -} - public bool isNonAssignmentStatementToRename(Node graphNode) { return !isReplaced(graphNode) && !isOrdinaryAssignment(graphNode) && !ignoreNode(graphNode) && !isPhiFunctionAssigment(graphNode); } -public String getVariableImmediateName(Immediate immediate) { - switch(immediate) { - case local(String localName): return localName; - default: return ""; - } -} - public int returnAssignmentQuantity(Immediate immediate) { - str name = getVariableImmediateName(immediate); + str name = returnVariableImmediateName(immediate); if(name in VARIABLE_ASSIGNMENT_COUNT) return VARIABLE_ASSIGNMENT_COUNT[name]; @@ -463,7 +369,7 @@ public int returnAssignmentQuantity(Immediate immediate) { } public int iterateAssignmentQuantity(Immediate immediate) { - str name = getVariableImmediateName(immediate); + str name = returnVariableImmediateName(immediate); VARIABLE_ASSIGNMENT_COUNT[name] = VARIABLE_ASSIGNMENT_COUNT[name] + 1; @@ -471,7 +377,7 @@ public int iterateAssignmentQuantity(Immediate immediate) { } public str stackVariableVersion(Immediate immediate, int renameIndex) { - str name = getVariableImmediateName(immediate); + str name = returnVariableImmediateName(immediate); VARIABLE_VERSION_STACK[name] = name in VARIABLE_VERSION_STACK ? push(renameIndex, VARIABLE_VERSION_STACK[name]) : push(0, emptyStack()); @@ -479,7 +385,7 @@ public str stackVariableVersion(Immediate immediate, int renameIndex) { } public int getVariableVersionStacked(Immediate immediate) { - str name = getVariableImmediateName(immediate); + str name = returnVariableImmediateName(immediate); if(name in VARIABLE_VERSION_STACK) return peekIntValue(VARIABLE_VERSION_STACK[name]); @@ -488,10 +394,10 @@ public int getVariableVersionStacked(Immediate immediate) { } public Stack[int] popOldNode(Node oldNode) { - Variable V = getStmtVariable(oldNode); + Variable V = returnStmtVariable(oldNode); Immediate localVariableImmediate = local(V[0]); - str name = getVariableImmediateName(localVariableImmediate); + str name = returnVariableImmediateName(localVariableImmediate); newStackTuple = pop(VARIABLE_VERSION_STACK[name])[1]; VARIABLE_VERSION_STACK[name] = newStackTuple;