private static bool IsTrivialStackAssignment(Exprent first) { if (first.type == Exprent.Exprent_Assignment) { AssignmentExprent asf = (AssignmentExprent)first; if (asf.GetLeft().type == Exprent.Exprent_Var && asf.GetRight().type == Exprent.Exprent_Var) { VarExprent left = (VarExprent)asf.GetLeft(); VarExprent right = (VarExprent)asf.GetRight(); return(left.GetIndex() == right.GetIndex() && left.IsStack() && right.IsStack()); } } return(false); }
private static bool SetDefinition(Exprent expr, int index) { if (expr.type == Exprent.Exprent_Assignment) { Exprent left = ((AssignmentExprent)expr).GetLeft(); if (left.type == Exprent.Exprent_Var) { VarExprent var = (VarExprent)left; if (var.GetIndex() == index) { var.SetDefinition(true); return(true); } } } return(false); }
private void ProcessExprent(Exprent expr, SFormsFastMapDirect[] varmaparr, Statement stat, bool calcLiveVars) { if (expr == null) { return; } VarExprent varassign = null; bool finished = false; switch (expr.type) { case Exprent.Exprent_Assignment: { AssignmentExprent assexpr = (AssignmentExprent)expr; if (assexpr.GetCondType() == AssignmentExprent.Condition_None) { Exprent dest = assexpr.GetLeft(); if (dest.type == Exprent.Exprent_Var) { varassign = (VarExprent)dest; } } break; } case Exprent.Exprent_Function: { FunctionExprent func = (FunctionExprent)expr; switch (func.GetFuncType()) { case FunctionExprent.Function_Iif: { ProcessExprent(func.GetLstOperands()[0], varmaparr, stat, calcLiveVars); SFormsFastMapDirect varmapFalse; if (varmaparr[1] == null) { varmapFalse = new SFormsFastMapDirect(varmaparr[0]); } else { varmapFalse = varmaparr[1]; varmaparr[1] = null; } ProcessExprent(func.GetLstOperands()[1], varmaparr, stat, calcLiveVars); SFormsFastMapDirect[] varmaparrNeg = new SFormsFastMapDirect[] { varmapFalse, null }; ProcessExprent(func.GetLstOperands()[2], varmaparrNeg, stat, calcLiveVars); MergeMaps(varmaparr[0], varmaparrNeg[0]); varmaparr[1] = null; finished = true; break; } case FunctionExprent.Function_Cadd: { ProcessExprent(func.GetLstOperands()[0], varmaparr, stat, calcLiveVars); SFormsFastMapDirect[] varmaparrAnd = new SFormsFastMapDirect[] { new SFormsFastMapDirect (varmaparr[0]), null }; ProcessExprent(func.GetLstOperands()[1], varmaparrAnd, stat, calcLiveVars); // false map varmaparr[1] = MergeMaps(varmaparr[varmaparr[1] == null ? 0 : 1], varmaparrAnd[varmaparrAnd [1] == null ? 0 : 1]); // true map varmaparr[0] = varmaparrAnd[0]; finished = true; break; } case FunctionExprent.Function_Cor: { ProcessExprent(func.GetLstOperands()[0], varmaparr, stat, calcLiveVars); SFormsFastMapDirect[] varmaparrOr = new SFormsFastMapDirect[] { new SFormsFastMapDirect (varmaparr[varmaparr[1] == null ? 0 : 1]), null }; ProcessExprent(func.GetLstOperands()[1], varmaparrOr, stat, calcLiveVars); // false map varmaparr[1] = varmaparrOr[varmaparrOr[1] == null ? 0 : 1]; // true map varmaparr[0] = MergeMaps(varmaparr[0], varmaparrOr[0]); finished = true; break; } } break; } } if (!finished) { List <Exprent> lst = expr.GetAllExprents(); lst.Remove(varassign); foreach (Exprent ex in lst) { ProcessExprent(ex, varmaparr, stat, calcLiveVars); } } SFormsFastMapDirect varmap = varmaparr[0]; // field access if (expr.type == Exprent.Exprent_Field) { int?index; if (mapFieldVars.ContainsKey(expr.id)) { index = mapFieldVars.GetOrNullable(expr.id); } else { index = fieldvarcounter--; Sharpen.Collections.Put(mapFieldVars, expr.id, index); // ssu graph ssuversions.CreateNode(new VarVersionPair(index, 1)); } SetCurrentVar(varmap, index, 1); } else if (expr.type == Exprent.Exprent_Invocation || (expr.type == Exprent.Exprent_Assignment && ((AssignmentExprent)expr).GetLeft().type == Exprent.Exprent_Field) || (expr. type == Exprent.Exprent_New && ((NewExprent)expr).GetNewType().type == ICodeConstants .Type_Object) || expr.type == Exprent.Exprent_Function) { bool ismmpp = true; if (expr.type == Exprent.Exprent_Function) { ismmpp = false; FunctionExprent fexpr = (FunctionExprent)expr; if (fexpr.GetFuncType() >= FunctionExprent.Function_Imm && fexpr.GetFuncType() <= FunctionExprent.Function_Ppi) { if (fexpr.GetLstOperands()[0].type == Exprent.Exprent_Field) { ismmpp = true; } } } if (ismmpp) { varmap.RemoveAllFields(); } } if (varassign != null) { int varindex = varassign.GetIndex(); if (varassign.GetVersion() == 0) { // get next version int nextver = GetNextFreeVersion(varindex, stat); // set version varassign.SetVersion(nextver); // ssu graph ssuversions.CreateNode(new VarVersionPair(varindex, nextver)); SetCurrentVar(varmap, varindex, nextver); } else { if (calcLiveVars) { VarMapToGraph(new VarVersionPair(varindex, varassign.GetVersion()), varmap); } SetCurrentVar(varmap, varindex, varassign.GetVersion()); } } else if (expr.type == Exprent.Exprent_Function) { // MM or PP function FunctionExprent func_1 = (FunctionExprent)expr; switch (func_1.GetFuncType()) { case FunctionExprent.Function_Imm: case FunctionExprent.Function_Mmi: case FunctionExprent.Function_Ipp: case FunctionExprent.Function_Ppi: { if (func_1.GetLstOperands()[0].type == Exprent.Exprent_Var) { VarExprent var = (VarExprent)func_1.GetLstOperands()[0]; int varindex = var.GetIndex(); VarVersionPair varpaar = new VarVersionPair(varindex, var.GetVersion()); // ssu graph VarVersionPair phantomver = phantomppnodes.GetOrNull(varpaar); if (phantomver == null) { // get next version int nextver = GetNextFreeVersion(varindex, null); phantomver = new VarVersionPair(varindex, nextver); //ssuversions.createOrGetNode(phantomver); ssuversions.CreateNode(phantomver); VarVersionNode vernode = ssuversions.nodes.GetWithKey(varpaar); FastSparseSetFactory <int> .FastSparseSet <int> vers = factory.SpawnEmptySet(); if (vernode.preds.Count == 1) { vers.Add(new Sharpen.EnumeratorAdapter <VarVersionEdge>(vernode.preds.GetEnumerator()).Next().source.version); } else { foreach (VarVersionEdge edge in vernode.preds) { vers.Add(new Sharpen.EnumeratorAdapter <VarVersionEdge>(edge.source.preds.GetEnumerator()).Next().source.version); } } vers.Add(nextver); CreateOrUpdatePhiNode(varpaar, vers, stat); Sharpen.Collections.Put(phantomppnodes, varpaar, phantomver); } if (calcLiveVars) { VarMapToGraph(varpaar, varmap); } SetCurrentVar(varmap, varindex, var.GetVersion()); } break; } } } else if (expr.type == Exprent.Exprent_Var) { VarExprent vardest = (VarExprent)expr; int varindex = vardest.GetIndex(); int current_vers = vardest.GetVersion(); FastSparseSetFactory <int> .FastSparseSet <int> vers = varmap.Get(varindex); int cardinality = vers.GetCardinality(); if (cardinality == 1) { // size == 1 if (current_vers != 0) { if (calcLiveVars) { VarMapToGraph(new VarVersionPair(varindex, current_vers), varmap); } SetCurrentVar(varmap, varindex, current_vers); } else { // split last version int usever = GetNextFreeVersion(varindex, stat); // set version vardest.SetVersion(usever); SetCurrentVar(varmap, varindex, usever); // ssu graph int lastver = new Sharpen.EnumeratorAdapter <int>(vers.GetEnumerator()).Next(); VarVersionNode prenode = ssuversions.nodes.GetWithKey(new VarVersionPair(varindex , lastver)); VarVersionNode usenode = ssuversions.CreateNode(new VarVersionPair(varindex, usever )); VarVersionEdge edge = new VarVersionEdge(VarVersionEdge.Edge_General, prenode, usenode ); prenode.AddSuccessor(edge); usenode.AddPredecessor(edge); } } else if (cardinality == 2) { // size > 1 if (current_vers != 0) { if (calcLiveVars) { VarMapToGraph(new VarVersionPair(varindex, current_vers), varmap); } SetCurrentVar(varmap, varindex, current_vers); } else { // split version int usever = GetNextFreeVersion(varindex, stat); // set version vardest.SetVersion(usever); // ssu node ssuversions.CreateNode(new VarVersionPair(varindex, usever)); SetCurrentVar(varmap, varindex, usever); current_vers = usever; } CreateOrUpdatePhiNode(new VarVersionPair(varindex, current_vers), vers, stat); } } }
public VarVersionPair(VarExprent var) { this.var = var.GetIndex(); this.version = var.GetVersion(); }
private static bool BuildIff(Statement stat, SSAConstructorSparseEx ssa) { if (stat.type == Statement.Type_If && stat.GetExprents() == null) { IfStatement statement = (IfStatement)stat; Exprent ifHeadExpr = statement.GetHeadexprent(); HashSet <int> ifHeadExprBytecode = (ifHeadExpr == null ? null : ifHeadExpr.bytecode ); if (statement.iftype == IfStatement.Iftype_Ifelse) { Statement ifStatement = statement.GetIfstat(); Statement elseStatement = statement.GetElsestat(); if (ifStatement.GetExprents() != null && ifStatement.GetExprents().Count == 1 && elseStatement.GetExprents() != null && elseStatement.GetExprents().Count == 1 && ifStatement.GetAllSuccessorEdges().Count == 1 && elseStatement.GetAllSuccessorEdges ().Count == 1 && ifStatement.GetAllSuccessorEdges()[0].GetDestination() == elseStatement .GetAllSuccessorEdges()[0].GetDestination()) { Exprent ifExpr = ifStatement.GetExprents()[0]; Exprent elseExpr = elseStatement.GetExprents()[0]; if (ifExpr.type == Exprent.Exprent_Assignment && elseExpr.type == Exprent.Exprent_Assignment) { AssignmentExprent ifAssign = (AssignmentExprent)ifExpr; AssignmentExprent elseAssign = (AssignmentExprent)elseExpr; if (ifAssign.GetLeft().type == Exprent.Exprent_Var && elseAssign.GetLeft().type == Exprent.Exprent_Var) { VarExprent ifVar = (VarExprent)ifAssign.GetLeft(); VarExprent elseVar = (VarExprent)elseAssign.GetLeft(); if (ifVar.GetIndex() == elseVar.GetIndex() && ifVar.IsStack()) { // ifVar.getIndex() >= VarExprent.STACK_BASE) { bool found = false; foreach (KeyValuePair <VarVersionPair, FastSparseSetFactory <int> .FastSparseSet <int> > ent in ssa.GetPhi()) { if (ent.Key.var == ifVar.GetIndex()) { if (ent.Value.Contains(ifVar.GetVersion()) && ent.Value.Contains(elseVar.GetVersion ())) { found = true; break; } } } if (found) { List <Exprent> data = new List <Exprent>(statement.GetFirst().GetExprents()); List <Exprent> operands = Sharpen.Arrays.AsList(statement.GetHeadexprent().GetCondition (), ifAssign.GetRight(), elseAssign.GetRight()); data.Add(new AssignmentExprent(ifVar, new FunctionExprent(FunctionExprent.Function_Iif , operands, ifHeadExprBytecode), ifHeadExprBytecode)); statement.SetExprents(data); if ((statement.GetAllSuccessorEdges().Count == 0)) { StatEdge ifEdge = ifStatement.GetAllSuccessorEdges()[0]; StatEdge edge = new StatEdge(ifEdge.GetType(), statement, ifEdge.GetDestination() ); statement.AddSuccessor(edge); if (ifEdge.closure != null) { ifEdge.closure.AddLabeledEdge(edge); } } SequenceHelper.DestroyAndFlattenStatement(statement); return(true); } } } } else if (ifExpr.type == Exprent.Exprent_Exit && elseExpr.type == Exprent.Exprent_Exit) { ExitExprent ifExit = (ExitExprent)ifExpr; ExitExprent elseExit = (ExitExprent)elseExpr; if (ifExit.GetExitType() == elseExit.GetExitType() && ifExit.GetValue() != null && elseExit.GetValue() != null && ifExit.GetExitType() == ExitExprent.Exit_Return) { // throw is dangerous, because of implicit casting to a common superclass // e.g. throws IOException and throw true?new RuntimeException():new IOException(); won't work if (ifExit.GetExitType() == ExitExprent.Exit_Throw && !ifExit.GetValue().GetExprType ().Equals(elseExit.GetValue().GetExprType())) { // note: getExprType unreliable at this point! return(false); } // avoid flattening to 'iff' if any of the branches is an 'iff' already if (IsIff(ifExit.GetValue()) || IsIff(elseExit.GetValue())) { return(false); } List <Exprent> data = new List <Exprent>(statement.GetFirst().GetExprents()); data.Add(new ExitExprent(ifExit.GetExitType(), new FunctionExprent(FunctionExprent .Function_Iif, Sharpen.Arrays.AsList(statement.GetHeadexprent().GetCondition(), ifExit.GetValue(), elseExit.GetValue()), ifHeadExprBytecode), ifExit.GetRetType( ), ifHeadExprBytecode)); statement.SetExprents(data); StatEdge retEdge = ifStatement.GetAllSuccessorEdges()[0]; Statement closure = retEdge.closure == statement?statement.GetParent() : retEdge .closure; statement.AddSuccessor(new StatEdge(StatEdge.Type_Break, statement, retEdge.GetDestination (), closure)); SequenceHelper.DestroyAndFlattenStatement(statement); return(true); } } } } } return(false); }
private void ProcessExprent(Exprent expr, SFormsFastMapDirect[] varmaparr) { if (expr == null) { return; } VarExprent varassign = null; bool finished = false; switch (expr.type) { case Exprent.Exprent_Assignment: { AssignmentExprent assexpr = (AssignmentExprent)expr; if (assexpr.GetCondType() == AssignmentExprent.Condition_None) { Exprent dest = assexpr.GetLeft(); if (dest.type == Exprent.Exprent_Var) { varassign = (VarExprent)dest; } } break; } case Exprent.Exprent_Function: { FunctionExprent func = (FunctionExprent)expr; switch (func.GetFuncType()) { case FunctionExprent.Function_Iif: { ProcessExprent(func.GetLstOperands()[0], varmaparr); SFormsFastMapDirect varmapFalse; if (varmaparr[1] == null) { varmapFalse = new SFormsFastMapDirect(varmaparr[0]); } else { varmapFalse = varmaparr[1]; varmaparr[1] = null; } ProcessExprent(func.GetLstOperands()[1], varmaparr); SFormsFastMapDirect[] varmaparrNeg = new SFormsFastMapDirect[] { varmapFalse, null }; ProcessExprent(func.GetLstOperands()[2], varmaparrNeg); MergeMaps(varmaparr[0], varmaparrNeg[0]); varmaparr[1] = null; finished = true; break; } case FunctionExprent.Function_Cadd: { ProcessExprent(func.GetLstOperands()[0], varmaparr); SFormsFastMapDirect[] varmaparrAnd = new SFormsFastMapDirect[] { new SFormsFastMapDirect (varmaparr[0]), null }; ProcessExprent(func.GetLstOperands()[1], varmaparrAnd); // false map varmaparr[1] = MergeMaps(varmaparr[varmaparr[1] == null ? 0 : 1], varmaparrAnd[varmaparrAnd [1] == null ? 0 : 1]); // true map varmaparr[0] = varmaparrAnd[0]; finished = true; break; } case FunctionExprent.Function_Cor: { ProcessExprent(func.GetLstOperands()[0], varmaparr); SFormsFastMapDirect[] varmaparrOr = new SFormsFastMapDirect[] { new SFormsFastMapDirect (varmaparr[varmaparr[1] == null ? 0 : 1]), null }; ProcessExprent(func.GetLstOperands()[1], varmaparrOr); // false map varmaparr[1] = varmaparrOr[varmaparrOr[1] == null ? 0 : 1]; // true map varmaparr[0] = MergeMaps(varmaparr[0], varmaparrOr[0]); finished = true; break; } } break; } } if (finished) { return; } List <Exprent> lst = expr.GetAllExprents(); lst.Remove(varassign); foreach (Exprent ex in lst) { ProcessExprent(ex, varmaparr); } SFormsFastMapDirect varmap = varmaparr[0]; if (varassign != null) { int varindex = varassign.GetIndex(); if (varassign.GetVersion() == 0) { // get next version int nextver = GetNextFreeVersion(varindex); // set version varassign.SetVersion(nextver); SetCurrentVar(varmap, varindex, nextver); } else { SetCurrentVar(varmap, varindex, varassign.GetVersion()); } } else if (expr.type == Exprent.Exprent_Var) { VarExprent vardest = (VarExprent)expr; int varindex = vardest.GetIndex(); FastSparseSetFactory <int> .FastSparseSet <int> vers = varmap.Get(varindex); int cardinality = vers.GetCardinality(); if (cardinality == 1) { // == 1 // set version int it = new Sharpen.EnumeratorAdapter <int>(vers.GetEnumerator()).Next(); vardest.SetVersion(it); } else if (cardinality == 2) { // size > 1 int current_vers = vardest.GetVersion(); VarVersionPair currpaar = new VarVersionPair(varindex, current_vers); if (current_vers != 0 && phi.ContainsKey(currpaar)) { SetCurrentVar(varmap, varindex, current_vers); // update phi node phi.GetOrNull(currpaar).Union(vers); } else { // increase version int nextver = GetNextFreeVersion(varindex); // set version vardest.SetVersion(nextver); SetCurrentVar(varmap, varindex, nextver); // create new phi node Sharpen.Collections.Put(phi, new VarVersionPair(varindex, nextver), vers); } } } }
private static bool FindAndRemoveParameterCheck(Statement stat, StructMethod mt) { Statement st = stat.GetFirst(); while (st.type == Statement.Type_Sequence) { st = st.GetFirst(); } if (st.type == Statement.Type_If) { IfStatement ifstat = (IfStatement)st; Statement ifbranch = ifstat.GetIfstat(); Exprent if_condition = ifstat.GetHeadexprent().GetCondition(); bool is_notnull_check = false; // TODO: FUNCTION_NE also possible if reversed order (in theory) if (ifbranch != null && if_condition.type == Exprent.Exprent_Function && ((FunctionExprent )if_condition).GetFuncType() == FunctionExprent.Function_Eq && ifbranch.type == Statement.Type_Basicblock && ifbranch.GetExprents().Count == 1 && ifbranch.GetExprents ()[0].type == Exprent.Exprent_Exit) { FunctionExprent func = (FunctionExprent)if_condition; Exprent first_param = func.GetLstOperands()[0]; Exprent second_param = func.GetLstOperands()[1]; if (second_param.type == Exprent.Exprent_Const && second_param.GetExprType().type == ICodeConstants.Type_Null) { // TODO: reversed parameter order if (first_param.type == Exprent.Exprent_Var) { VarExprent var = (VarExprent)first_param; bool thisvar = !mt.HasModifier(ICodeConstants.Acc_Static); MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); // parameter annotations StructAnnotationParameterAttribute param_annotations = mt.GetAttribute(StructGeneralAttribute .Attribute_Runtime_Invisible_Parameter_Annotations); if (param_annotations != null) { List <List <AnnotationExprent> > param_annotations_lists = param_annotations.GetParamAnnotations (); int method_param_number = [email protected]; int index = thisvar ? 1 : 0; for (int i = 0; i < method_param_number; i++) { if (index == var.GetIndex()) { if (param_annotations_lists.Count >= method_param_number - i) { int shift = method_param_number - param_annotations_lists.Count; // NOTE: workaround for compiler bug, count annotations starting with the last parameter List <AnnotationExprent> annotations = param_annotations_lists[i - shift]; foreach (AnnotationExprent ann in annotations) { if (ann.GetClassName().Equals("org/jetbrains/annotations/NotNull")) { is_notnull_check = true; break; } } } break; } index += md.@params[i].stackSize; } } } } } if (!is_notnull_check) { return(false); } RemoveParameterCheck(stat); return(true); } return(false); }