Пример #1
0
        /// <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);
        }
Пример #2
0
        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);
                }
            }
        }
Пример #3
0
        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);
                }
            }
        }