コード例 #1
0
ファイル: CallRewriter.cs プロジェクト: xxtxiaofeng/reko
 public void RemoveStatementsFromExitBlock(SsaState ssa)
 {
     foreach (var stm in ssa.Procedure.ExitBlock.Statements.ToList())
     {
         ssa.DeleteStatement(stm);
     }
 }
コード例 #2
0
        /// <summary>
        /// Remove any UseInstructions in the exit block of the procedure that
        /// can be proved to be dead out.
        /// </summary>
        /// <param name="ssa">SSA of the procedure whose exit block is to be examined.</param>
        /// <param name="wl">Worklist of SSA states.</param>
        /// <returns>True if any change was made to SSA.</returns>
        public bool RemoveUnusedDefinedValues(SsaState ssa, WorkList <SsaState> wl)
        {
            bool change = false;

            trace.Verbose("UVR: {0}", ssa.Procedure.Name);
            var(deadStms, deadStgs) = FindDeadStatementsInExitBlock(ssa, this.dataFlow[ssa.Procedure].BitsLiveOut);

            // Remove 'use' statements that are known to be dead from the exit block.
            foreach (var stm in deadStms)
            {
                trace.Verbose("UVR: {0}, deleting {1}", ssa.Procedure.Name, stm.Instruction);
                ssa.DeleteStatement(stm);
                change = true;
            }

            // If any instructions were removed, update the callers.
            if (!ssa.Procedure.Signature.ParametersValid && deadStms.Count > 0)
            {
                DeadCode.Eliminate(ssa);
                foreach (Statement stm in program.CallGraph.CallerStatements(ssa.Procedure))
                {
                    if (!(stm.Instruction is CallInstruction ci))
                    {
                        continue;
                    }
                    var ssaCaller = this.procToSsa[stm.Block.Procedure];
                    if (RemoveDeadCallDefinitions(ssaCaller, ci, deadStgs))
                    {
                        wl.Add(ssaCaller);
                    }
                }
            }
            return(change);
        }
コード例 #3
0
 private void RemoveDefinition(Identifier id, Statement defStatement)
 {
     switch (defStatement.Instruction)
     {
     case CallInstruction ci:
         ci.Definitions.RemoveWhere(cb => cb.Expression == id);
         break;
     case PhiAssignment phi:
         ssa.DeleteStatement(defStatement);
         break;
     }
 }
コード例 #4
0
        private void ReplaceStores(SsaIdentifier sid, StoreOffset stoTail, StoreOffset stoHead)
        {
            if (Operator.Lt.ApplyConstants(stoTail.Offset, stoHead.Offset).ToBoolean())
            {
                stoTail.Store.Dst.DataType = sid.Identifier.DataType;
                stoTail.Store.Src          = sid.Identifier;

                ssa.DeleteStatement(stoHead.Statement);
            }
            else
            {
                throw new NotImplementedException();
            }
        }
コード例 #5
0
        /// <summary>
        /// Remove any Use instruction that uses identifiers
        /// that are marked as preserved.
        /// </summary>
        /// <param name="ssa"></param>
        private void RemovePreservedUseInstructions(SsaState ssa)
        {
            var flow     = this.flow[ssa.Procedure];
            var deadStms = new List <Statement>();

            foreach (var stm in ssa.Procedure.ExitBlock.Statements)
            {
                if (stm.Instruction is UseInstruction u &&
                    u.Expression is Identifier id &&
                    flow.Preserved.Contains(id.Storage))
                {
                    deadStms.Add(stm);
                }
            }
            foreach (var stm in deadStms)
            {
                ssa.DeleteStatement(stm);
            }
        }
コード例 #6
0
ファイル: Coalescer.cs プロジェクト: xxtxiaofeng/reko
        /// <summary>
        /// Coalesces the single use and the single definition of an identifier.
        /// </summary>
        /// <param name="sid"></param>
        /// <param name="defExpr"></param>
        /// <param name="def"></param>
        /// <param name="use"></param>
        /// <returns></returns>
        public bool CoalesceStatements(SsaIdentifier sid, Expression defExpr, Statement def, Statement use)
        {
            PreCoalesceDump(sid, def, use);
            use.Instruction.Accept(new IdentifierReplacer(ssa.Identifiers, use, sid.Identifier, defExpr, false));

            if (defsByStatement.TryGetValue(def, out var sids))
            {
                foreach (SsaIdentifier s in sids)
                {
                    if (s != sid)
                    {
                        s.DefStatement = use;
                        SetDefStatement(use, s);
                    }
                }
            }
            ssa.DeleteStatement(def);
            PostCoalesceDump(use);
            return(true);
        }
