private void addToTrace(ErrorTraceInstr inst, InstrLocation loc, ref ErrorTraceBlock curr, ErrorTrace trace) { if (curr == null) { curr = new ErrorTraceBlock(loc.blockName); Debug.Assert(loc.num == 0); curr.addInstr(inst); return; } // curr != null. We need to see if inst should be put inside curr or start a new block? if (loc.num == curr.Cmds.Count && loc.blockName == curr.blockName) { curr.addInstr(inst); } else { // start a new block Debug.Assert(loc.num == 0); trace.addBlock(curr); curr = new ErrorTraceBlock(loc.blockName); curr.addInstr(inst); } }
// 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 override ErrorTrace mapBackTrace(ErrorTrace trace) { if (unrollNum >= 0) { return(base.mapBackTrace(trace)); } var ret = new ErrorTrace(trace.procName); var firstInfo = trace.Blocks[0].info; ErrorTraceBlock lastBlk = null; foreach (var blk in trace.Blocks) { var rblkLabel = elGetBlock(trace.procName, blk.blockName); if (rblkLabel != null) { lastBlk = new ErrorTraceBlock(rblkLabel); lastBlk.info = blk.info; if (ret.Blocks.Count == 0 && lastBlk.info == null) { lastBlk.info = firstInfo; } ret.addBlock(lastBlk); } foreach (var cmd in blk.Cmds) { var ccmd = cmd as CallInstr; if (ccmd == null || ccmd.calleeTrace == null) { if (lastBlk != null) { lastBlk.addInstr(cmd); } continue; } var ctrace = mapBackTrace(ccmd.calleeTrace); if (isLoop(ctrace.procName)) { // absorb trace ret.Blocks.AddRange(ctrace.Blocks); lastBlk = null; } else { if (lastBlk != null) { lastBlk.addInstr(new CallInstr(ctrace.procName, ctrace, ccmd.asyncCall, cmd.info)); } continue; } } } if (trace.returns && ret.Blocks.Count > 0) { ret.addReturn(trace.raisesException); } return(ret); }
public ErrorTrace mapBackTrace(ErrorTrace trace) { Debug.Assert(tinfo.ContainsKey(trace.procName)); var ret = new ErrorTrace(trace.procName); var info = tinfo[trace.procName]; foreach (var blk in trace.Blocks) { var peices = info[blk.blockName]; Debug.Assert(peices.Count != 0); // This is an index into blk.Cmds var cnt = 0; var done = false; var lastInf = blk.info; for (int i = 0; !done && i < peices.Count; i++) { // Do we have enough in blk.Cmds for peices[i]? if (cnt + peices[i].snd - 1 >= blk.Cmds.Count) { done = true; } var eblk = new ErrorTraceBlock(peices[i].fst); eblk.info = lastInf; int j = 0; while (j < peices[i].snd && cnt < blk.Cmds.Count) { var inst = blk.Cmds[cnt]; lastInf = inst.info; if (inst is CallInstr) { var cinst = inst as CallInstr; if (cinst.hasCalledTrace) { inst = new CallInstr(cinst.callee, mapBackTrace(cinst.calleeTrace), cinst.asyncCall, cinst.info); if (!(inst as CallInstr).calleeTrace.returns) { done = true; } } } eblk.addInstr(inst); cnt++; j++; } ret.addBlock(eblk); } } if (trace.returns) { ret.addReturn(); } return(ret); }
public ErrorTrace mapBackTraceRecord(ErrorTrace trace) { var ret = new ErrorTrace(trace.procName); foreach (var block in trace.Blocks) { var nb = new ErrorTraceBlock(block.blockName); foreach (var cmd in block.Cmds) { if (cmd is CallInstr) { var ccmd = cmd as CallInstr; if (ccmd.callee == recordProcNameInt || ccmd.callee == recordProcNameBool || ccmd.callee.StartsWith(recordProcNameCtor)) { Debug.Assert(nb.Cmds.Count != 0); nb.Cmds.Last().info = ccmd.info; continue; } if (ccmd.hasCalledTrace) { var c = new CallInstr(mapBackTraceRecord(ccmd.calleeTrace), ccmd.asyncCall, ccmd.info); nb.addInstr(c); } else { nb.addInstr(ccmd); } } else { nb.addInstr(cmd.Copy()); } } ret.addBlock(nb); } if (trace.returns) { ret.addReturn(trace.raisesException); } return(ret); }
// 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 ErrorTrace mapBackTrace(ErrorTrace trace, InsertionTrans tinfo) { // Output to be constructed var ret = new ErrorTrace(tinfo.getSrcProcName(trace.procName)); // The current block being constructed ErrorTraceBlock curr = null; foreach (var blk in trace.Blocks) { if (toFromBlockMap.ContainsKey(blk.blockName)) { // This "blk" corresponds to some block in the source program, // then start a new block here. if (curr != null) { ret.addBlock(curr); } curr = new ErrorTraceBlock(toFromBlockMap[blk.blockName]); if (blk.info != null) { curr.info = blk.info.Copy(); } } for (int i = 0; i < blk.Cmds.Count; i++) { var toType = InstrTypeEnum.INTRA; string callee = null; if (blk.Cmds[i].isCall()) { var cc = (blk.Cmds[i] as CallInstr); callee = cc.callee; if (cc.asyncCall) { toType = InstrTypeEnum.ASYNC; } else { toType = InstrTypeEnum.CALL; } } var to = new InstrLocation(blk.blockName, i, new InstrType(toType, callee)); // Is there a corresponding source instruction? if (!toFromMap.ContainsKey(to)) { continue; } // This is the location of the corresponding source instruction var from = toFromMap[to]; // This is the source instruction var inst = getCorrespondingInst(from, blk.Cmds[i], tinfo); // Now we have to place "inst" in "ret" addToTrace(inst, from, ref curr, ret); } } if (curr != null) { ret.addBlock(curr); } if (trace.returns) { ret.addReturn(trace.raisesException); } return(ret); }