private void preprocess(GFunction gFunc) { var varMap = getVarMap(gFunc); foreach (var pair in varMap) { var duc = pair.Value .SelectMany(x => x.ducAssignments.data) .Union(pair.Value.SelectMany(x => x.ducReferences.data)) .ToList( ); foreach (var entry in duc) { var lhsStmt = blockMap[entry.block].gStatements[entry.line - 1]; var rhsStmt = gFunc.blockMap[entry.block].gStatements[entry.line - 1]; if (rhsStmt.vars.Count == lhsStmt.vars.Count) { for (int i = 0; i < lhsStmt.vars.Count; ++i) { string lvar = lhsStmt.vars[i]; string rvar = rhsStmt.vars[i]; if (gFunc.usedToDeclMap.ContainsKey(rvar) && varMap[usedToDeclMap[lvar]].Contains(gFunc.usedToDeclMap[rvar])) { rhsStmt.Rename(rvar, lvar); } } } } } }
public decimal Compare(GFunction gFunc, bool doNormalizeConditionals = false, bool doReorderPhi = false) { PreProcess(gFunc); decimal count = 0; var lhsStmts = GStatements; var rhsStmts = gFunc.GStatements; lhsStmts.RemoveAll(s => s is GBBStmt); rhsStmts.RemoveAll(s => s is GBBStmt); count = LevenshteinDistance(lhsStmts, rhsStmts); decimal result = 100m - 100m * count / Math.Max(lhsStmts.Count, rhsStmts.Count); gFunc.Reset(doNormalizeConditionals, doReorderPhi); return(result); }
private void PreProcessLineByLine(GFunction gFunc) { var varMap = GetVarMap(gFunc); foreach (var pair in varMap) { var duc = pair.Value .SelectMany(x => x.DucAssignments.Data) .Union(pair.Value.SelectMany(x => x.DucReferences.Data)) .ToList( ); foreach (var entry in duc) { if (BlockMap[entry.block].GStatements.Count < entry.line) { continue; } if (gFunc.BlockMap[entry.block].GStatements.Count < entry.line) { continue; } var lhsStmt = BlockMap[entry.block].GStatements[entry.line - 1]; var rhsStmt = gFunc.BlockMap[entry.block].GStatements[entry.line - 1]; if (rhsStmt.Vars.Count == lhsStmt.Vars.Count) { for (int i = 0; i < lhsStmt.Vars.Count; ++i) { string lvar = lhsStmt.Vars[i]; string rvar = rhsStmt.Vars[i]; if (gFunc.UsedToDeclMap.ContainsKey(rvar) && varMap.ContainsKey(UsedToDeclMap[lvar]) && varMap[UsedToDeclMap[lvar]].Contains(gFunc.UsedToDeclMap[rvar])) { rhsStmt.Rename(rvar, lvar); } } } } } }
public decimal Compare(GFunction gFunc) { preprocess(gFunc); decimal count = 0; var lhsStmts = gStatements; var rhsStmts = gFunc.gStatements; for (int i = 0; i < lhsStmts.Count && i < rhsStmts.Count; ++i) { if (lhsStmts[i] == rhsStmts[i]) { ++count; } } decimal result = 200m * count / (lhsStmts.Count + rhsStmts.Count); gFunc.initialize(gFunc.gimple); return(result); }
public static decimal Compare(GFunction lhs, GFunction rhs) { var results = new List <decimal> ( ); var flags = new List <(bool doNormalizeConditionals, bool doReorderPhi)> { (false, false), (false, true), (true, false), (true, true) }; foreach (var lhsFlag in flags) { lhs.Reset(lhsFlag.doNormalizeConditionals, lhsFlag.doReorderPhi); foreach (var rhsFlag in flags) { rhs.Reset(rhsFlag.doNormalizeConditionals, rhsFlag.doReorderPhi); results.Add(lhs.Compare(rhs, rhsFlag.doNormalizeConditionals, rhsFlag.doReorderPhi)); } } return(results.Max( )); }
public Dictionary <GVar, List <GVar> > getVarMap(GFunction gFunc) { Dictionary <GVar, List <GVar> > varMap = new Dictionary <GVar, List <GVar> > ( ); Dictionary <GVar, Dictionary <GVar, decimal> > correlation = new Dictionary <GVar, Dictionary <GVar, decimal> > ( ); foreach (var v1 in gVarsDecl) { foreach (var v2 in gFunc.gVarsDecl) { if (!correlation.ContainsKey(v1)) { correlation[v1] = new Dictionary <GVar, decimal> ( ); } correlation[v1][v2] = v1.map(v2); } var probable = correlation[v1] .Where(x => x.Value != 0) .OrderBy(x => x.Value) .Select(x => x.Key) .ToList( ); var minimal = new List <GVar> ( ); foreach (var v in probable) { if (!v.isSubsetOf(v1)) { continue; } minimal.Add(v); if (v1.map(minimal) > threshold) { varMap[v1] = minimal; break; } } } foreach (var v1 in gFunc.gVarsDecl) { foreach (var v2 in gVarsDecl) { var probable = correlation .Where(x => x.Value[v1] != 0m) .OrderBy(x => x.Value[v1]) .Select(x => x.Key) .ToList( ); var minimal = new List <GVar> ( ); foreach (var v in probable) { minimal.Add(v); if (v1.map(minimal) > threshold) { minimal.ForEach(m => { if (!varMap.ContainsKey(m)) { varMap[m] = new List <GVar> { v1 } } ; } ); break; } } } } //foreach ( var v1 in gVarsDecl ) // foreach ( var v2 in gFunc.gVarsDecl ) // if ( v1.map ( v2 ) == 1m ) // varMap[v1] = v2; return(varMap); }
private void PreProcess(GFunction gFunc) { for (int times = 0; times != Iterations; ++times) { var varMap = GetVarMap(gFunc) .ToDictionary(x => x.Key.Name, x => x.Value.Select(y => y.Name).ToList( )); var revVarMap = varMap .GroupBy(x => string.Join(", ", x.Value.OrderBy(v => v))) .Where(x => x.Count( ) > 1) .ToDictionary(x => x.Key, x => x.Select(y => y.Key).ToList( )); var lhsVars = this.GStatements.SelectMany(b => b.Vars).Distinct( ).ToList( ); var rhsVars = gFunc.GStatements.SelectMany(b => b.Vars).Distinct( ).ToList( ); foreach (var rhsVar in lhsVars) { if (!UsedToDeclMap.ContainsKey(rhsVar)) { continue; } this.Rename(rhsVar, UsedToDeclMap[rhsVar].Name); } foreach (var rhsVar in rhsVars) { if (!gFunc.UsedToDeclMap.ContainsKey(rhsVar)) { continue; } gFunc.Rename(rhsVar, gFunc.UsedToDeclMap[rhsVar].Name); } foreach (var pair in varMap) { if (revVarMap.ContainsKey(pair.Value.First( ))) { this.Rename(pair.Key, pair.Value.First( )); } else { foreach (var v in pair.Value) { gFunc.Rename(v, pair.Key); } } } gFunc.GetVarsUsed( ); gFunc.BuildUsedToDeclMap( ); gFunc.BuildDUC( ); this.GetVarsUsed( ); this.BuildUsedToDeclMap( ); this.BuildDUC( ); if (DumpIntermediateGimple) { var lhsFileName = Path.GetFileNameWithoutExtension(FileName); var rhsFileName = Path.GetFileNameWithoutExtension(gFunc.FileName); DumpGimple($"{Folder}\\{lhsFileName}_{rhsFileName}_pass_{times + 1}.GIMPLE"); gFunc.DumpGimple($"{gFunc.Folder}\\{rhsFileName}_{lhsFileName}_pass_{times + 1}.GIMPLE"); } } }