コード例 #7
0
ファイル: DeadCode.cs プロジェクト: victor3frainGmail/reko
        private void Eliminate()
        {
            liveIds = new WorkList <SsaIdentifier>();
            HashSet <Statement> marks = new HashSet <Statement>();

            // Initially, just mark those statements that contain critical statements.
            // These are calls to other functions, functions (which have side effects) and use statements.
            // Critical instructions must never be considered dead.

            foreach (var stm in proc.Statements)
            {
                if (critical.IsCritical(stm.Instruction))
                {
                    if (trace.TraceInfo)
                    {
                        Debug.WriteLineIf(trace.TraceInfo, string.Format("Critical: {0}", stm.Instruction));
                    }
                    marks.Add(stm);
                    stm.Instruction.Accept(this);               // mark all used identifiers as live.
                }
            }

            // Each identifier is live, so its defining statement is also live.

            SsaIdentifier sid;

            while (liveIds.GetWorkItem(out sid))
            {
                Statement def = sid.DefStatement;
                if (def != null)
                {
                    if (!marks.Contains(def))
                    {
                        if (trace.TraceInfo)
                        {
                            Debug.WriteLine(string.Format("Marked: {0}", def.Instruction));
                        }
                        marks.Add(def);
                        sid.DefStatement.Instruction.Accept(this);
                    }
                }
            }

            // We have now marked all the useful instructions in the code. Any non-marked
            // instruction is now useless and should be deleted.

            foreach (Block b in proc.ControlGraph.Blocks)
            {
                for (int iStm = 0; iStm < b.Statements.Count; ++iStm)
                {
                    Statement stm = b.Statements[iStm];
                    if (!marks.Contains(stm))
                    {
                        if (trace.TraceInfo)
                        {
                            Debug.WriteLineIf(trace.TraceInfo, string.Format("Deleting: {0}", stm.Instruction));
                        }
                        ssa.DeleteStatement(stm);
                        --iStm;
                    }
                }
            }

            AdjustApplicationsWithDeadReturnValues();
        }
コード例 #8
0
        public void CreateLongInstruction(AddSubCandidate loCandidate, AddSubCandidate hiCandidate)
        {
            var totalSize = PrimitiveType.Create(
                Domain.SignedInt | Domain.UnsignedInt,
                loCandidate.Dst.DataType.BitSize + hiCandidate.Dst.DataType.BitSize);
            var left  = CreateCandidate(loCandidate.Left, hiCandidate.Left, totalSize);
            var right = CreateCandidate(loCandidate.Right, hiCandidate.Right, totalSize);

            this.dst = CreateCandidate(loCandidate.Dst, hiCandidate.Dst, totalSize);
            var       stmts     = hiCandidate.Statement.Block.Statements;
            var       linAddr   = hiCandidate.Statement.LinearAddress;
            var       iStm      = FindInsertPosition(loCandidate, hiCandidate, stmts);
            Statement stmMkLeft = null;

            if (left is Identifier)
            {
                stmMkLeft = stmts.Insert(
                    iStm++,
                    linAddr,
                    CreateMkSeq(left, hiCandidate.Left, loCandidate.Left));
                left = ReplaceDstWithSsaIdentifier(left, null, stmMkLeft);
            }

            Statement stmMkRight = null;

            if (right is Identifier)
            {
                stmMkRight = stmts.Insert(
                    iStm++,
                    linAddr,
                    CreateMkSeq(right, hiCandidate.Right, loCandidate.Right));
                right = ReplaceDstWithSsaIdentifier(right, null, stmMkRight);
            }

            var         expSum  = new BinaryExpression(loCandidate.Op, left.DataType, left, right);
            Instruction instr   = Assign(dst, expSum);
            var         stmLong = stmts.Insert(iStm++, linAddr, instr);

            this.dst = ReplaceDstWithSsaIdentifier(this.dst, expSum, stmLong);

            var sidDst   = GetSsaIdentifierOf(dst);
            var sidLeft  = GetSsaIdentifierOf(left);
            var sidRight = GetSsaIdentifierOf(right);

            if (stmMkLeft != null && sidLeft != null)
            {
                GetSsaIdentifierOf(loCandidate.Left)?.Uses.Add(stmMkLeft);
                GetSsaIdentifierOf(hiCandidate.Left)?.Uses.Add(stmMkLeft);
            }
            if (stmMkRight != null && sidRight != null)
            {
                GetSsaIdentifierOf(loCandidate.Right)?.Uses.Add(stmMkRight);
                GetSsaIdentifierOf(hiCandidate.Right)?.Uses.Add(stmMkRight);
            }
            if (sidDst != null)
            {
                if (sidLeft != null)
                {
                    sidLeft.Uses.Add(stmLong);
                }
                if (sidRight != null)
                {
                    sidRight.Uses.Add(stmLong);
                }
            }

            var sidDstLo = GetSsaIdentifierOf(loCandidate.Dst);

            if (sidDstLo != null)
            {
                var cast      = new Slice(loCandidate.Dst.DataType, dst, 0);
                var stmCastLo = stmts.Insert(iStm++, linAddr, new AliasAssignment(
                                                 sidDstLo.Identifier, cast));
                var stmDeadLo = sidDstLo.DefStatement;
                sidDstLo.DefExpression = cast;
                sidDstLo.DefStatement  = stmCastLo;

                var sidDstHi   = GetSsaIdentifierOf(hiCandidate.Dst);
                var slice      = new Slice(hiCandidate.Dst.DataType, dst, loCandidate.Dst.DataType.BitSize);
                var stmSliceHi = stmts.Insert(iStm++, linAddr, new AliasAssignment(
                                                  sidDstHi.Identifier, slice));
                var stmDeadHi = sidDstHi.DefStatement;
                sidDstHi.DefExpression = slice;
                sidDstHi.DefStatement  = stmSliceHi;

                if (sidDstLo != null)
                {
                    sidDst.Uses.Add(stmCastLo);
                }
                if (sidDstHi != null)
                {
                    sidDst.Uses.Add(stmSliceHi);
                }
                ssa.DeleteStatement(stmDeadLo);
                ssa.DeleteStatement(stmDeadHi);
            }
        }