Ejemplo n.º 1
0
 public void Transform(Procedure proc)
 {
     this.ssa            = new SsaState(proc, null);
     this.asta           = new AliasState();
     this.currentDef     = new Dictionary <Block, Dictionary <Storage, SsaIdentifier> >();
     this.incompletePhis = new Dictionary <Block, Dictionary <Storage, SsaIdentifier> >();
     this.sealedBlocks   = new HashSet <Block>();
     foreach (Block b in new DfsIterator <Block>(proc.ControlGraph).PreOrder())
     {
         this.block = b;
         this.currentDef.Add(block, new Dictionary <Storage, SsaIdentifier>()); // new StorageEquality()));
         foreach (var s in b.Statements.ToList())
         {
             this.stm        = s;
             stm.Instruction = stm.Instruction.Accept(this);
         }
     }
 }
Ejemplo n.º 2
0
            /// <summary>
            /// Registers the fact that identifier <paramref name="id"/> is
            /// modified in the block <paramref name="b" /> and generates a
            /// fresh SSA identifier.
            /// </summary>
            /// <param name="bs">The block in which the identifier was changed</param>
            /// <param name="sid">The identifier after being SSA transformed.</param>
            /// <returns>The new SSA identifier</returns>
            public override Identifier WriteVariable(SsaBlockState bs, SsaIdentifier sid)
            {
                DebugEx.Verbose(trace, "  WriteBlockLocalVariable: ({0}, {1}, ({2})", bs.Block.Name, id, this.liveBits);
                if (!bs.currentDef.TryGetValue(id.Storage.Domain, out var aliasState))
                {
                    aliasState = new AliasState();
                    bs.currentDef.Add(id.Storage.Domain, aliasState);
                }
                var stgDef   = id.Storage;
                var defRange = stgDef.GetBitRange();

                for (int i = 0; i < aliasState.Definitions.Count; ++i)
                {
                    var(sidPrev, prevRange, offset) = aliasState.Definitions[i];
                    var stgPrev = sidPrev.Identifier.Storage;
                    if (defRange.Covers(prevRange))
                    {
                        DebugEx.Verbose(trace, "     overwriting: {0}", sidPrev.Identifier);
                        aliasState.Definitions.RemoveAt(i);
                        --i;
                    }
                }
                aliasState.Definitions.Add((sid, defRange, this.Offset));
                DebugEx.Verbose(trace, "     writing: {0}", sid.Identifier);

                var newDict = aliasState.ExactAliases
                              .Where(kv => !kv.Key.OverlapsWith(id.Storage))
                              .ToDictionary(kv => kv.Key, kv => kv.Value);

                if (id.Storage == sid.Identifier.Storage)
                {
                    newDict[id.Storage] = sid;
                }
                aliasState.ExactAliases = newDict;
                return(sid.Identifier);
            }