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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }
Example #6
0
        // 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);
        }