// map back "trace[start, start + to.size - 1]" through this transformation. // // tinfo is the parent // transformation info for the whole program -- it is used for recursively // calling the mapBack procedure on callee traces public ErrorTraceInstr mapBackTrace(List <ErrorTraceInstr> trace, int start, ModifyTrans tinfo) { Debug.Assert(start >= 0); Debug.Assert(start + to.Count - 1 < trace.Count); // Find the "info" for "from". It is obtained from the // corresponding instruction, if one is provided. Else // we search through "to" to find (any) valid info. InstrInfo info = null; if (correspondingInstr >= 0) { info = trace[start + correspondingInstr].info; } else { // Default info (invalid) info = new InstrInfo(); for (int i = start; i < start + to.Count; i++) { if (trace[i].info.isValid) { info = trace[i].info; break; } } } Debug.Assert(info != null); ErrorTraceInstr ret = null; if (from.type == InstrTypeEnum.CALL || from.type == InstrTypeEnum.ASYNC) { // check if the corresponding instruction is also a call if (correspondingInstr >= 0 && trace[start + correspondingInstr].isCall()) { var calleeTrace = (trace[start + correspondingInstr] as CallInstr).calleeTrace; if (calleeTrace != null) { // Recurse on the callee trace calleeTrace = tinfo.mapBackTrace(calleeTrace); } ret = new CallInstr(from.callee, calleeTrace, (from.type == InstrTypeEnum.ASYNC ? true : false), info); } else { // no corresponding callee trace ret = new CallInstr(from.callee, null, (from.type == InstrTypeEnum.ASYNC ? true : false), info); } } else { ret = new IntraInstr(info); } Debug.Assert(ret != null); return(ret); }
// map back through an identity transformation (basically just recurse // on the callee traces) public static ErrorTraceBlock mapBackTraceIdentity(ErrorTraceBlock tblock, ModifyTrans tinfo) { var ret = new ErrorTraceBlock(tblock.blockName); ret.info = tblock.info; for (int i = 0; i < tblock.Cmds.Count; i++) { var tp = new InstrType(); if (tblock.Cmds[i] is CallInstr) { var ci = tblock.Cmds[i] as CallInstr; if (ci.asyncCall) { tp = new InstrType(InstrTypeEnum.ASYNC, ci.callee); } else { tp = new InstrType(InstrTypeEnum.CALL, ci.callee); } } var it = new InstrTrans(tp); ret.addInstr(it.mapBackTrace(tblock.Cmds, i, tinfo)); } return(ret); }
public UnReadVarEliminator(bool onlyLocals) { this.onlyLocals = onlyLocals; varsRead = null; globalsRead = null; ltinfo = new ModifyTrans(); gtinfo = new ModifyTrans(); sliceGlobals = null; }
public VariableSlicing(VarSet rmv, ModifyTrans t, Implementation impl) { trackedVars = new VarSet(rmv); trackedVarsVariables = new HashSet <string>(trackedVars.Variables); tinfo = t; onlyGlobals = false; currImplementation = impl; visitedImplementations = new HashSet <string>(); slicedRequires = new HashSet <string>(); slicedEnsures = new HashSet <string>(); }
// map back "trace" through this transformation. tinfo is the parent // transformation info for the whole program -- it is used for recursively // calling the mapBack procedure on callee traces public ErrorTraceBlock mapBackTrace(ErrorTraceBlock tblock, ModifyTrans tinfo) { var ret = new ErrorTraceBlock(tblock.blockName); ret.info = tblock.info; // This is the number of instructions in tblock that we've processed int count = 0; // This is an index into trans int trans_index = 0; while (trans_index < trans.Count) { var it = trans[trans_index]; // Does tblock have enough instructions for this transformation to apply? //if (count + it.Size <= tblock.Cmds.Count || // (it.correspondingInstr >= 0 && count + it.correspondingInstr <= tblock.Cmds.Count ) // break; var inst = it.mapBackTrace(tblock.Cmds, count, tinfo); if (inst == null) { break; } ret.addInstr(inst); // Are we done? if (inst is CallInstr && (inst as CallInstr).calleeTrace != null && ( !(inst as CallInstr).calleeTrace.returns || ( (inst as CallInstr).calleeTrace.raisesException && !(inst as CallInstr).asyncCall ) )) { break; } count += it.Size; trans_index++; } return(ret); }
public VariableSlicePass(VarSet v) { tinfo = new ModifyTrans(); vslice = new VariableSlicing(v, tinfo); passName = "Variable Slicing"; }