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); } } }
/// <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); }