/// <summary> /// Merges another state into this state by taking the set unions of all their respective reaching definitions /// </summary> /// <param name="other">another state</param> /// <returns>indication whether this state was changed by the merging procedure</returns> public EMergeResult Merge(VarAssignmentSet other) { EMergeResult result = _succMerge ? EMergeResult.NoChange : EMergeResult.Change; _succMerge = true; for (int i = 0; i < other._asmts.Length; i++) { if (_fixedLocals[i]) { continue; } HashSet <int> rhss = other._asmts[i]; if (rhss != null) { foreach (int rhs in rhss) { if (_asmts.Add(i, rhs)) { result = EMergeResult.Change; } } } if (other._sideFx[i] && !_sideFx[i]) { _sideFx[i] = true; result = EMergeResult.Change; } } return(result); }
private void DetectEliminableAccesses() { _writeToRead = new Dictionary <int, int>(); _eliminableLocals = new HashSet <int>(); _writtenAndNeverRead = new HashSet <int>(); for (int localIndex = 0; localIndex < _numLocals; localIndex++) { if (IsEliminationInhibited(localIndex)) { continue; } HashSet <int> storePoints = _storePoints[localIndex]; int numEliminatedAccesses = 0; foreach (int storePoint in storePoints) { if (storePoint < 0) { continue; } var storeBB = Code.GetBasicBlockContaining(storePoint); HashSet <int> uses = _varUses.Get(storePoint); // Assignment never used? if (DetectWriteAndNeverRead && uses.Count == 0) { _writtenAndNeverRead.Add(storePoint); numEliminatedAccesses++; } // Used exactly once? else if (DetectReadAfterWrite && uses.Count == 1) { int readPoint = uses.Single(); var readBB = Code.GetBasicBlockContaining(readPoint); // If variable is read within a different basic block than is // is stored, do not optimize. if (DoNotOptimizeAcrossBasicBlocks && !readBB.Equals(storeBB)) { continue; } VarAssignmentSet preCond = _preConds[readPoint]; if (preCond.HasSideEffects(localIndex)) { continue; } IEnumerable <int> readPointStores = preCond.GetStorePoints(localIndex); // Variable definition must be unambiguous if (readPointStores.Count() != 1) { continue; } Debug.Assert(readPointStores.Single() == storePoint); //_readAfterWritePairs.Add(new ReadAfterWritePair(storePoint, readPoint)); _writeToRead[storePoint] = readPoint; numEliminatedAccesses++; } } if (numEliminatedAccesses == storePoints.Count) { // All variable accesses could be eliminated // ==> local variable is completely superfluous _eliminableLocals.Add(localIndex); } } }
private void IterateToFixPoint() { List <Ti> instrs = Code.Instructions; _preConds = new VarAssignmentSet[instrs.Count]; _postConds = new VarAssignmentSet[instrs.Count]; _refPoints = new int[instrs.Count]; _refUses = new Dictionary <int, List <int> >(); _inhibitElimination = new bool[_numLocals]; Queue <int> q = new Queue <int>(); _loadPoints = new HashSet <int> [_numLocals]; _storePoints = new HashSet <int> [_numLocals]; for (int i = 0; i < _numLocals; i++) { if (Code.IsLocalPinned(i)) { InhitbitElimination(i); } _loadPoints[i] = new HashSet <int>(); _storePoints[i] = new HashSet <int>(); } for (int i = 0; i < instrs.Count; i++) { _preConds[i] = new VarAssignmentSet(_numLocals); _postConds[i] = new VarAssignmentSet(_numLocals); _refPoints[i] = -1; } int startIndex = Code.EntryCB.StartIndex; _preConds[startIndex].SetInitial(); q.Enqueue(startIndex); IExtendedInstructionInfo <Ti> xinfo = InstructionInfo as IExtendedInstructionInfo <Ti>; while (q.Count > 0) { int iidx = q.Dequeue(); _curILI = Code.Instructions[iidx]; _curPreCond = _preConds[iidx]; _curPostCond = _postConds[iidx]; _curPostCond.Merge(_curPreCond); ProcessInstruction(); if (xinfo != null) { ProcessInstructionExtended(); } Ti[] succs = Code.GetSuccessorsOf(_curILI); foreach (Ti succ in succs) { int siidx = succ.Index; if (_preConds[siidx].Merge(_curPostCond) == VarAssignmentSet.EMergeResult.Change) { q.Enqueue(siidx); } } } // Post-process to make sure each variable has at least one assignment location // Variables which are not assigned in the course of the program are assumed // to possess a "virtual assignment" location at IL index -1. for (int i = 0; i < _numLocals; i++) { if (_storePoints[i].Count == 0) { _storePoints[i].Add(-1); } } }