예제 #1
0
            /// <summary>
            /// Renames all variables in a block to use their SSA names
            /// </summary>
            /// <param name="n">Block to rename</param>
            public void RenameBlock(Block n)
            {
                var wasonentry = new Dictionary <Identifier, Identifier>(rename);

                // Rename variables in all blocks except the starting block which
                // only contains dummy 'def' variables.

                if (n != n.Procedure.EntryBlock)
                {
                    foreach (Statement stm in n.Statements)
                    {
                        stmCur             = stm;
                        stmCur.Instruction = stmCur.Instruction.Accept(this);
                    }
                    if (n == n.Procedure.ExitBlock && this.addUseInstructions)
                    {
                        AddUseInstructions(n);
                    }
                }

                // Rename arguments to phi functions in successor blocks.

                bool [] visited = new bool[proc.ControlGraph.Blocks.Count];
                foreach (Block y in n.Succ)
                {
                    for (int j = 0; j < y.Pred.Count; ++j)
                    {
                        if (y.Pred[j] == n && !visited[ssa.RpoNumber(y)])
                        {
                            visited[ssa.RpoNumber(y)] = true;

                            // For each phi function in y...

                            foreach (Statement stm in y.Statements.Where(s => s.Instruction is PhiAssignment))
                            {
                                var newPhi = newPhiStatements.Contains(stm);
                                stmCur = stm;
                                PhiAssignment phi = (PhiAssignment)stmCur.Instruction;
                                PhiFunction   p   = phi.Src;
                                // replace 'n's slot with the renamed name of the variable.
                                p.Arguments[j] =
                                    NewUse((Identifier)p.Arguments[j], stm, newPhi);
                            }
                        }
                    }
                }
                foreach (Block c in ssa.DomGraph.ReversePostOrder.Keys)
                {
                    if (c != proc.EntryBlock && ssa.DomGraph.ImmediateDominator(c) == n)
                    {
                        RenameBlock(c);
                    }
                }
                rename = wasonentry;
            }
예제 #2
0
            private void MarkDefined(Identifier eDef)
            {
                SsaIdentifier sid;
                var           idDef = eDef as Identifier;

                if (idDef != null && ssa.Identifiers.TryGetValue(idDef, out sid))
                {
                    // If we've seen this identifier before, use its
                    // original name.
                    eDef = sid.OriginalIdentifier;
                }
                var  dict = defVars[ssa.RpoNumber(block)];
                byte bits;

                dict.TryGetValue(eDef, out bits);
                dict[eDef] = (byte)(bits | (BitDefined | BitDeadIn));
                if (!inDefinitions.Contains(eDef))
                {
                    inDefinitions.Add(eDef);
                    definitions.Add(eDef);
                }
            }
예제 #3
0
        private HashSet <Statement> PlacePhiFunctions()
        {
            HashSet <Statement> phiStatements = new HashSet <Statement>();
            var defVars = LocateAllDefinedVariables(AOrig);

            MarkTemporariesDeadIn(AOrig);

            // For each defined variable in block n, collect the places where it is defined

            foreach (var a in defVars)
            {
                // Create a worklist W of all the blocks that define a.

                var W = new WorkList <Block>();
                foreach (Block b in SsaState.DomGraph.ReversePostOrder.Keys)
                {
                    byte bits;
                    AOrig[SsaState.RpoNumber(b)].TryGetValue(a, out bits);
                    if ((bits & BitDefined) != 0)
                    {
                        W.Add(b);
                    }
                }
                Block n;
                while (W.GetWorkItem(out n))
                {
                    foreach (Block y in SsaState.DomGraph.DominatorFrontier(n))
                    {
                        // Only add phi functions if there is no
                        // phi already and variable is not deadIn.

                        var  dict = AOrig[SsaState.RpoNumber(y)];
                        byte bits;
                        dict.TryGetValue(a, out bits);
                        if ((bits & (BitHasPhi | BitDeadIn)) == 0)
                        {
                            bits   |= BitHasPhi;
                            dict[a] = bits;
                            var stm = InsertPhiStatement(y, a);
                            phiStatements.Add(stm);
                            if ((bits & BitDefined) == 0)
                            {
                                W.Add(y);
                            }
                        }
                    }
                }
            }
            return(phiStatements);
        }
예제 #4
0
 /// <summary>
 /// Temporary variables are never live-in, so we avoid getting phi
 /// functions all over the place by marking them explicitly as dead-in.
 /// </summary>
 /// <param name="def"></param>
 private void MarkTemporariesDeadIn(Dictionary <Expression, byte>[] def)
 {
     foreach (var block in proc.ControlGraph.Blocks)
     {
         int iBlock = SsaState.RpoNumber(block);
         foreach (Identifier id in proc.Frame.Identifiers.Where(id => id.Storage is TemporaryStorage))
         {
             byte bits;
             if (!def[iBlock].TryGetValue(id, out bits))
             {
                 bits = 0;
             }
             def[iBlock][id] = (byte)(bits | BitDeadIn);
         }
     }
 }